@catalyst-cloud/schema 0.1.12 → 0.1.13

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.12",
3
+ "version": "0.1.13",
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",
package/src/index.ts CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  issue_history,
19
19
  projects,
20
20
  cycles,
21
+ workflow_states,
21
22
  initiatives,
22
23
  project_initiatives,
23
24
  comments,
@@ -76,6 +77,7 @@ export const mirrorSchema = {
76
77
  issue_history,
77
78
  projects,
78
79
  cycles,
80
+ workflow_states,
79
81
  initiatives,
80
82
  project_initiatives,
81
83
  comments,
@@ -136,6 +138,7 @@ export const mirrorEntityTables = {
136
138
  issue_history,
137
139
  projects,
138
140
  cycles,
141
+ workflow_states,
139
142
  initiatives,
140
143
  project_initiatives,
141
144
  comments,
@@ -165,6 +165,13 @@ export const MIRROR_MIGRATIONS = {
165
165
  tag: "0021_worried_annihilus",
166
166
  breakpoints: true,
167
167
  },
168
+ {
169
+ idx: 22,
170
+ version: "6",
171
+ when: 1786928302892,
172
+ tag: "0022_chilly_gorgon",
173
+ breakpoints: true,
174
+ },
168
175
  ],
169
176
  },
170
177
  migrations: {
@@ -210,5 +217,7 @@ export const MIRROR_MIGRATIONS = {
210
217
  "CREATE TABLE `pr_review_backfill` (\n\t`repo_id` text NOT NULL,\n\t`pr_number` integer NOT NULL,\n\t`backfilled_at` integer NOT NULL,\n\tPRIMARY KEY(`repo_id`, `pr_number`)\n);\n--> statement-breakpoint\nALTER TABLE `reviews` ADD `body` text;",
211
218
  "0021_worried_annihilus":
212
219
  "CREATE TABLE `pr_ancillary_backfill` (\n\t`repo_id` text NOT NULL,\n\t`pr_number` integer NOT NULL,\n\t`backfilled_at` integer NOT NULL,\n\tPRIMARY KEY(`repo_id`, `pr_number`)\n);\n--> statement-breakpoint\nCREATE TABLE `pr_commits` (\n\t`repo_id` text NOT NULL,\n\t`pr_number` integer NOT NULL,\n\t`sha` text NOT NULL,\n\t`message` text,\n\t`author_login` text,\n\t`author_name` text,\n\t`author_email` text,\n\t`authored_at` integer,\n\t`committed_at` integer,\n\tPRIMARY KEY(`repo_id`, `pr_number`, `sha`)\n);\n--> statement-breakpoint\nCREATE TABLE `pr_conversation_comments` (\n\t`id` text PRIMARY KEY NOT NULL,\n\t`repo_id` text NOT NULL,\n\t`pr_number` integer NOT NULL,\n\t`author_id` text,\n\t`body` text,\n\t`created_at` integer,\n\t`updated_at` integer,\n\t`removed_at` integer\n);\n--> statement-breakpoint\nCREATE INDEX `idx_pr_conversation_comments_pr` ON `pr_conversation_comments` (`repo_id`,`pr_number`);--> statement-breakpoint\nCREATE TABLE `pr_events` (\n\t`id` text PRIMARY KEY NOT NULL,\n\t`repo_id` text NOT NULL,\n\t`pr_number` integer NOT NULL,\n\t`action` text,\n\t`actor_id` text,\n\t`created_at` integer,\n\t`updated_at` integer,\n\t`raw` text\n);\n--> statement-breakpoint\nCREATE INDEX `idx_pr_events_pr` ON `pr_events` (`repo_id`,`pr_number`,`created_at`);--> statement-breakpoint\nCREATE TABLE `pr_review_comments` (\n\t`id` text PRIMARY KEY NOT NULL,\n\t`repo_id` text NOT NULL,\n\t`pr_number` integer NOT NULL,\n\t`review_id` text,\n\t`commit_id` text,\n\t`path` text,\n\t`line` integer,\n\t`diff_hunk` text,\n\t`in_reply_to_id` text,\n\t`author_id` text,\n\t`body` text,\n\t`created_at` integer,\n\t`updated_at` integer,\n\t`removed_at` integer\n);\n--> statement-breakpoint\nCREATE INDEX `idx_pr_review_comments_pr` ON `pr_review_comments` (`repo_id`,`pr_number`);",
220
+ "0022_chilly_gorgon":
221
+ "CREATE TABLE `workflow_states` (\n\t`id` text PRIMARY KEY NOT NULL,\n\t`team_id` text,\n\t`name` text,\n\t`type` text,\n\t`position` real,\n\t`color` text,\n\t`archived_at` integer,\n\t`updated_at` integer\n);\n--> statement-breakpoint\nCREATE INDEX `idx_workflow_states_team` ON `workflow_states` (`team_id`);--> statement-breakpoint\nALTER TABLE `issues` ADD `state_type` text;--> statement-breakpoint\nALTER TABLE `issues` ADD `state_position` real;",
213
222
  },
214
223
  } as const;
