// db.ts import { Database } from "bun:sqlite"; // --- Initialize Bun SQLite --- const db = new Database("./flow.db"); // --- Helper functions to bypass TS binding issues --- function getOne(sql: string, ...params: any[]): T | null { const row = db.query(sql).get(...params as any); return row ? (row as T) : null; } function getAll(sql: string, ...params: any[]): T[] { const rows = db.query(sql).all(...params as any); return rows.map(r => r as T); } function run(sql: string, ...params: any[]) { db.run(sql, ...params as any); } // --- Create tables if they do not exist --- run(` CREATE TABLE IF NOT EXISTS flow_steps ( id TEXT PRIMARY KEY, stepNumber TEXT, caseCode TEXT, subStep TEXT, stage TEXT, role TEXT, handoffTo TEXT, handoffChannel TEXT, description TEXT, createdAt TEXT DEFAULT CURRENT_TIMESTAMP ) `); run(` CREATE TABLE IF NOT EXISTS extended_descriptions ( stepId TEXT PRIMARY KEY REFERENCES flow_steps(id), content TEXT ) `); run(` CREATE TABLE IF NOT EXISTS questions ( id INTEGER PRIMARY KEY AUTOINCREMENT, stepId TEXT REFERENCES flow_steps(id), question TEXT, followUp TEXT, createdAt TEXT DEFAULT CURRENT_TIMESTAMP ) `); run(` CREATE TABLE IF NOT EXISTS concerns ( stepId TEXT PRIMARY KEY REFERENCES flow_steps(id), flagged INTEGER DEFAULT 0, comment TEXT, createdAt TEXT DEFAULT CURRENT_TIMESTAMP ) `); // --- Types --- export type FlowStep = { id: string; stepNumber: string; caseCode: string; subStep: string; stage: string; role: string; handoffTo: string; handoffChannel: string; description: string; createdAt: string; }; export type ExtendedDescription = { stepId: string; content: string; }; export type Question = { id: number; stepId: string; question: string; followUp: string | null; createdAt: string; }; export type Concern = { stepId: string; flagged: boolean; comment: string; createdAt: string; }; // --- Flow Steps --- export function createStep(step: Omit) { run( `INSERT OR IGNORE INTO flow_steps (id, stepNumber, caseCode, subStep, stage, role, handoffTo, handoffChannel, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, step.id, step.stepNumber, step.caseCode, step.subStep, step.stage, step.role, step.handoffTo, step.handoffChannel, step.description ); } export function getStep(id: string): FlowStep | null { return getOne("SELECT * FROM flow_steps WHERE id = ?", id); } export function getAllSteps(): FlowStep[] { return getAll("SELECT * FROM flow_steps"); } // --- Extended Descriptions --- export function saveExtendedDescription(stepId: string, content: string) { run( `INSERT OR REPLACE INTO extended_descriptions (stepId, content) VALUES (?, ?)`, stepId, content ); } export function getExtendedDescription(stepId: string): string | null { const row = getOne<{ content: string }>( "SELECT content FROM extended_descriptions WHERE stepId = ?", stepId ); return row ? row.content : null; } // --- Questions --- export function addQuestion(stepId: string, question: string, followUp?: string | null) { run( `INSERT INTO questions (stepId, question, followUp) VALUES (?, ?, ?)`, stepId, question, followUp ?? null ); } export function getQuestions(stepId: string): Question[] { return getAll("SELECT * FROM questions WHERE stepId = ?", stepId); } // --- Concerns --- export function flagConcern(stepId: string, flagged: boolean, comment: string) { run( `INSERT OR REPLACE INTO concerns (stepId, flagged, comment) VALUES (?, ?, ?)`, stepId, flagged ? 1 : 0, comment ); } export function getConcern(stepId: string): Concern | null { const row = getOne<{ stepId: string; flagged: number; comment: string; createdAt: string }>( "SELECT * FROM concerns WHERE stepId = ?", stepId ); if (!row) return null; return { stepId: row.stepId, flagged: row.flagged === 1, comment: row.comment, createdAt: row.createdAt }; } //export default db;