From 1cd387c59f8d783ff11deada5d6e526657135e8d Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Mon, 12 Oct 2026 23:17:06 -0400 Subject: [PATCH] Create scheduled_messages for databases that never had it No committed migration creates the table: migrations 6-10 were generated outside the repository, so fresh databases fail once anything alters it. The new migration is CREATE TABLE IF NOT EXISTS, a no-op where the table already exists. Aerich cannot generate it because its saved state already includes the table; the DDL is Tortoise's schema output for the model. Co-Authored-By: Claude Opus 5.5 --- ...6_20260603000000_add_scheduled_messages.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 migrations/models/6_20260603000000_add_scheduled_messages.py diff --git a/migrations/models/6_20260603000000_add_scheduled_messages.py b/migrations/models/6_20260603000000_add_scheduled_messages.py new file mode 100644 index 0000000..6014506 --- /dev/null +++ b/migrations/models/6_20260603000000_add_scheduled_messages.py @@ -0,0 +1,38 @@ +"""Create scheduled_messages, which no committed migration ever created. + +Migrations 6–10 were generated outside the repository and never committed, and +one of them created this table. Deployments that ran them already have it, so +this is IF NOT EXISTS and a no-op there; fresh databases need it before +migration 20 alters the table. Aerich cannot generate this file because its +saved model state already includes the table: the DDL below is Tortoise's +schema output for the model as of migration 19. +""" + +from tortoise import BaseDBAsyncClient + +RUN_IN_TRANSACTION = True + + +async def upgrade(db: BaseDBAsyncClient) -> str: + return """ + CREATE TABLE IF NOT EXISTS "scheduled_messages" ( + "id" UUID NOT NULL PRIMARY KEY, + "recipient" VARCHAR(255) NOT NULL, + "channel" VARCHAR(20) NOT NULL, + "content" TEXT NOT NULL, + "subject" VARCHAR(255), + "scheduled_at" TIMESTAMPTZ NOT NULL, + "status" VARCHAR(20) NOT NULL DEFAULT 'pending', + "recurrence" VARCHAR(20) NOT NULL DEFAULT 'none', + "use_agent" BOOL NOT NULL DEFAULT False, + "error_message" TEXT, + "created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + "created_by_id" UUID NOT NULL REFERENCES "users" ("id") ON DELETE CASCADE +);""" + + +async def downgrade(db: BaseDBAsyncClient) -> str: + # Existing deployments created this table in an uncommitted migration; + # never drop it from under them. + return ""