Files
Flowchart/src/db.ts
T

180 lines
4.0 KiB
TypeScript

// 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<T>(sql: string, ...params: any[]): T | null {
const row = db.query(sql).get(...params as any);
return row ? (row as T) : null;
}
function getAll<T>(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<FlowStep, "createdAt">) {
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<FlowStep>("SELECT * FROM flow_steps WHERE id = ?", id);
}
export function getAllSteps(): FlowStep[] {
return getAll<FlowStep>("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<Question>("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;