docs(onboarding): user guide, architecture and QA checklist for the guided getting-started path #407

Merged
maximus merged 11 commits from issue-401-onboarding-guide-qa into main 2026-10-09 01:11:03 +00:00
Showing only changes of commit ec3b5d5185 - Show all commits

View file

@ -31,7 +31,7 @@ vi.mock("./db", () => {
};
});
import { getDb } from "./db";
import { getDb, withTransaction } from "./db";
import {
getExportImportSources,
getExportImportTemplates,
@ -803,6 +803,46 @@ describe("a committed restore is announced on the data channel (#396)", () => {
expect(seen[0][seen[0].length - 1]).toBe("COMMIT");
});
// ADR 0022: a write notifies once `withTransaction` has returned, never from
// its callback, where the DB lock is still held.
it.each([
[
"transactions with categories",
() =>
importTransactionsWithCategories(
envelopeData({ transactions: [transactionFixture(1)] }),
"backup.json"
),
],
[
"transactions only",
() => importTransactionsOnly(envelopeData({ transactions: [transactionFixture(1)] }), "backup.json"),
],
[
"categories only",
() => importCategoriesOnly({ categories: CATEGORY_FIXTURES, suppliers: [], keywords: [] }),
],
] as const)("%s: notifies once the DB lock is released", async (_name, restore) => {
let inLock = false;
const locks: boolean[] = [];
const stop = subscribeDataChanged(() => locks.push(inLock));
vi.mocked(withTransaction).mockImplementation(async (fn) => {
inLock = true;
try {
return await fn((await getDb()) as never);
} finally {
inLock = false;
}
});
try {
await restore();
} finally {
stop();
vi.mocked(withTransaction).mockImplementation(async (fn) => fn((await getDb()) as never));
}
expect(locks).toEqual([false]);
});
it("a restore rolled back announces nothing", async () => {
let txInserts = 0;
wire(