Simpl-Resultat/src/services/userPreferenceService.ts
le king fu 4febed9eab feat(data): announce counter-moving writes on a data-change channel
Add src/services/dataEvents.ts (ADR 0022): notifyDataChanged() and
subscribeDataChanged(), without React, on the model of logService.subscribe.
A throwing subscriber is logged and does not stop the others.

Notify after every successful write of the tables the getting-started
counters read, plus the import folder: setImportFolder, createSource,
deleteSource, createImportedFile, updateFileStatus, both import deletions,
insertBatch, updateTransactionCategory, applyKeywordWithReassignment (after
COMMIT), the four budget writes and runRestore (after COMMIT, one point for
the three restore modes). executeImport notifies once more when it ends,
succeeded or not. A failed write notifies nothing; transactional writes
notify once withTransaction has returned. applyTemplate notifies once for
the whole template through a private writeBudgetEntry helper.

Each service suite proves the notification after a success and its absence
after a failure; executeImport is driven as a plain function with React's
hooks stubbed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 07:33:47 -04:00

46 lines
1.3 KiB
TypeScript

import { getDb } from "./db";
import { notifyDataChanged } from "./dataEvents";
import type { UserPreference } from "../shared/types";
export async function getPreference(key: string): Promise<string | null> {
const db = await getDb();
const rows = await db.select<UserPreference[]>(
"SELECT * FROM user_preferences WHERE key = $1",
[key]
);
return rows.length > 0 ? rows[0].value : null;
}
export async function setPreference(
key: string,
value: string
): Promise<void> {
const db = await getDb();
await db.execute(
`INSERT INTO user_preferences (key, value, updated_at)
VALUES ($1, $2, CURRENT_TIMESTAMP)
ON CONFLICT(key) DO UPDATE SET value = $2, updated_at = CURRENT_TIMESTAMP`,
[key, value]
);
}
export async function deletePreference(key: string): Promise<void> {
const db = await getDb();
await db.execute(
"DELETE FROM user_preferences WHERE key = $1",
[key]
);
}
export async function getImportFolder(): Promise<string | null> {
return getPreference("import_folder");
}
/**
* Stores the import folder. The getting-started path counts it as a step, so
* a successful write is announced on the data channel (ADR 0022).
*/
export async function setImportFolder(path: string): Promise<void> {
await setPreference("import_folder", path);
notifyDataChanged();
}