const Database = require('better-sqlite3'); const path = require('path'); const fs = require('fs'); const DB_PATH = process.env.DB_PATH || '/data/db/app.db'; fs.mkdirSync(path.dirname(DB_PATH), { recursive: true }); const db = new Database(DB_PATH); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); db.exec(` CREATE TABLE IF NOT EXISTS customers ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, token TEXT NOT NULL UNIQUE, password_hash TEXT, expires_at INTEGER, created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS uploads ( id INTEGER PRIMARY KEY AUTOINCREMENT, customer_id INTEGER NOT NULL, filename TEXT NOT NULL, relative_path TEXT NOT NULL, size INTEGER NOT NULL, uploaded_at INTEGER NOT NULL, FOREIGN KEY(customer_id) REFERENCES customers(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'staff', created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS sessions ( token TEXT PRIMARY KEY, user_id INTEGER NOT NULL, created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL, FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS customer_access ( customer_id INTEGER NOT NULL, user_id INTEGER NOT NULL, access TEXT NOT NULL DEFAULT 'read', PRIMARY KEY(customer_id, user_id), FOREIGN KEY(customer_id) REFERENCES customers(id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT ); `); // Additive migrations for existing DBs function addColumnIfMissing(table, column, ddl) { const cols = db.prepare(`PRAGMA table_info(${table})`).all(); if (!cols.some(c => c.name === column)) { db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${ddl}`); } } addColumnIfMissing('users', 'email', 'TEXT'); addColumnIfMissing('customers', 'email', 'TEXT'); addColumnIfMissing('customers', 'archived_at', 'INTEGER'); module.exports = db;