diff options
Diffstat (limited to 'app/lib/db.server.ts')
| -rw-r--r-- | app/lib/db.server.ts | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/app/lib/db.server.ts b/app/lib/db.server.ts index c4b11b4..37d819b 100644 --- a/app/lib/db.server.ts +++ b/app/lib/db.server.ts @@ -142,7 +142,22 @@ function initSchema(db: Database.Database) { CREATE INDEX IF NOT EXISTS idx_artist_revisions_artist_id ON artist_revisions(artist_id); CREATE INDEX IF NOT EXISTS idx_list_entries_list_id ON list_entries(list_id); CREATE INDEX IF NOT EXISTS idx_list_revisions_list_id ON list_revisions(list_id); + + CREATE TABLE IF NOT EXISTS parse_jobs ( + id TEXT PRIMARY KEY, + status TEXT NOT NULL DEFAULT 'pending', + input_text TEXT NOT NULL, + result TEXT, + error_message TEXT, + created_at TEXT NOT NULL DEFAULT (datetime('now')), + updated_at TEXT NOT NULL DEFAULT (datetime('now')) + ); + + CREATE INDEX IF NOT EXISTS idx_parse_jobs_status ON parse_jobs(status, created_at); `); + + // reset stuck jobs from previous server run + db.prepare("UPDATE parse_jobs SET status = 'pending', updated_at = datetime('now') WHERE status = 'processing'").run(); } // ── Interfaces ──────────────────────────────────────────────────────────────── @@ -330,6 +345,14 @@ export function listBands(): Band[] { return getDb().prepare("SELECT * FROM bands ORDER BY slug").all() as Band[]; } +export function listRecentBands(limit = 8): Band[] { + return getDb().prepare("SELECT * FROM bands ORDER BY created_at DESC LIMIT ?").all(limit) as Band[]; +} + +export function listRecentArtists(limit = 8): Artist[] { + return getDb().prepare("SELECT * FROM artists ORDER BY created_at DESC LIMIT ?").all(limit) as Artist[]; +} + export function getBandById(id: string): Band | null { return getDb().prepare("SELECT * FROM bands WHERE id = ?").get(id) as Band | null; } @@ -796,3 +819,59 @@ export function importDb(data: DbExport): ImportResult { }; })() as ImportResult; } + +// ── Parse job queue ─────────────────────────────────────────────────────────── + +export interface ParseJob { + id: string; + status: "pending" | "processing" | "done" | "error"; + input_text: string; + result: string | null; + error_message: string | null; + created_at: string; + updated_at: string; +} + +export function createParseJob(inputText: string): ParseJob { + const id = crypto.randomUUID(); + getDb().prepare( + "INSERT INTO parse_jobs (id, input_text) VALUES (?, ?)" + ).run(id, inputText); + return getDb().prepare("SELECT * FROM parse_jobs WHERE id = ?").get(id) as ParseJob; +} + +export function getParseJob(id: string): ParseJob | null { + return getDb().prepare("SELECT * FROM parse_jobs WHERE id = ?").get(id) as ParseJob | null; +} + +export function listRecentParseJobs(limit = 20): ParseJob[] { + return getDb() + .prepare("SELECT * FROM parse_jobs ORDER BY created_at DESC LIMIT ?") + .all(limit) as ParseJob[]; +} + +export function claimNextParseJob(): ParseJob | null { + const db = getDb(); + return db.transaction(() => { + const job = db.prepare( + "SELECT * FROM parse_jobs WHERE status = 'pending' ORDER BY created_at LIMIT 1" + ).get() as ParseJob | null; + if (!job) return null; + db.prepare( + "UPDATE parse_jobs SET status = 'processing', updated_at = datetime('now') WHERE id = ?" + ).run(job.id); + return { ...job, status: "processing" as const }; + })(); +} + +export function completeParseJob(id: string, result: string): void { + getDb().prepare( + "UPDATE parse_jobs SET status = 'done', result = ?, updated_at = datetime('now') WHERE id = ?" + ).run(result, id); +} + +export function failParseJob(id: string, errorMessage: string): void { + getDb().prepare( + "UPDATE parse_jobs SET status = 'error', error_message = ?, updated_at = datetime('now') WHERE id = ?" + ).run(errorMessage, id); +} |
