1d4300d505
Deploy to route.crispygoat.com / deploy (push) Failing after 1m12s
The "Run migrations" job (and thus the whole deploy) was failing on every push after the first successful bootstrap with: ✗ 0001_init.sql failed: relation "admin_users" already exists Root causes: - 0001_init.sql used plain CREATE TABLE/INDEX/TRIGGER despite the header comment claiming "CREATE TABLE IF NOT EXISTS". - The _migrations tracking row for 0001_init.sql was never recorded on the prod DATABASE_URL (tracking logic landed after initial apply, or apply happened outside the runner). Fix (3 layers of defense): * db/migrations/0001_init.sql: every CREATE TABLE now uses IF NOT EXISTS (63 tables), CREATE INDEX uses IF NOT EXISTS (49), all CREATE TRIGGER wrapped in safe DO $$ IF NOT EXISTS (pg_trigger join check) THEN ... END IF; $$, removed the file's own BEGIN/COMMIT so the runner's transaction is authoritative. RLS drop+create and CREATE OR REPLACE FUNCTION were already safe. * scripts/migrate.js: added ensureTracked() right after loading the applied set. For 0001/0002, if the core objects (admin_users table, password_hash column) already exist in information_schema but the tracking row is absent, INSERT the filename (ON CONFLICT DO NOTHING) and log "repaired tracking". Then the normal skip path handles it. * .gitea/workflows/deploy.yml: added an inline node -e pre-repair (same admin_users existence check → force _migrations row) immediately before `npm run migrate:one`. This protects even on an older checkout of the runner. The neon_auth preflight and post-apply "admin_users must exist" hard gate are untouched. * Minor: cleaned 0002_admin_password.sql tx wrapper for consistency; updated MEMORY.md with the incident + resolution. Result: deploys (and any server-side `node scripts/migrate.js` recovery runs) on an already-initialized prod DB will repair/skip 0001 cleanly, pass the verification query, and continue to build/deploy. The scp of scripts/ + db/migrations/ in the Deploy step now carries the fixed versions. See the plan note in deploy.yml and MEMORY.md for background.
21 lines
841 B
SQL
21 lines
841 B
SQL
-- 0002_admin_password.sql
|
|
--
|
|
-- Adds a `password_hash` column to `users` so the Auth.js Credentials
|
|
-- provider can verify email + password against the database.
|
|
--
|
|
-- Idempotent: uses `ADD COLUMN IF NOT EXISTS`. The column is nullable
|
|
-- because OAuth-only users (Google) never set a password.
|
|
--
|
|
-- The Credentials provider's `authorize` function is documented in
|
|
-- `src/lib/auth.ts` — it queries this column and runs `verifyPassword`
|
|
-- (see `src/lib/passwords.ts`) before returning the user.
|
|
|
|
-- Transaction is managed by the migrate runner (scripts/migrate.js).
|
|
-- File kept small and re-runnable via IF NOT EXISTS on the ALTER.
|
|
|
|
ALTER TABLE users
|
|
ADD COLUMN IF NOT EXISTS password_hash TEXT;
|
|
|
|
-- Update the updated_at trigger tracking — no new triggers needed since
|
|
-- `users` already has `set_updated_at` from migration 0001.
|