chore: initialize repository baseline
Import the existing Electron + React + TypeScript app as the version-control baseline before the scanner rework (C# input/capture sidecar, resolution-anchored layout profiles, OCR preprocessing, eval harness, rescan-merge, GOOD interop). Housekeeping in this commit: - Remove orphaned temp_inputhelper_block.ts (duplicate of the input-helper script). - Ignore .claude/scheduled_tasks.lock local session state. - Add .gitattributes to normalize line endings (LF in repo). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { ipcMain } from "electron";
|
||||
import type {
|
||||
ArtifactStoreLoadResult,
|
||||
ArtifactStoreRepositoryPort,
|
||||
ArtifactStoreSaveResult,
|
||||
ReviewSampleListResult,
|
||||
ReviewSamplePayload,
|
||||
ReviewSamplesRepositoryPort,
|
||||
} from "../repositories/contracts.js";
|
||||
import type {
|
||||
GoodDatabase,
|
||||
LoadScannerLearningRulesResult,
|
||||
SaveScannerLearningRulesResult,
|
||||
ScannerLearningRulePayload,
|
||||
SaveResultWithPath,
|
||||
} 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<ReviewSampleListResult>;
|
||||
loadScannerLearningRules: () => Promise<LoadScannerLearningRulesResult>;
|
||||
writeScannerLearningRules: (rules: ScannerLearningRulePayload) => Promise<SaveScannerLearningRulesResult>;
|
||||
exportGood: (payload: GoodDatabase) => Promise<SaveResultWithPath>;
|
||||
}
|
||||
|
||||
export function registerPersistenceHandlers({
|
||||
getArtifactStoreRepository,
|
||||
getReviewSamplesRepository,
|
||||
artifactStorePath,
|
||||
reviewSamplesPath,
|
||||
loadReviewSamples,
|
||||
loadScannerLearningRules,
|
||||
writeScannerLearningRules,
|
||||
exportGood,
|
||||
}: 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);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user