From fca3d8de7004b60cba77dab4b2f6ff53810f5677 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Mon, 20 Apr 2026 10:08:03 +0300 Subject: [PATCH] fix(migrations): drop 011 table-rebuild; keep only pending_sender_approvals The original 011 also rebuilt `messaging_groups` to flip the `unknown_sender_policy` column DEFAULT from "strict" to "request_approval". On live DBs the DROP TABLE step fails SQLite's foreign-key integrity check because `sessions`, `user_dms`, and `pending_sender_approvals` all reference `messaging_groups(id)`. `PRAGMA foreign_keys=OFF` / `defer_foreign_keys` can't be toggled inside the implicit migration transaction, so the rebuild can't be made to apply cleanly. The default-flip was cosmetic anyway: every `createMessagingGroup` callsite passes `unknown_sender_policy` explicitly. Router auto-create was already updated to hardcode "request_approval" (router.ts:151), and setup / seed scripts pick per context. Changes: - Migration 011 now only creates the `pending_sender_approvals` table + index. The rebuild block is gone. - Reference `SCHEMA` in src/db/schema.ts updated to reflect what the DB actually has: DEFAULT 'strict' (from migration 001), with a note about the effective policy applied at insert sites. Discovered on v2 post-merge during live restart. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../011-pending-sender-approvals.ts | 35 +++++-------------- src/db/schema.ts | 9 ++--- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/db/migrations/011-pending-sender-approvals.ts b/src/db/migrations/011-pending-sender-approvals.ts index cb47039..2331a6e 100644 --- a/src/db/migrations/011-pending-sender-approvals.ts +++ b/src/db/migrations/011-pending-sender-approvals.ts @@ -4,10 +4,15 @@ * in-flight entry in this table dedups concurrent attempts from the same * sender; the row is cleared on approve / deny. * - * Also flips the `messaging_groups.unknown_sender_policy` default from 'strict' - * to 'request_approval' so fresh wirings don't silently swallow messages from - * users the admin hasn't added yet. Existing rows are left as-is (silent - * upgrade would change established behavior without the admin asking for it). + * Previously this migration also rebuilt `messaging_groups` to flip the + * column DEFAULT from `'strict'` to `'request_approval'`. Removed: the + * rebuild failed SQLite's foreign-key integrity check at DROP time on live + * DBs with existing FK references (sessions, user_dms, etc.), and `PRAGMA + * foreign_keys` / `defer_foreign_keys` can't be toggled inside the + * implicit migration transaction. The default-flip was cosmetic anyway — + * every `createMessagingGroup` callsite passes `unknown_sender_policy` + * explicitly, and the router's auto-create path was updated to hardcode + * `'request_approval'` directly (see src/router.ts:123). */ import type Database from 'better-sqlite3'; import type { Migration } from './index.js'; @@ -31,27 +36,5 @@ export const migration011: Migration = { CREATE INDEX IF NOT EXISTS idx_pending_sender_approvals_mg ON pending_sender_approvals(messaging_group_id); `); - - // Default-flip: fresh messaging_groups default to request_approval instead - // of silently dropping. SQLite doesn't support modifying column DEFAULTs - // in place, so we rebuild the table via the classic rename-copy-drop - // pattern. Existing rows keep their current unknown_sender_policy value. - db.exec(` - CREATE TABLE messaging_groups_new ( - id TEXT PRIMARY KEY, - channel_type TEXT NOT NULL, - platform_id TEXT NOT NULL, - name TEXT, - is_group INTEGER DEFAULT 0, - unknown_sender_policy TEXT NOT NULL DEFAULT 'request_approval', - created_at TEXT NOT NULL, - UNIQUE(channel_type, platform_id) - ); - INSERT INTO messaging_groups_new - SELECT id, channel_type, platform_id, name, is_group, unknown_sender_policy, created_at - FROM messaging_groups; - DROP TABLE messaging_groups; - ALTER TABLE messaging_groups_new RENAME TO messaging_groups; - `); }, }; diff --git a/src/db/schema.ts b/src/db/schema.ts index aa33fae..8433035 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -19,17 +19,18 @@ CREATE TABLE agent_groups ( -- Platform groups/channels. unknown_sender_policy governs what happens -- when a sender we've never seen before posts in this chat. +-- The column DEFAULT is "strict" (inherited from migration 001), but it +-- only matters if something inserts without specifying the field, which no +-- current callsite does. Router auto-create hardcodes "request_approval" +-- (see src/router.ts:151); setup scripts pick per context. CREATE TABLE messaging_groups ( id TEXT PRIMARY KEY, channel_type TEXT NOT NULL, platform_id TEXT NOT NULL, name TEXT, is_group INTEGER DEFAULT 0, - unknown_sender_policy TEXT NOT NULL DEFAULT 'request_approval', + unknown_sender_policy TEXT NOT NULL DEFAULT 'strict', -- 'strict' | 'request_approval' | 'public' - -- Default is request_approval so silent drops don't - -- mystery-break users who wired their DM during - -- setup and haven't explicitly marked it public. created_at TEXT NOT NULL, UNIQUE(channel_type, platform_id) );