fase(2): shared infrastructure layer

This commit is contained in:
debian
2026-03-04 16:26:32 -05:00
parent 0e6c0c3655
commit 4a58749048
21 changed files with 1170 additions and 23 deletions

View File

@@ -0,0 +1,150 @@
import { Kysely, SqliteDialect } from 'kysely';
import SQLite from 'better-sqlite3';
import path from 'path';
import fs from 'fs';
export interface SessionTable {
id: string;
url: string;
status: string;
seed: number;
max_states: number;
states_visited: number;
anomalies_found: number;
started_at: number;
finished_at: number | null;
config_json: string;
}
export interface StateTable {
id: string;
session_id: string;
url: string;
title: string;
dom_snapshot_path: string | null;
visit_count: number;
discovered_at: number;
}
export interface ActionTable {
id: string;
session_id: string;
state_id: string;
type: string;
selector: string | null;
value: string | null;
url: string | null;
seed: number;
executed_at: number;
sequence_order: number;
}
export interface AnomalyTable {
id: string;
session_id: string;
type: string;
severity: string;
description: string;
action_trace_json: string;
evidence_json: string;
screenshot_path: string | null;
dom_snapshot_path: string | null;
detected_at: number;
ai_enrichment_json: string | null;
ai_enriched_at: number | null;
browser: string | null;
browser_version: string | null;
}
export interface NotificationTable {
id: string;
anomaly_id: string;
channel: string;
status: string;
sent_at: number | null;
error: string | null;
}
export interface ScheduleTable {
id: string;
name: string;
url: string;
config_json: string;
cron_expression: string;
enabled: number;
last_run_at: number | null;
next_run_at: number | null;
created_at: number;
}
export interface VisualBaselineTable {
id: string;
state_id: string;
url: string;
screenshot_path: string;
approved_at: number;
approved_by: string | null;
width: number;
height: number;
}
export interface VisualComparisonTable {
id: string;
session_id: string;
state_id: string;
baseline_id: string | null;
current_screenshot_path: string;
diff_screenshot_path: string | null;
diff_pixels: number | null;
diff_percent: number | null;
status: string;
created_at: number;
}
export interface PerformanceMetricTable {
id: string;
session_id: string;
state_id: string;
url: string;
ttfb: number | null;
dom_content_loaded: number | null;
load_complete: number | null;
lcp: number | null;
cls: number | null;
fid: number | null;
inp: number | null;
total_requests: number | null;
failed_requests: number | null;
total_transfer_size: number | null;
captured_at: number;
}
export interface Database {
sessions: SessionTable;
states: StateTable;
actions: ActionTable;
anomalies: AnomalyTable;
notifications: NotificationTable;
schedules: ScheduleTable;
visual_baselines: VisualBaselineTable;
visual_comparisons: VisualComparisonTable;
performance_metrics: PerformanceMetricTable;
}
export function createDatabase(config: { driver: string; path: string; url?: string }): Kysely<Database> {
if (config.driver === 'postgres') {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { Pool } = require('pg') as { Pool: new (opts: { connectionString?: string }) => unknown };
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { PostgresDialect } = require('kysely') as { PostgresDialect: new (opts: { pool: unknown }) => SqliteDialect };
return new Kysely<Database>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString: config.url }) }),
});
}
fs.mkdirSync(path.dirname(config.path), { recursive: true });
return new Kysely<Database>({
dialect: new SqliteDialect({ database: new SQLite(config.path) }),
});
}