panels-origin/api/platform_db.ts
2026-08-21 16:55:01 -05:00

135 lines
4.1 KiB
TypeScript

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<Database> {
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);
}