import { ipcMain } from "electron"; import type { ArtifactStoreLoadResult, ArtifactStoreRepositoryPort, ArtifactStoreSaveResult, ReviewSampleListResult, ReviewSamplePayload, ReviewSamplesRepositoryPort, } from "../repositories/contracts.js"; import type { GoodDatabase, LoadScannerLearningRulesResult, SaveScannerLearningRulesResult, ScannerLearningRulePayload, SaveResultWithPath, GoodImportFileResult, } from "../../src/types/global.js"; import type { StoredArtifactRecord } from "../../src/types/storage.js"; type ArtifactStoreAccessor = () => ArtifactStoreRepositoryPort; type ReviewSamplesAccessor = () => ReviewSamplesRepositoryPort; interface PersistenceDependencies { getArtifactStoreRepository: ArtifactStoreAccessor; getReviewSamplesRepository: ReviewSamplesAccessor; artifactStorePath: () => string; reviewSamplesPath: () => string; loadReviewSamples: (limit?: number) => Promise; loadScannerLearningRules: () => Promise; writeScannerLearningRules: (rules: ScannerLearningRulePayload) => Promise; exportGood: (payload: GoodDatabase) => Promise; importGoodFile: () => Promise; } export function registerPersistenceHandlers({ getArtifactStoreRepository, getReviewSamplesRepository, artifactStorePath, reviewSamplesPath, loadReviewSamples, loadScannerLearningRules, writeScannerLearningRules, exportGood, importGoodFile, }: PersistenceDependencies) { ipcMain.handle("review:saveSample", async (_event, sample: ReviewSamplePayload) => { try { return await getReviewSamplesRepository().append(sample); } catch { const filePath = reviewSamplesPath(); return { ok: false, path: filePath }; } }); ipcMain.handle("review:loadSamples", async (_event, limit = 50) => { return loadReviewSamples(Number(limit) || 50); }); ipcMain.handle("scanner:loadLearningRules", async () => { return loadScannerLearningRules(); }); ipcMain.handle("scanner:saveLearningRules", async (_event, rules: ScannerLearningRulePayload) => { return writeScannerLearningRules(rules); }); ipcMain.handle("artifacts:load", async () => { try { return (await getArtifactStoreRepository().loadAll()) as ArtifactStoreLoadResult; } catch { return { ok: false, artifacts: [], total: 0, path: artifactStorePath() }; } }); ipcMain.handle("artifacts:saveMany", async (_event, records: StoredArtifactRecord[]) => { try { const safeRecords = Array.isArray(records) ? records : []; return (await getArtifactStoreRepository().saveMany(safeRecords)) as ArtifactStoreSaveResult; } catch { return { ok: false, added: 0, updated: 0, total: 0, path: artifactStorePath() }; } }); ipcMain.handle("good:export", async (_event, payload: GoodDatabase) => { return exportGood(payload); }); ipcMain.handle("good:importFile", async () => { return importGoodFile(); }); }