Skip to content

fix(schema): backfill schema.py to match migrations.py reality (#691) - #732

Closed
AndriiPasternak31 wants to merge 1 commit into
devfrom
AndriiPasternak31/claim-691
Closed

fix(schema): backfill schema.py to match migrations.py reality (#691)#732
AndriiPasternak31 wants to merge 1 commit into
devfrom
AndriiPasternak31/claim-691

Conversation

@AndriiPasternak31

Copy link
Copy Markdown
Contributor

Summary

Brings src/backend/db/schema.py into alignment with src/backend/db/migrations.py, restoring it as a faithful reference for the database (Architectural Invariant #3"All table DDL lives in schema.py"). /validate-schema flagged 11 tables and 14 columns that existed in every running database (created by migrations) but were missing from schema.py.

The change is mechanical and additive — every CREATE TABLE / ALTER TABLE / CREATE INDEX statement in this PR was copied byte-for-byte from migrations.py. No migration changes. No code changes. Existing databases unaffected — every new statement uses IF NOT EXISTS.

Closes #691

What's added to schema.py

11 tables (each with the canonical DDL from its source migration):

  • subscription_credentials (SUB-001) — declared before agent_ownership so the subscription_id FK target exists if FKs ever get turned on
  • agent_notifications (NOTIF-001)
  • subscription_rate_limit_events (SUB-003)
  • slack_workspaces, slack_channel_agents, slack_active_threads (SLACK-002)
  • telegram_bindings, telegram_chat_links, telegram_group_configs (TELEGRAM-001 / TGRAM-GROUP) — verified_email/verified_at and verified_by_email/verified_at rolled in from _migrate_access_control and _migrate_group_auth_mode
  • whatsapp_bindings, whatsapp_chat_links (WHATSAPP-001)

14 columns rolled into existing CREATE TABLE bodies:

  • agent_ownership: full_capabilities, max_backlog_depth, voice_system_prompt
  • schedule_executions: source_user_id, source_user_email, source_agent_name, source_mcp_key_id, source_mcp_key_name, claude_session_id, queued_at, backlog_metadata, fan_out_id
  • agent_schedules: webhook_token, webhook_enabled (feat: Webhook triggers for agent schedules (WEBHOOK-001) #291)

~22 indexes including the partials that were defined only in migrations:

  • idx_executions_queued (partial WHERE status = 'queued')
  • idx_executions_pending_retry (partial WHERE retry_scheduled_at IS NOT NULL AND status = 'pending_retry')
  • idx_executions_fan_out
  • idx_schedules_webhook_token (partial UNIQUE WHERE webhook_token IS NOT NULL)
  • idx_agent_sharing_proactive (partial WHERE allow_proactive = 1)
  • Plus table-local indexes for every new table

Why now

schema.py was a 70%-true reference — anyone reading it to learn the schema saw the wrong picture, and the architecture cross-reference to db/schema.py as canonical DDL was misleading. This PR closes that gap. It does not eliminate the two-source-of-truth pattern that lets drift recur — see "Follow-up" below.

Out of scope (intentional, per plan)

  • No changes to migrations.py — migrations are append-only history.
  • No code changes — routers/services already work against the live schema.
  • No architecture.md update — Invariant Feature/vector log retention #3 is already documented.

Follow-up

A CI gate that fails PRs adding a migration without updating schema.py was approved at the autoplan final gate as a separate issue. Filing alongside this PR so the prevention path doesn't slip.

Test plan

  • Plan's name-only diff script: missing tables: [], no missing cols, missing indexes: []
  • Plan's strict DDL parity script: 0 missing, 0 different
  • Migration ADD COLUMN cross-reference: every column added by a migration lives in schema.py
  • tests/unit/test_migrations.py: 17/17 pass
  • Smoke: backend boots against an existing ~/trinity-data/trinity.db (reviewer to verify; IF NOT EXISTS guarantees this is a no-op)

🤖 Generated with Claude Code


Migrated from #712 (head moved from fork to upstream as part of dropping the fork-based workflow). See #712 for original review thread.

Adds 11 tables, 14 columns, and ~22 indexes that existed only in
migrations.py to schema.py, restoring it as a faithful reference for
the database (Architectural Invariant #3).

Mechanical and additive. Migrations are append-only history. Existing
databases unaffected — every new statement uses IF NOT EXISTS.

Tables added: subscription_credentials, agent_notifications,
subscription_rate_limit_events, slack_workspaces, slack_channel_agents,
slack_active_threads, telegram_bindings, telegram_chat_links,
telegram_group_configs, whatsapp_bindings, whatsapp_chat_links.

Columns added: agent_ownership (full_capabilities, max_backlog_depth,
voice_system_prompt), schedule_executions (source_user_id,
source_user_email, source_agent_name, source_mcp_key_id,
source_mcp_key_name, claude_session_id, queued_at, backlog_metadata,
fan_out_id), agent_schedules (webhook_token, webhook_enabled).

Indexes added: subscription, notification, rate-limit, multi-agent
slack, telegram, whatsapp, plus partial indexes for execution backlog
(idx_executions_queued), retry (idx_executions_pending_retry),
fan-out (idx_executions_fan_out), webhook tokens
(idx_schedules_webhook_token), and proactive sharing
(idx_agent_sharing_proactive).

Verified: name-only and strict DDL parity scripts both pass with
zero missing and zero different entries. test_migrations.py 17/17.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AndriiPasternak31

Copy link
Copy Markdown
Contributor Author

Closing: this PR was opened to migrate #712 from fork to upstream, but #712 was already merged earlier today (commit d56012b). Branch AndriiPasternak31/claim-691 is already in dev via #712. No replacement needed.

@AndriiPasternak31
AndriiPasternak31 deleted the AndriiPasternak31/claim-691 branch May 8, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant