Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions services/api/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ CREATE TABLE break_note_history (
CREATE INDEX break_note_history_key ON break_note_history (asset_id, scope, key, id);
INSERT INTO break_note_history (asset_id, scope, key, fingerprint, status, note, author, author_id, at)
SELECT asset_id, scope, key, fingerprint, status, note, author, author_id, updated_at FROM break_notes;
`,
// v3: keep the recurring reconcileDue search off reconciled action rows.
`
CREATE INDEX actions_due ON actions (record_time) WHERE snapshot IS NULL;
`,
];

Expand Down
29 changes: 29 additions & 0 deletions services/api/test/due-action-index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { Db } from "../src/db.js";
import { ORG_MIGRATIONS } from "../src/schema.js";

describe("due action migration index", () => {
it("upgrades a version-1 workspace and uses a partial index for unreconciled actions", () => {
const dir = mkdtempSync(join(tmpdir(), "concord-due-index-"));
const path = join(dir, "org.db");
try {
const old = new Db(path, [ORG_MIGRATIONS[0]!]);
old.close();
const db = new Db(path, ORG_MIGRATIONS);
try {
expect(db.get<{ user_version: number }>("PRAGMA user_version")?.user_version).toBe(ORG_MIGRATIONS.length);
const plans = db.raw.prepare(
"EXPLAIN QUERY PLAN SELECT id FROM actions WHERE snapshot IS NULL AND record_time <= ?",
).all("2026-10-28T00:00:00Z") as Array<{ detail: string }>;
expect(plans.map((p) => p.detail).join("\n")).toContain("actions_due");
} finally {
db.close();
}
} finally {
rmSync(dir, { recursive: true, force: true });
}
});
});
Binary file added services/api/test/fixtures/db/org-v3.db
Binary file not shown.
5 changes: 5 additions & 0 deletions services/api/test/fixtures/make-db-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ build(join(outDir, "org-v2.db"), ORG_MIGRATIONS.slice(0, 2), (db) => {
('usd-mainnet', 'recon', 'SUPPLY_MISMATCH', '10|12', 'resolved', 'corrected', 'bob', 'u2', '2024-01-05T00:00:00Z')`);
});

// Freeze the v3 schema for future upgrade-compatibility checks.
build(join(outDir, "org-v3.db"), ORG_MIGRATIONS.slice(0, 3), (db) => {
db.exec("INSERT INTO meta (key, value) VALUES ('fixture', 'org-v3')");
});

build(join(outDir, "control-v1.db"), CONTROL_MIGRATIONS.slice(0, 1), (db) => {
db.exec(`INSERT INTO users (id, email, name, email_verified, created_at)
VALUES ('u1', 'alice@example.org', 'Alice', 1, '2024-01-01T00:00:00Z')`);
Expand Down
Loading