From 3c3709b0ef75111bed4379e14055ae25782a23a9 Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Wed, 28 Oct 2026 02:26:55 +0530 Subject: [PATCH 1/3] perf(db): add partial index for pending due actions --- services/api/src/schema.ts | 4 +++ services/api/test/due-action-index.test.ts | 29 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 services/api/test/due-action-index.test.ts diff --git a/services/api/src/schema.ts b/services/api/src/schema.ts index 75dee2d..bab000f 100644 --- a/services/api/src/schema.ts +++ b/services/api/src/schema.ts @@ -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; `, ]; diff --git a/services/api/test/due-action-index.test.ts b/services/api/test/due-action-index.test.ts new file mode 100644 index 0000000..465347e --- /dev/null +++ b/services/api/test/due-action-index.test.ts @@ -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 }); + } + }); +}); From cbbd7b8a695f2c689ac461d3fa8a00f83697aa02 Mon Sep 17 00:00:00 2001 From: Harshit Sharma <66710144+harshitethic@users.noreply.github.com> Date: Sat, 31 Oct 2026 05:53:40 -0400 Subject: [PATCH 2/3] test(db): register v3 upgrade fixture generator --- services/api/test/fixtures/make-db-fixtures.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/api/test/fixtures/make-db-fixtures.ts b/services/api/test/fixtures/make-db-fixtures.ts index ea182a5..e45dad4 100644 --- a/services/api/test/fixtures/make-db-fixtures.ts +++ b/services/api/test/fixtures/make-db-fixtures.ts @@ -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')`); From ef7ab7c57b27d56bc47bcef191e984e14d9d2d00 Mon Sep 17 00:00:00 2001 From: Harshit Sharma <66710144+harshitethic@users.noreply.github.com> Date: Sat, 31 Oct 2026 05:55:05 -0400 Subject: [PATCH 3/3] test(db): include frozen v3 SQLite migration fixture --- services/api/test/fixtures/db/org-v3.db | Bin 0 -> 122880 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 services/api/test/fixtures/db/org-v3.db diff --git a/services/api/test/fixtures/db/org-v3.db b/services/api/test/fixtures/db/org-v3.db new file mode 100644 index 0000000000000000000000000000000000000000..dd1cfa327dc2339b6443c74c0c2ffe9bc3431869 GIT binary patch literal 122880 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