fase(2): shared infrastructure layer
This commit is contained in:
150
src/shared/infrastructure/DatabaseConnection.ts
Normal file
150
src/shared/infrastructure/DatabaseConnection.ts
Normal 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) }),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user