docs: codify the FK-safe stream ordering as a wire-format invariant
CI / lint (pull_request) Successful in 31s
CI / format (pull_request) Successful in 31s
CI / install-and-build (pull_request) Successful in 55s
CI / typecheck-tests (pull_request) Successful in 31s
CI / typecheck-source (pull_request) Successful in 31s
CI / test (pull_request) Successful in 42s
CI / lint (pull_request) Successful in 31s
CI / format (pull_request) Successful in 31s
CI / install-and-build (pull_request) Successful in 55s
CI / typecheck-tests (pull_request) Successful in 31s
CI / typecheck-source (pull_request) Successful in 31s
CI / test (pull_request) Successful in 42s
The postgres importer inserts records sequentially with FK enforcement live, so it depends on records arriving in dependency order. That requirement was implicit in each backend's export table list; make it explicit and enforced. - Add EXPORT_KIND_ORDER (user, abode, resident, apikey, note) as a documented single source of truth, with the FK dependency chain spelled out on its doc comment, and note the ordering guarantee on the ExportEnvelope wire-format doc. Derive the isExportKind set from it. - Both backends' export() now iterate EXPORT_KIND_ORDER via a loader map (postgres omits note by leaving it out of the map), so emission order is tied to the constant and can't drift. - Tests: a change-detector on EXPORT_KIND_ORDER, plus assertions that both the sqlite and postgres (fake) exports emit record kinds grouped in FK-safe order (kind rank non-decreasing down the stream, after the leading meta). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #13.
This commit is contained in:
@@ -4,6 +4,10 @@ import { Readable } from "node:stream";
|
||||
import { PostgresInterface } from "../../../src/db/postgres/PostgresInterface.js";
|
||||
import type { WrappedPgClient } from "../../../src/db/postgres/pool.js";
|
||||
import type { SqlCode } from "../../../src/db/postgres/sql.js";
|
||||
import {
|
||||
EXPORT_KIND_ORDER,
|
||||
type ExportKind,
|
||||
} from "../../../src/db/types/ExportImport.js";
|
||||
|
||||
// The postgres backend has no CI database, so these tests drive the real
|
||||
// PostgresInterface.export/import code paths against an in-memory fake client.
|
||||
@@ -158,6 +162,20 @@ describe("postgres export", () => {
|
||||
assert.ok(!kinds.has("note"), "note is unsupported on postgres");
|
||||
});
|
||||
|
||||
it("emits record kinds grouped in FK-safe EXPORT_KIND_ORDER", async () => {
|
||||
const db = new PostgresInterface(new FakePg(seededRows()));
|
||||
const lines = parseLines(await streamToString(db.export()));
|
||||
assert.equal(lines[0]?.kind, "meta", "first line is meta");
|
||||
const rank = (k: string) => EXPORT_KIND_ORDER.indexOf(k as ExportKind);
|
||||
let last = -1;
|
||||
for (const { kind } of lines.slice(1)) {
|
||||
const r = rank(kind);
|
||||
assert.notEqual(r, -1, `unexpected kind ${kind}`);
|
||||
assert.ok(r >= last, `kind ${kind} out of FK-safe order`);
|
||||
last = r;
|
||||
}
|
||||
});
|
||||
|
||||
it("applies the kinds filter", async () => {
|
||||
const db = new PostgresInterface(new FakePg(seededRows()));
|
||||
const lines = parseLines(
|
||||
|
||||
Reference in New Issue
Block a user