import { Database } from "@db/sqlite"; import { mkdir } from "node:fs/promises"; import { DATA_DIR, PLATFORM_DB_PATH } from "./config.ts"; import { config } from "./config.ts"; import { hashPassword } from "./crypto.ts"; import { runLiquibase } from "./liquibase.ts"; export type PlatformDb = Database; let platformDb: Database | null = null; export type PlatformUser = { id: number; username: string; display_name: string; status: string; }; export async function getPlatformDb(): Promise { if (platformDb) return platformDb; await mkdir(DATA_DIR, { recursive: true }); await runLiquibase(); platformDb = new Database(PLATFORM_DB_PATH); platformDb.exec("PRAGMA foreign_keys = ON;"); await seedPlatform(platformDb); return platformDb; } async function seedPlatform(database: Database) { if (!config.seedPassword) { console.warn("[platform] SEED_PASSWORD vacĂ­o; no se siembra usuario admin"); } else { const hash = await hashPassword(config.seedPassword); const admin = database.prepare("SELECT id FROM platform_users WHERE username = ?").get("admin") as | { id: number } | undefined; const legacy = database.prepare("SELECT id FROM platform_users WHERE username = ?").get("operador") as | { id: number } | undefined; if (legacy && !admin) { database.prepare( `UPDATE platform_users SET username = ?, password_hash = ?, display_name = ? WHERE id = ?`, ).run("admin", hash, "Admin PANELS", legacy.id); } else if (!admin) { database.prepare( `INSERT INTO platform_users (username, password_hash, display_name, status) VALUES (?, ?, ?, 'activo')`, ).run("admin", hash, "Admin PANELS"); } else if (legacy) { database.prepare("DELETE FROM platform_users WHERE id = ?").run(legacy.id); } const sync = ["1", "true", "yes"].includes( (Deno.env.get("SEED_SYNC_PASSWORD") ?? "").toLowerCase(), ); if (sync) { const row = database.prepare("SELECT id FROM platform_users WHERE username = ?").get("admin") as | { id: number } | undefined; if (row) { database.prepare( `UPDATE platform_users SET password_hash = ?, display_name = ? WHERE id = ?`, ).run(hash, "Admin PANELS", row.id); console.warn("[platform] SEED_SYNC_PASSWORD: password de admin actualizado"); } } } const arctec = database.prepare( "SELECT id FROM tenants WHERE code IN ('ARCT2608', 'ARCTEC')", ).get(); if (!arctec) { database.prepare( `INSERT INTO tenants (id, code, name, status) VALUES (1, 'ARCT2608', 'ARCTEC', 'activo')`, ).run(); } } export function listTenants(database: Database) { return database.prepare( `SELECT id, code, name, status, created_at, COALESCE(plan, 'trial') AS plan, valid_until, COALESCE(notes, '') AS notes, COALESCE(contact_email, '') AS contact_email, COALESCE(contact_name, '') AS contact_name, access_sent_at FROM tenants ORDER BY id`, ).all() as { id: number; code: string; name: string; status: string; created_at: string; plan: string; valid_until: string | null; notes: string; contact_email: string; contact_name: string; access_sent_at: string | null; }[]; } export function tenantByCode(database: Database, code: string) { return database.prepare("SELECT * FROM tenants WHERE code = ?").get(code.trim().toUpperCase()) as | { id: number; code: string; name: string; status: string; plan?: string; valid_until?: string | null; notes?: string; } | undefined; } export function tenantById(database: Database, id: number) { return database.prepare("SELECT * FROM tenants WHERE id = ?").get(id) as | { id: number; code: string; name: string; status: string; plan?: string; valid_until?: string | null; notes?: string; created_at?: string; } | undefined; } export function lastInsertId(database: Database): number { return Number((database.prepare("SELECT last_insert_rowid() AS id").get() as { id: number }).id); }