2026-02-20 00:28:48 -08:00
|
|
|
import { Database } from "bun:sqlite";
|
|
|
|
|
import type { RoundState } from "./game.ts";
|
|
|
|
|
|
2026-02-27 13:09:00 +01:00
|
|
|
const dbPath = process.env.DATABASE_PATH ?? "argumentes.sqlite";
|
2026-02-20 03:53:37 -08:00
|
|
|
export const db = new Database(dbPath, { create: true });
|
2026-02-20 00:28:48 -08:00
|
|
|
|
|
|
|
|
db.exec(`
|
|
|
|
|
CREATE TABLE IF NOT EXISTS rounds (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
num INTEGER,
|
|
|
|
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
data TEXT
|
|
|
|
|
);
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
export function saveRound(round: RoundState) {
|
|
|
|
|
const insert = db.prepare("INSERT INTO rounds (num, data) VALUES ($num, $data)");
|
|
|
|
|
insert.run({ $num: round.num, $data: JSON.stringify(round) });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRounds(page: number = 1, limit: number = 10) {
|
|
|
|
|
const offset = (page - 1) * limit;
|
|
|
|
|
const countQuery = db.query("SELECT COUNT(*) as count FROM rounds").get() as { count: number };
|
2026-02-20 04:49:40 -08:00
|
|
|
const rows = db.query("SELECT data FROM rounds ORDER BY num DESC, id DESC LIMIT $limit OFFSET $offset")
|
2026-02-20 00:28:48 -08:00
|
|
|
.all({ $limit: limit, $offset: offset }) as { data: string }[];
|
|
|
|
|
return {
|
|
|
|
|
rounds: rows.map(r => JSON.parse(r.data) as RoundState),
|
|
|
|
|
total: countQuery.count,
|
|
|
|
|
page,
|
|
|
|
|
limit,
|
|
|
|
|
totalPages: Math.ceil(countQuery.count / limit)
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-02-20 04:49:40 -08:00
|
|
|
|
|
|
|
|
export function getAllRounds() {
|
|
|
|
|
const rows = db.query("SELECT data FROM rounds ORDER BY num ASC, id ASC").all() as { data: string }[];
|
|
|
|
|
return rows.map(r => JSON.parse(r.data) as RoundState);
|
|
|
|
|
}
|
2026-02-22 01:20:19 -08:00
|
|
|
|
|
|
|
|
export function clearAllRounds() {
|
|
|
|
|
db.exec("DELETE FROM rounds;");
|
|
|
|
|
db.exec("DELETE FROM sqlite_sequence WHERE name = 'rounds';");
|
|
|
|
|
}
|
2026-02-27 14:03:30 +01:00
|
|
|
|
|
|
|
|
// ── Questions (user-submitted via Redsys) ───────────────────────────────────
|
|
|
|
|
|
|
|
|
|
db.exec(`
|
|
|
|
|
CREATE TABLE IF NOT EXISTS questions (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
text TEXT NOT NULL,
|
|
|
|
|
order_id TEXT NOT NULL UNIQUE,
|
|
|
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
|
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
|
|
|
);
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
export function createPendingQuestion(text: string, orderId: string): number {
|
|
|
|
|
const stmt = db.prepare("INSERT INTO questions (text, order_id) VALUES ($text, $orderId)");
|
|
|
|
|
const result = stmt.run({ $text: text, $orderId: orderId });
|
|
|
|
|
return result.lastInsertRowid as number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function markQuestionPaid(orderId: string): boolean {
|
|
|
|
|
const stmt = db.prepare("UPDATE questions SET status = 'paid' WHERE order_id = $orderId AND status = 'pending'");
|
|
|
|
|
const result = stmt.run({ $orderId: orderId });
|
|
|
|
|
return result.changes > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getNextPendingQuestion(): { id: number; text: string; order_id: string } | null {
|
|
|
|
|
return db.query("SELECT id, text, order_id FROM questions WHERE status = 'paid' ORDER BY id ASC LIMIT 1")
|
|
|
|
|
.get() as { id: number; text: string; order_id: string } | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function markQuestionUsed(id: number): void {
|
|
|
|
|
db.prepare("UPDATE questions SET status = 'used' WHERE id = $id").run({ $id: id });
|
|
|
|
|
}
|