@catalyst-cloud/schema 0.1.37 → 0.1.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catalyst-cloud/schema",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "type": "module",
5
5
  "description": "Typed Drizzle schema = single source of truth for the per-tenant Mirror DO SQLite store (CTC-13 / ADR-0002). Shared by the mirror Worker, the host-sync replica, and the browser OPFS replica.",
6
6
  "license": "MIT",
@@ -249,6 +249,13 @@ export const MIRROR_MIGRATIONS = {
249
249
  tag: "0033_lethal_electro",
250
250
  breakpoints: true,
251
251
  },
252
+ {
253
+ idx: 34,
254
+ version: "6",
255
+ when: 1788312053951,
256
+ tag: "0034_special_onslaught",
257
+ breakpoints: true,
258
+ },
252
259
  ],
253
260
  },
254
261
  migrations: {
@@ -317,5 +324,7 @@ export const MIRROR_MIGRATIONS = {
317
324
  "ALTER TABLE `issues` ADD `creator_id` text;--> statement-breakpoint\nALTER TABLE `issues` ADD `creator_name` text;--> statement-breakpoint\nALTER TABLE `issues` ADD `creator_avatar_url` text;",
318
325
  "0033_lethal_electro":
319
326
  "ALTER TABLE `labels` ADD `team_id` text;--> statement-breakpoint\nCREATE INDEX `idx_labels_team` ON `labels` (`team_id`);",
327
+ "0034_special_onslaught":
328
+ "CREATE INDEX `idx_processed_events_source_received` ON `processed_events` (`source`,`received_at`);",
320
329
  },
321
330
  } as const;
package/src/mirror.ts CHANGED
@@ -1070,12 +1070,31 @@ export const pr_review_threads = sqliteTable(
1070
1070
 
1071
1071
  // ── Mirror infra (not domain entities — never ride the change-feed) ─────────────────────────────────
1072
1072
 
1073
- export const processed_events = sqliteTable("processed_events", {
1074
- delivery_id: text("delivery_id").primaryKey(),
1075
- source: text("source"),
1076
- event_type: text("event_type"),
1077
- received_at: integer("received_at"),
1078
- });
1073
+ /**
1074
+ * CTC-1441 — the webhook dedup marker, one row per provider delivery. DELIBERATELY NEVER PRUNED (see
1075
+ * `linearPurgeStatements`' doc in apps/mirror/src/do/MirrorDO.ts: old markers must never collide with
1076
+ * a new workspace's deliveries), so this table only ever grows — 762,190 rows on tenant-0 as of
1077
+ * 2026-09-02, climbing ~53,000 a day.
1078
+ *
1079
+ * ⭐ THE INDEX IS LOAD-BEARING, AND ITS COLUMN ORDER IS THE WHOLE POINT. `computeFreshness`
1080
+ * (apps/mirror/src/do/changefeed.ts) runs `SELECT max(received_at) ... WHERE source = ?` once per
1081
+ * source on EVERY reconcile pass, which is every alarm tick. With only the `delivery_id` primary key
1082
+ * that predicate was a full table scan, twice per alarm — measured at 2.21 BILLION rows read a day on
1083
+ * tenant-0, 93-100% of the account's entire Durable Objects rows-read bill. `(source, received_at)`
1084
+ * lets SQLite's max() optimization seek to the end of the source group and read ONE index entry;
1085
+ * `(source)` alone would only narrow the scan to that source's ~half of the table, which is not the
1086
+ * fix. Pinned by apps/mirror/test/processed-events-query-plan.test.ts.
1087
+ */
1088
+ export const processed_events = sqliteTable(
1089
+ "processed_events",
1090
+ {
1091
+ delivery_id: text("delivery_id").primaryKey(),
1092
+ source: text("source"),
1093
+ event_type: text("event_type"),
1094
+ received_at: integer("received_at"),
1095
+ },
1096
+ (t) => [index("idx_processed_events_source_received").on(t.source, t.received_at)],
1097
+ );
1079
1098
 
1080
1099
  export const change_log = sqliteTable("change_log", {
1081
1100
  seq: integer("seq").primaryKey({ autoIncrement: true }),