Skip to content

Commit 7b7979d

Browse files
lexwhitingclaude
andcommitted
fix(db): hotfix prod schema drift — add is_premium, premium_price_cents, listed_in_marketplace
Production was returning 500s on /api/tools, /marketplace/trending, /api/v1/discover, and /api/templates/* routes with errors like 'column "is_premium" of relation "tools" does not exist' and 'column "listed_in_marketplace" does not exist'. Root cause: 1. is_premium + premium_price_cents were added to schema.ts (lines 124-125) without a corresponding migration ever being generated. Three API routes referenced the columns but no .sql migration added them. 2. Migration 0001_listed_in_marketplace.sql was generated and recorded in meta/_journal.json but never applied to prod — Vercel does not auto-run drizzle migrations on deploy and no manual `drizzle-kit migrate` was ever run against prod DATABASE_URL. Hotfix applied to prod via psql (idempotent ADD COLUMN IF NOT EXISTS) on 2026-04-29: - tools.listed_in_marketplace boolean NOT NULL DEFAULT true - tools.is_premium boolean NOT NULL DEFAULT false - tools.premium_price_cents integer - UPDATE tools SET listed_in_marketplace = false WHERE status = 'draft' (1 row affected; 1,460 total rows in table) Post-hotfix verification: - /api/tools: 500 → 401 (auth-gated, reaches gate without DB error) - /marketplace/trending: 500 → 200 - /api/v1/discover: 500 → 200 - /sitemap.xml: 200 (was sometimes 500 with ENOENT — separate P3) This file 0008_premium_template_columns.sql is the source-of-truth record. Idempotent ADD COLUMN IF NOT EXISTS makes it safe to re-run through drizzle-kit migrate on a fresh environment. Out of scope (separate triage card needed): - drizzle.__drizzle_migrations table is empty in prod — Drizzle has zero record of any migration applied even though base schema is provisioned. Reconciling the journal with prod state requires auditing what's actually in the prod DB vs what the migration files would create. - Migrations 0002-0007 (mcp_shadow_index, ledger_*, processed_ webhook_events, chargeback_alerts) exist as files but have not been applied to prod and are not in meta/_journal.json. Apply selectively after auditing each one — some create new tables that may already exist in some other form. Refs: P0-prod-schema-drift, blocks PR #3 merge Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 70aa130 commit 7b7979d

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- 0008 — Premium template columns + listed_in_marketplace catch-up
2+
--
3+
-- Two schema-drift fixes hand-applied to prod on 2026-04-29 after
4+
-- /api/tools, /marketplace/trending, /api/v1/discover, and the
5+
-- premium-template purchase flow began returning 500s with
6+
-- "column ... does not exist" errors. This file is the source-of-
7+
-- truth record of what was applied; prod was patched in-place via
8+
-- idempotent ALTER TABLE statements (`ADD COLUMN IF NOT EXISTS`),
9+
-- so re-running this migration through drizzle-kit on a fresh
10+
-- environment will produce the same end state.
11+
--
12+
-- Why this migration exists:
13+
-- 1. `is_premium` and `premium_price_cents` were added to
14+
-- `apps/web/src/lib/db/schema.ts` (lines 124-125) without a
15+
-- corresponding migration ever being generated. The schema
16+
-- declared them, three API routes referenced them
17+
-- (`api/templates/purchase`, `api/templates/[slug]/download`,
18+
-- and `api/tools/quick-publish` via the schema's INSERT
19+
-- column list), but no .sql file in this directory ever
20+
-- added the columns. Prod went without them since they were
21+
-- introduced.
22+
-- 2. Migration `0001_listed_in_marketplace.sql` was generated
23+
-- and recorded in `meta/_journal.json`, but never applied
24+
-- to the prod database — Vercel does not auto-run drizzle
25+
-- migrations on deploy, and no manual `drizzle-kit migrate`
26+
-- step was run against the prod DATABASE_URL after 0001 was
27+
-- authored. This file folds the same column add into 0008
28+
-- with `IF NOT EXISTS` so a future fresh-environment apply
29+
-- produces a coherent end state regardless of whether 0001
30+
-- already ran.
31+
--
32+
-- Known broader drift (out of scope for this migration, see follow-
33+
-- up triage card): `drizzle.__drizzle_migrations` in prod is empty
34+
-- — Drizzle has no record of any migration applied even though
35+
-- the base schema was provisioned somehow. Migrations 0002-0007
36+
-- exist as files in this directory but have not been applied to
37+
-- prod. This file does NOT attempt to reconcile those.
38+
39+
ALTER TABLE "tools" ADD COLUMN IF NOT EXISTS "is_premium" boolean DEFAULT false NOT NULL;
40+
--> statement-breakpoint
41+
ALTER TABLE "tools" ADD COLUMN IF NOT EXISTS "premium_price_cents" integer;
42+
--> statement-breakpoint
43+
ALTER TABLE "tools" ADD COLUMN IF NOT EXISTS "listed_in_marketplace" boolean DEFAULT true NOT NULL;
44+
--> statement-breakpoint
45+
UPDATE "tools" SET "listed_in_marketplace" = false WHERE "status" = 'draft' AND "listed_in_marketplace" = true;

apps/web/drizzle/meta/_journal.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
"when": 1776513600000,
1616
"tag": "0001_listed_in_marketplace",
1717
"breakpoints": true
18+
},
19+
{
20+
"idx": 8,
21+
"version": "7",
22+
"when": 1777737600000,
23+
"tag": "0008_premium_template_columns",
24+
"breakpoints": true
1825
}
1926
]
2027
}

0 commit comments

Comments
 (0)