package/src/mirror.ts CHANGED
@@ -39,6 +39,11 @@ export const issues = sqliteTable(
39
39
  // CTC-148: the workflow state id behind the `state` NAME — lets a consumer key on state without
40
40
  // string-matching the renameable name.
41
41
  state_id: text("state_id"),
42
+ // CTC-308: the state's bucket (triage|backlog|unstarted|started|completed|canceled) + its manual
43
+ // column order — denormalized off `state` (the `workflow_states` FK, below) so a board can order
44
+ // its columns without a join on the hot path. Null on a partial webhook, exactly like state_id.
45
+ state_type: text("state_type"),
46
+ state_position: real("state_position"),
42
47
  assignee: text("assignee"),
43
48
  // CTC-USERS: the assignee's user id (FK → users.id), so the row JOINs to a name + avatar. The
44
49
  // legacy `assignee` name string is KEPT for back-compat (the SSE list row still carries it).
@@ -308,6 +313,28 @@ export const cycles = sqliteTable("cycles", {
308
313
  updated_at: integer("updated_at"),
309
314
  });
310
315
 
316
+ // Linear workflow states (CTC-308) — the id/type/position behind an issue's `state` NAME, mirrored as
317
+ // its own entity table so a board can order columns by (type, position) and key a column across teams
318
+ // (the prerequisite CTC-277's kanban board blocks on). Small, workspace-wide set — full sweep each
319
+ // pass, same discipline as `labels`/`cycles`. No `removed_at`: Linear ARCHIVES a workflow state rather
320
+ // than deleting it (`archived_at`), same convention `issues.archived_at` already uses.
321
+ export const workflow_states = sqliteTable(
322
+ "workflow_states",
323
+ {
324
+ id: text("id").primaryKey(),
325
+ team_id: text("team_id"),
326
+ name: text("name"),
327
+ // The state's bucket: triage | backlog | unstarted | started | completed | canceled.
328
+ type: text("type"),
329
+ // Manual sort rank within its team's workflow — a Float, Linear's own column order.
330
+ position: real("position"),
331
+ color: text("color"),
332
+ archived_at: integer("archived_at"),
333
+ updated_at: integer("updated_at"),
334
+ },
335
+ (t) => [index("idx_workflow_states_team").on(t.team_id)],
336
+ );
337
+
311
338
  // Linear initiatives (CTC-HIERARCHY) — the top of the HIERARCHY (initiative → project → cycle →
312
339
  // issue). PK `id` (Linear node id). `status` is the InitiativeStatus enum string; `target_date` is a
313
340
  // TimelessDate ("YYYY-MM-DD") stored AS-IS as TEXT (the trap). `owner_id` is the FK → users.id.