fase(2): shared infrastructure layer
This commit is contained in:
135
dist/db/migrations/001_initial_schema.js
vendored
Normal file
135
dist/db/migrations/001_initial_schema.js
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.up = up;
|
||||
exports.down = down;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async function up(db) {
|
||||
await db.schema.createTable('sessions')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('url', 'text', col => col.notNull())
|
||||
.addColumn('status', 'text', col => col.notNull().defaultTo('running'))
|
||||
.addColumn('seed', 'integer', col => col.notNull())
|
||||
.addColumn('max_states', 'integer', col => col.notNull().defaultTo(50))
|
||||
.addColumn('states_visited', 'integer', col => col.notNull().defaultTo(0))
|
||||
.addColumn('anomalies_found', 'integer', col => col.notNull().defaultTo(0))
|
||||
.addColumn('started_at', 'integer', col => col.notNull())
|
||||
.addColumn('finished_at', 'integer')
|
||||
.addColumn('config_json', 'text', col => col.notNull().defaultTo('{}'))
|
||||
.execute();
|
||||
await db.schema.createTable('states')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('session_id', 'text', col => col.notNull().references('sessions.id'))
|
||||
.addColumn('url', 'text', col => col.notNull())
|
||||
.addColumn('title', 'text', col => col.notNull())
|
||||
.addColumn('dom_snapshot_path', 'text')
|
||||
.addColumn('visit_count', 'integer', col => col.notNull().defaultTo(0))
|
||||
.addColumn('discovered_at', 'integer', col => col.notNull())
|
||||
.execute();
|
||||
await db.schema.createTable('actions')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('session_id', 'text', col => col.notNull().references('sessions.id'))
|
||||
.addColumn('state_id', 'text', col => col.notNull().references('states.id'))
|
||||
.addColumn('type', 'text', col => col.notNull())
|
||||
.addColumn('selector', 'text')
|
||||
.addColumn('value', 'text')
|
||||
.addColumn('url', 'text')
|
||||
.addColumn('seed', 'integer', col => col.notNull())
|
||||
.addColumn('executed_at', 'integer', col => col.notNull())
|
||||
.addColumn('sequence_order', 'integer', col => col.notNull())
|
||||
.execute();
|
||||
await db.schema.createTable('anomalies')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('session_id', 'text', col => col.notNull().references('sessions.id'))
|
||||
.addColumn('type', 'text', col => col.notNull())
|
||||
.addColumn('severity', 'text', col => col.notNull())
|
||||
.addColumn('description', 'text', col => col.notNull())
|
||||
.addColumn('action_trace_json', 'text', col => col.notNull())
|
||||
.addColumn('evidence_json', 'text', col => col.notNull())
|
||||
.addColumn('screenshot_path', 'text')
|
||||
.addColumn('dom_snapshot_path', 'text')
|
||||
.addColumn('detected_at', 'integer', col => col.notNull())
|
||||
.addColumn('ai_enrichment_json', 'text')
|
||||
.addColumn('ai_enriched_at', 'integer')
|
||||
.addColumn('browser', 'text')
|
||||
.addColumn('browser_version', 'text')
|
||||
.execute();
|
||||
await db.schema.createTable('notifications')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('anomaly_id', 'text', col => col.notNull().references('anomalies.id'))
|
||||
.addColumn('channel', 'text', col => col.notNull())
|
||||
.addColumn('status', 'text', col => col.notNull().defaultTo('pending'))
|
||||
.addColumn('sent_at', 'integer')
|
||||
.addColumn('error', 'text')
|
||||
.execute();
|
||||
await db.schema.createTable('schedules')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('name', 'text', col => col.notNull())
|
||||
.addColumn('url', 'text', col => col.notNull())
|
||||
.addColumn('config_json', 'text', col => col.notNull())
|
||||
.addColumn('cron_expression', 'text', col => col.notNull())
|
||||
.addColumn('enabled', 'integer', col => col.notNull().defaultTo(1))
|
||||
.addColumn('last_run_at', 'integer')
|
||||
.addColumn('next_run_at', 'integer')
|
||||
.addColumn('created_at', 'integer', col => col.notNull())
|
||||
.execute();
|
||||
await db.schema.createTable('visual_baselines')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('state_id', 'text', col => col.notNull())
|
||||
.addColumn('url', 'text', col => col.notNull())
|
||||
.addColumn('screenshot_path', 'text', col => col.notNull())
|
||||
.addColumn('approved_at', 'integer', col => col.notNull())
|
||||
.addColumn('approved_by', 'text')
|
||||
.addColumn('width', 'integer', col => col.notNull())
|
||||
.addColumn('height', 'integer', col => col.notNull())
|
||||
.execute();
|
||||
await db.schema.createTable('visual_comparisons')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('session_id', 'text', col => col.notNull())
|
||||
.addColumn('state_id', 'text', col => col.notNull())
|
||||
.addColumn('baseline_id', 'text')
|
||||
.addColumn('current_screenshot_path', 'text', col => col.notNull())
|
||||
.addColumn('diff_screenshot_path', 'text')
|
||||
.addColumn('diff_pixels', 'integer')
|
||||
.addColumn('diff_percent', 'real')
|
||||
.addColumn('status', 'text', col => col.notNull())
|
||||
.addColumn('created_at', 'integer', col => col.notNull())
|
||||
.execute();
|
||||
await db.schema.createTable('performance_metrics')
|
||||
.ifNotExists()
|
||||
.addColumn('id', 'text', col => col.primaryKey())
|
||||
.addColumn('session_id', 'text', col => col.notNull())
|
||||
.addColumn('state_id', 'text', col => col.notNull())
|
||||
.addColumn('url', 'text', col => col.notNull())
|
||||
.addColumn('ttfb', 'integer')
|
||||
.addColumn('dom_content_loaded', 'integer')
|
||||
.addColumn('load_complete', 'integer')
|
||||
.addColumn('lcp', 'integer')
|
||||
.addColumn('cls', 'real')
|
||||
.addColumn('fid', 'integer')
|
||||
.addColumn('inp', 'integer')
|
||||
.addColumn('total_requests', 'integer')
|
||||
.addColumn('failed_requests', 'integer')
|
||||
.addColumn('total_transfer_size', 'integer')
|
||||
.addColumn('captured_at', 'integer', col => col.notNull())
|
||||
.execute();
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async function down(db) {
|
||||
await db.schema.dropTable('performance_metrics').ifExists().execute();
|
||||
await db.schema.dropTable('visual_comparisons').ifExists().execute();
|
||||
await db.schema.dropTable('visual_baselines').ifExists().execute();
|
||||
await db.schema.dropTable('schedules').ifExists().execute();
|
||||
await db.schema.dropTable('notifications').ifExists().execute();
|
||||
await db.schema.dropTable('anomalies').ifExists().execute();
|
||||
await db.schema.dropTable('actions').ifExists().execute();
|
||||
await db.schema.dropTable('states').ifExists().execute();
|
||||
await db.schema.dropTable('sessions').ifExists().execute();
|
||||
}
|
||||
31
dist/db/migrator.js
vendored
Normal file
31
dist/db/migrator.js
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runMigrations = runMigrations;
|
||||
const kysely_1 = require("kysely");
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const promises_1 = __importDefault(require("fs/promises"));
|
||||
async function runMigrations(db) {
|
||||
const migrator = new kysely_1.Migrator({
|
||||
db,
|
||||
provider: new kysely_1.FileMigrationProvider({
|
||||
fs: promises_1.default,
|
||||
path: path_1.default,
|
||||
migrationFolder: path_1.default.join(__dirname, 'migrations'),
|
||||
}),
|
||||
});
|
||||
const { error, results } = await migrator.migrateToLatest();
|
||||
results?.forEach(result => {
|
||||
if (result.status === 'Success') {
|
||||
console.log(`Migration "${result.migrationName}" executed successfully`);
|
||||
}
|
||||
else if (result.status === 'Error') {
|
||||
console.error(`Migration "${result.migrationName}" failed`);
|
||||
}
|
||||
});
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user