@cat-factory/worker 0.80.1 → 0.80.2

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.
@@ -0,0 +1,114 @@
1
+ -- Referential integrity for the user-identity lineage (the account-orphaning incident).
2
+ --
3
+ -- Previously NOTHING referenced users(id) at the DB level, so a users row could be removed
4
+ -- while its identity, personal account, personal subscription, memberships, and run
5
+ -- activations lived on — a dangling identity that the login path then silently forked a
6
+ -- fresh (empty) account around. Add ON DELETE RESTRICT foreign keys so a users row can no
7
+ -- longer be dropped while any of those still reference it; an unsafe delete now fails
8
+ -- loudly instead of orphaning.
9
+ --
10
+ -- SQLite cannot ALTER a table to add a constraint, so each table is rebuilt via the
11
+ -- standard create-new / copy / drop / rename dance and its indexes recreated. The current
12
+ -- (post-migration) column shapes are reproduced exactly — including accounts.spend_monthly_limit
13
+ -- (added in 0042). user_id on personal_subscriptions, memberships, and subscription_activations
14
+ -- is also corrected from INTEGER to TEXT to match the canonical `usr_*` users.id (the Postgres
15
+ -- side is already text).
16
+ --
17
+ -- defer_foreign_keys holds FK enforcement until this transaction commits, so the drop/rename
18
+ -- steps of the rebuild dance don't trip an intermediate constraint check (mirrors 0001_init).
19
+
20
+ PRAGMA defer_foreign_keys=TRUE;
21
+
22
+ -- user_identities.user_id -> users(id)
23
+ CREATE TABLE user_identities_new (
24
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
25
+ provider TEXT NOT NULL,
26
+ subject TEXT NOT NULL,
27
+ secret TEXT,
28
+ metadata TEXT,
29
+ created_at INTEGER NOT NULL,
30
+ PRIMARY KEY (provider, subject)
31
+ );
32
+ INSERT INTO user_identities_new (user_id, provider, subject, secret, metadata, created_at)
33
+ SELECT user_id, provider, subject, secret, metadata, created_at FROM user_identities;
34
+ DROP TABLE user_identities;
35
+ ALTER TABLE user_identities_new RENAME TO user_identities;
36
+ CREATE INDEX idx_user_identities_user ON user_identities (user_id);
37
+
38
+ -- accounts.owner_user_id -> users(id) (nullable: null for org accounts)
39
+ CREATE TABLE accounts_new (
40
+ id TEXT NOT NULL PRIMARY KEY,
41
+ type TEXT NOT NULL,
42
+ name TEXT NOT NULL,
43
+ github_account_login TEXT,
44
+ created_at INTEGER NOT NULL,
45
+ default_cloud_provider TEXT,
46
+ owner_user_id TEXT REFERENCES users(id) ON DELETE RESTRICT,
47
+ spend_monthly_limit REAL
48
+ );
49
+ INSERT INTO accounts_new (id, type, name, github_account_login, created_at, default_cloud_provider, owner_user_id, spend_monthly_limit)
50
+ SELECT id, type, name, github_account_login, created_at, default_cloud_provider, owner_user_id, spend_monthly_limit FROM accounts;
51
+ DROP TABLE accounts;
52
+ ALTER TABLE accounts_new RENAME TO accounts;
53
+ CREATE UNIQUE INDEX idx_accounts_personal
54
+ ON accounts (owner_user_id)
55
+ WHERE type = 'personal';
56
+
57
+ -- personal_subscriptions.user_id -> users(id) (also INTEGER -> TEXT)
58
+ CREATE TABLE personal_subscriptions_new (
59
+ id TEXT NOT NULL,
60
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
61
+ vendor TEXT NOT NULL,
62
+ label TEXT NOT NULL,
63
+ token_cipher TEXT NOT NULL,
64
+ expires_at INTEGER,
65
+ created_at INTEGER NOT NULL,
66
+ updated_at INTEGER NOT NULL,
67
+ last_used_at INTEGER,
68
+ deleted_at INTEGER,
69
+ PRIMARY KEY (id)
70
+ );
71
+ INSERT INTO personal_subscriptions_new (id, user_id, vendor, label, token_cipher, expires_at, created_at, updated_at, last_used_at, deleted_at)
72
+ SELECT id, user_id, vendor, label, token_cipher, expires_at, created_at, updated_at, last_used_at, deleted_at FROM personal_subscriptions;
73
+ DROP TABLE personal_subscriptions;
74
+ ALTER TABLE personal_subscriptions_new RENAME TO personal_subscriptions;
75
+ CREATE UNIQUE INDEX idx_personal_subs_user_vendor
76
+ ON personal_subscriptions (user_id, vendor)
77
+ WHERE deleted_at IS NULL;
78
+ CREATE INDEX idx_personal_subs_expiry
79
+ ON personal_subscriptions (expires_at)
80
+ WHERE deleted_at IS NULL;
81
+
82
+ -- memberships.user_id -> users(id) (also INTEGER -> TEXT)
83
+ CREATE TABLE memberships_new (
84
+ account_id TEXT NOT NULL,
85
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
86
+ roles TEXT NOT NULL DEFAULT 'developer',
87
+ created_at INTEGER NOT NULL,
88
+ PRIMARY KEY (account_id, user_id)
89
+ );
90
+ INSERT INTO memberships_new (account_id, user_id, roles, created_at)
91
+ SELECT account_id, user_id, roles, created_at FROM memberships;
92
+ DROP TABLE memberships;
93
+ ALTER TABLE memberships_new RENAME TO memberships;
94
+ CREATE INDEX idx_memberships_user ON memberships (user_id);
95
+
96
+ -- subscription_activations.user_id -> users(id) (also INTEGER -> TEXT)
97
+ CREATE TABLE subscription_activations_new (
98
+ id TEXT NOT NULL,
99
+ execution_id TEXT NOT NULL,
100
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
101
+ vendor TEXT NOT NULL,
102
+ token_cipher TEXT NOT NULL,
103
+ created_at INTEGER NOT NULL,
104
+ expires_at INTEGER NOT NULL,
105
+ PRIMARY KEY (id)
106
+ );
107
+ INSERT INTO subscription_activations_new (id, execution_id, user_id, vendor, token_cipher, created_at, expires_at)
108
+ SELECT id, execution_id, user_id, vendor, token_cipher, created_at, expires_at FROM subscription_activations;
109
+ DROP TABLE subscription_activations;
110
+ ALTER TABLE subscription_activations_new RENAME TO subscription_activations;
111
+ CREATE UNIQUE INDEX idx_sub_activations_run
112
+ ON subscription_activations (execution_id, user_id, vendor);
113
+ CREATE INDEX idx_sub_activations_expiry
114
+ ON subscription_activations (expires_at);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/worker",
3
- "version": "0.80.1",
3
+ "version": "0.80.2",
4
4
  "description": "Reusable Cloudflare Worker library (Hono + D1) exposing the Agent Architecture Board core: the `createApp()` Hono factory, the default fetch/scheduled/queue handler, and the Durable Object + Workflow classes. Deployments (see deploy/backend) supply the wrangler.toml + config and re-export these.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -52,10 +52,10 @@
52
52
  "@cat-factory/integrations": "0.79.2",
53
53
  "@cat-factory/kernel": "0.115.1",
54
54
  "@cat-factory/observability-langfuse": "0.7.175",
55
- "@cat-factory/orchestration": "0.102.1",
55
+ "@cat-factory/orchestration": "0.102.2",
56
56
  "@cat-factory/prompt-fragments": "0.13.7",
57
57
  "@cat-factory/provider-cloudflare": "0.7.191",
58
- "@cat-factory/server": "0.106.1",
58
+ "@cat-factory/server": "0.106.2",
59
59
  "@cat-factory/spend": "0.12.1"
60
60
  },
61
61
  "devDependencies": {
@@ -64,7 +64,7 @@
64
64
  "typescript": "7.0.1-rc",
65
65
  "vitest": "^4.1.9",
66
66
  "wrangler": "^4.107.0",
67
- "@cat-factory/conformance": "0.10.76"
67
+ "@cat-factory/conformance": "0.10.77"
68
68
  },
69
69
  "scripts": {
70
70
  "build": "tsc -b tsconfig.build.json",