mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 21:02:12 +03:00
feat(db): add inspector custom hosts + sessions CRUD modules (F2)
This commit is contained in:
77
src/lib/db/inspectorCustomHosts.ts
Normal file
77
src/lib/db/inspectorCustomHosts.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Database module: InspectorCustomHosts
|
||||
* CRUD operations for inspector_custom_hosts table.
|
||||
*/
|
||||
|
||||
import { getDbInstance } from "./core";
|
||||
import type { InspectorCustomHostRow } from "./_rowTypes";
|
||||
|
||||
// SQLite stores booleans as integers
|
||||
interface InspectorCustomHostDbRow {
|
||||
host: string;
|
||||
enabled: number;
|
||||
label: string | null;
|
||||
kind: string;
|
||||
added_at: string;
|
||||
last_seen_at: string | null;
|
||||
}
|
||||
|
||||
function mapRow(row: InspectorCustomHostDbRow): InspectorCustomHostRow {
|
||||
return {
|
||||
host: row.host,
|
||||
enabled: row.enabled === 1,
|
||||
label: row.label,
|
||||
kind: row.kind as "llm" | "app" | "custom",
|
||||
added_at: row.added_at,
|
||||
last_seen_at: row.last_seen_at,
|
||||
};
|
||||
}
|
||||
|
||||
export function listCustomHosts(opts?: { enabledOnly?: boolean }): InspectorCustomHostRow[] {
|
||||
const db = getDbInstance();
|
||||
const enabledOnly = opts?.enabledOnly === true;
|
||||
|
||||
const rows = enabledOnly
|
||||
? (db
|
||||
.prepare(
|
||||
"SELECT * FROM inspector_custom_hosts WHERE enabled = 1 ORDER BY host ASC"
|
||||
)
|
||||
.all() as InspectorCustomHostDbRow[])
|
||||
: (db
|
||||
.prepare("SELECT * FROM inspector_custom_hosts ORDER BY host ASC")
|
||||
.all() as InspectorCustomHostDbRow[]);
|
||||
|
||||
return rows.map(mapRow);
|
||||
}
|
||||
|
||||
export function addCustomHost(
|
||||
host: string,
|
||||
kind: "llm" | "app" | "custom" = "custom",
|
||||
label?: string
|
||||
): void {
|
||||
const db = getDbInstance();
|
||||
const now = new Date().toISOString();
|
||||
db.prepare(
|
||||
`INSERT OR IGNORE INTO inspector_custom_hosts (host, enabled, label, kind, added_at)
|
||||
VALUES (?, 1, ?, ?, ?)`
|
||||
).run(host, label ?? null, kind, now);
|
||||
}
|
||||
|
||||
export function removeCustomHost(host: string): void {
|
||||
const db = getDbInstance();
|
||||
db.prepare("DELETE FROM inspector_custom_hosts WHERE host = ?").run(host);
|
||||
}
|
||||
|
||||
export function toggleCustomHost(host: string, enabled: boolean): void {
|
||||
const db = getDbInstance();
|
||||
db.prepare("UPDATE inspector_custom_hosts SET enabled = ? WHERE host = ?").run(
|
||||
enabled ? 1 : 0,
|
||||
host
|
||||
);
|
||||
}
|
||||
|
||||
export function touchLastSeen(host: string): void {
|
||||
const db = getDbInstance();
|
||||
const now = new Date().toISOString();
|
||||
db.prepare("UPDATE inspector_custom_hosts SET last_seen_at = ? WHERE host = ?").run(now, host);
|
||||
}
|
||||
117
src/lib/db/inspectorSessions.ts
Normal file
117
src/lib/db/inspectorSessions.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Database module: InspectorSessions
|
||||
* CRUD + snapshot for inspector_sessions and inspector_session_requests tables.
|
||||
*/
|
||||
|
||||
import { randomUUID } from "crypto";
|
||||
import { getDbInstance } from "./core";
|
||||
import type { InspectorSessionRow } from "./_rowTypes";
|
||||
|
||||
interface InspectorSessionDbRow {
|
||||
id: string;
|
||||
name: string | null;
|
||||
started_at: string;
|
||||
ended_at: string | null;
|
||||
request_count: number;
|
||||
profile: string | null;
|
||||
}
|
||||
|
||||
interface InspectorSessionRequestDbRow {
|
||||
session_id: string;
|
||||
seq: number;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
function mapSessionRow(row: InspectorSessionDbRow): InspectorSessionRow {
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
started_at: row.started_at,
|
||||
ended_at: row.ended_at,
|
||||
request_count: row.request_count,
|
||||
profile: row.profile as "llm" | "custom" | "all" | null,
|
||||
};
|
||||
}
|
||||
|
||||
export function createSession(opts?: {
|
||||
name?: string;
|
||||
profile?: "llm" | "custom" | "all";
|
||||
}): { id: string; started_at: string } {
|
||||
const db = getDbInstance();
|
||||
const id = randomUUID();
|
||||
const started_at = new Date().toISOString();
|
||||
|
||||
db.prepare(
|
||||
`INSERT INTO inspector_sessions (id, name, started_at, profile) VALUES (?, ?, ?, ?)`
|
||||
).run(id, opts?.name ?? null, started_at, opts?.profile ?? null);
|
||||
|
||||
return { id, started_at };
|
||||
}
|
||||
|
||||
export function stopSession(id: string): void {
|
||||
const db = getDbInstance();
|
||||
const ended_at = new Date().toISOString();
|
||||
db.prepare("UPDATE inspector_sessions SET ended_at = ? WHERE id = ?").run(ended_at, id);
|
||||
}
|
||||
|
||||
export function renameSession(id: string, name: string): void {
|
||||
const db = getDbInstance();
|
||||
db.prepare("UPDATE inspector_sessions SET name = ? WHERE id = ?").run(name, id);
|
||||
}
|
||||
|
||||
export function listSessions(): InspectorSessionRow[] {
|
||||
const db = getDbInstance();
|
||||
const rows = db
|
||||
.prepare("SELECT * FROM inspector_sessions ORDER BY started_at DESC")
|
||||
.all() as InspectorSessionDbRow[];
|
||||
return rows.map(mapSessionRow);
|
||||
}
|
||||
|
||||
export function getSession(id: string): InspectorSessionRow | null {
|
||||
const db = getDbInstance();
|
||||
const row = db
|
||||
.prepare("SELECT * FROM inspector_sessions WHERE id = ?")
|
||||
.get(id) as InspectorSessionDbRow | undefined;
|
||||
return row ? mapSessionRow(row) : null;
|
||||
}
|
||||
|
||||
export function appendSessionRequest(sessionId: string, payload: string): void {
|
||||
const db = getDbInstance();
|
||||
|
||||
const runTransaction = db.transaction(() => {
|
||||
// Get next seq atomically within transaction
|
||||
const seqRow = db
|
||||
.prepare(
|
||||
"SELECT COALESCE(MAX(seq), 0) + 1 AS next_seq FROM inspector_session_requests WHERE session_id = ?"
|
||||
)
|
||||
.get(sessionId) as { next_seq: number };
|
||||
|
||||
const nextSeq = seqRow.next_seq;
|
||||
|
||||
db.prepare(
|
||||
`INSERT INTO inspector_session_requests (session_id, seq, payload) VALUES (?, ?, ?)`
|
||||
).run(sessionId, nextSeq, payload);
|
||||
|
||||
db.prepare(
|
||||
"UPDATE inspector_sessions SET request_count = request_count + 1 WHERE id = ?"
|
||||
).run(sessionId);
|
||||
});
|
||||
|
||||
runTransaction();
|
||||
}
|
||||
|
||||
export function getSessionRequests(sessionId: string): Array<{ seq: number; payload: string }> {
|
||||
const db = getDbInstance();
|
||||
const rows = db
|
||||
.prepare(
|
||||
"SELECT seq, payload FROM inspector_session_requests WHERE session_id = ? ORDER BY seq ASC"
|
||||
)
|
||||
.all(sessionId) as InspectorSessionRequestDbRow[];
|
||||
return rows.map((r) => ({ seq: r.seq, payload: r.payload }));
|
||||
}
|
||||
|
||||
export function deleteSession(id: string): void {
|
||||
const db = getDbInstance();
|
||||
// Cascade via FK ON DELETE CASCADE for inspector_session_requests
|
||||
db.prepare("DELETE FROM inspector_sessions WHERE id = ?").run(id);
|
||||
}
|
||||
Reference in New Issue
Block a user