import { Injectable, OnModuleInit } from '@nestjs/common'; import Database from 'better-sqlite3'; import * as fs from 'fs'; import { config, dbPath } from '../config'; export interface RunRow { id: string; original_filename: string; status: 'pending' | 'running' | 'done' | 'error'; created_at: string; finished_at: string | null; params_json: string | null; report_json: string | null; log: string; error: string | null; } @Injectable() export class DatabaseService implements OnModuleInit { private db!: Database.Database; onModuleInit() { fs.mkdirSync(config.dataDir, { recursive: true }); this.db = new Database(dbPath()); this.db.pragma('journal_mode = WAL'); this.db.exec(` CREATE TABLE IF NOT EXISTS runs ( id TEXT PRIMARY KEY, original_filename TEXT NOT NULL, status TEXT NOT NULL, created_at TEXT NOT NULL, finished_at TEXT, params_json TEXT, report_json TEXT, log TEXT NOT NULL DEFAULT '', error TEXT ); `); } insert(row: Pick) { this.db .prepare( `INSERT INTO runs (id, original_filename, status, created_at, params_json, log) VALUES (?, ?, ?, ?, ?, '')`, ) .run(row.id, row.original_filename, row.status, row.created_at, row.params_json); } updateStatus(id: string, status: RunRow['status']) { this.db.prepare(`UPDATE runs SET status = ? WHERE id = ?`).run(status, id); } appendLog(id: string, line: string) { this.db.prepare(`UPDATE runs SET log = log || ? WHERE id = ?`).run(`[${new Date().toISOString()}] ${line}\n`, id); } complete(id: string, reportJson: string) { this.db .prepare(`UPDATE runs SET status = 'done', report_json = ?, finished_at = ? WHERE id = ?`) .run(reportJson, new Date().toISOString(), id); } fail(id: string, error: string) { this.db.prepare(`UPDATE runs SET status = 'error', error = ?, finished_at = ? WHERE id = ?`).run(error, new Date().toISOString(), id); } get(id: string): RunRow | undefined { return this.db.prepare(`SELECT * FROM runs WHERE id = ?`).get(id) as RunRow | undefined; } list(): RunRow[] { return this.db.prepare(`SELECT * FROM runs ORDER BY created_at DESC`).all() as RunRow[]; } remove(id: string) { this.db.prepare(`DELETE FROM runs WHERE id = ?`).run(id); } }