"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KyselyFindingRepository = void 0; const Finding_1 = require("../../domain/entities/Finding"); const UniqueId_1 = require("../../../../shared/domain/UniqueId"); const Severity_1 = require("../../domain/value-objects/Severity"); const FindingType_1 = require("../../domain/value-objects/FindingType"); const FindingStatus_1 = require("../../domain/value-objects/FindingStatus"); const Evidence_1 = require("../../domain/value-objects/Evidence"); class KyselyFindingRepository { constructor(db) { this.db = db; } async save(finding) { const row = { id: finding.id.toString(), session_id: finding.sessionId, type: finding.type.value, severity: finding.severity.value, description: finding.description, status: finding.status.value, action_trace_json: JSON.stringify(finding.actionTrace), evidence_json: JSON.stringify(finding.evidence.toJSON()), screenshot_path: finding.evidence.screenshotPath ?? null, dom_snapshot_path: finding.evidence.domSnapshotPath ?? null, browser: finding.browser ?? null, browser_version: finding.browserVersion ?? null, ai_enrichment_json: finding.aiEnrichment ? JSON.stringify(finding.aiEnrichment) : null, created_at: finding.createdAt.getTime(), resolved_at: finding.resolvedAt ? finding.resolvedAt.getTime() : null, }; await this.db.insertInto('findings').values(row).execute(); } async findById(id) { const row = await this.db .selectFrom('findings') .selectAll() .where('id', '=', id) .executeTakeFirst(); return row ? this.toDomain(row) : undefined; } async findAll(filters) { let query = this.db.selectFrom('findings').selectAll(); if (filters?.sessionId) { query = query.where('session_id', '=', filters.sessionId); } if (filters?.severity) { query = query.where('severity', '=', filters.severity); } if (filters?.type) { query = query.where('type', '=', filters.type); } if (filters?.status) { query = query.where('status', '=', filters.status); } if (filters?.search) { query = query.where('description', 'like', `%${filters.search}%`); } const rows = await query.orderBy('created_at', 'desc').execute(); return rows.map((row) => this.toDomain(row)); } async update(finding) { await this.db .updateTable('findings') .set({ status: finding.status.value, ai_enrichment_json: finding.aiEnrichment ? JSON.stringify(finding.aiEnrichment) : null, resolved_at: finding.resolvedAt ? finding.resolvedAt.getTime() : null, }) .where('id', '=', finding.id.toString()) .execute(); } async count(filters) { let query = this.db.selectFrom('findings').select(eb => eb.fn.countAll().as('cnt')); if (filters?.sessionId) { query = query.where('session_id', '=', filters.sessionId); } if (filters?.severity) { query = query.where('severity', '=', filters.severity); } if (filters?.type) { query = query.where('type', '=', filters.type); } if (filters?.status) { query = query.where('status', '=', filters.status); } const result = await query.executeTakeFirst(); return Number(result?.cnt ?? 0); } async countBySeverity() { const rows = await this.db .selectFrom('findings') .select(['severity', eb => eb.fn.countAll().as('cnt')]) .groupBy('severity') .execute(); const result = {}; for (const row of rows) { result[row.severity] = Number(row.cnt); } return result; } toDomain(row) { const actionTrace = this.parseJson(row.action_trace_json, []); const evidenceData = this.parseJson(row.evidence_json, {}); const aiEnrichment = row.ai_enrichment_json ? this.parseJson(row.ai_enrichment_json, undefined) : undefined; const props = { sessionId: row.session_id, severity: Severity_1.Severity.fromString(row.severity), type: FindingType_1.FindingType.fromString(row.type), description: row.description, evidence: Evidence_1.Evidence.create({ screenshotPath: row.screenshot_path ?? undefined, domSnapshotPath: row.dom_snapshot_path ?? undefined, httpLog: evidenceData.httpLog ?? [], rawErrors: evidenceData.rawErrors ?? [], }), status: FindingStatus_1.FindingStatus.fromString(row.status), actionTrace, browser: row.browser ?? undefined, browserVersion: row.browser_version ?? undefined, aiEnrichment, createdAt: new Date(row.created_at), resolvedAt: row.resolved_at ? new Date(row.resolved_at) : undefined, }; return Finding_1.Finding.reconstitute(props, UniqueId_1.UniqueId.from(row.id)); } parseJson(json, fallback) { try { return JSON.parse(json); } catch { return fallback; } } } exports.KyselyFindingRepository = KyselyFindingRepository;