Commit graph

6 commits

Author SHA1 Message Date
Chris Parsons
787b817fa7
Add PgBouncer connection pooling support for Vultr managed PostgreSQL (#271)
Disables prepared statements when PGBOUNCER=true (required for PgBouncer
transaction mode). Adds DATABASE_DIRECT_URL so migrations always use a
direct connection, bypassing the pool.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:15:18 -04:00
Claude
0f97ab258f
Fix migrate.mjs exiting with code 1 after successful migration
client.end() in the finally block was throwing (postgres driver already
cleaned up connections internally during migrate()), causing an unhandled
rejection and exit code 1 despite the migration succeeding.

- Use explicit process.exit(0)/exit(1) instead of relying on implicit exit
- Wrap both client.end() calls with .catch(() => {}) to tolerate cleanup errors
- Add onnotice: () => {} to suppress noisy NOTICE messages (schema/table
  already exists) that are normal on every idempotent re-run

https://claude.ai/code/session_01ReaqH3o9NVH4QU4qE9WMMQ
2026-04-06 04:24:04 +00:00
Chris Parsons
f1af4b5171
Decouple database migrations from server startup (#265)
* Use Docker Compose init service pattern for database migrations

Replaces the fragile double-migration approach (server.ts startup +
drizzle-kit CLI in CI) with a one-shot migrate service in Docker Compose
that the app depends on via condition: service_completed_successfully.

- Add scripts/migrate.mjs: programmatic drizzle-orm migration (uses
  production deps, not drizzle-kit which is devOnly and absent from image)
- Dockerfile: copy scripts/ into image, remove drizzle.config.ts (only
  needed by drizzle-kit CLI)
- server.ts: remove runMigrations() entirely; migrations are now handled
  by the migrate container before the app starts
- deploy.yml: remove explicit docker run migration step; replace sleep 10
  health check with a poll loop and explicit migrate exit-code check

Production server's docker-compose.yaml needs a one-time manual update
to add the migrate service — see plan for exact config.

https://claude.ai/code/session_01ReaqH3o9NVH4QU4qE9WMMQ

* Move drizzle-kit to devDependencies; use docker compose wait in deploy

drizzle-kit is a dev-only tool (schema generation and local migrations).
Now that production migrations run via the programmatic drizzle-orm API
in the migrate init container, drizzle-kit has no runtime role.

Also replaces the polling health check loop with docker compose wait,
which blocks until the migrate service exits and returns its exit code
cleanly — no sleep or manual status inspection needed.

https://claude.ai/code/session_01ReaqH3o9NVH4QU4qE9WMMQ

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-06 00:07:36 -04:00
Chris Parsons
61715b43d2
Load PROD_DATABASE_URL from .env automatically (#259)
Mirrors how DATABASE_URL is loaded, so users can store both in their
local .env instead of passing PROD_DATABASE_URL inline each time.

https://claude.ai/code/session_01EiYh5ZiuWAnpo1PND45Yi1

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-03 15:38:09 -07:00
Chris Parsons
139061e702
Add production database sync script with sanitization (#258)
* Add prod-to-dev database sync script

Adds scripts/sync-prod-db.sh and npm run db:sync-prod to safely copy
production data to the development database. After restoring, the script
nulls all Discord webhook URLs and anonymizes non-admin user PII (email,
name, avatar) to prevent notification leaks and reduce PII exposure on
developer machines. Admin accounts are preserved intact.

https://claude.ai/code/session_01EiYh5ZiuWAnpo1PND45Yi1

* Fix six code review issues in sync-prod-db.sh

- Add upfront check for pg_dump/pg_restore/psql availability (#5)
- Fix password masking to use sed instead of broken bash glob (#6)
- Replace DROP/CREATE DATABASE with pg_restore --clean --if-exists,
  which works on managed cloud databases without superuser access (#2)
- Remove dead ADMIN_DB assignment that was immediately overwritten (#3)
- Handle pg_restore exit code 1 (non-fatal warnings) gracefully
  instead of aborting via set -e (#1)
- Count webhook URLs before the UPDATE for an accurate cleared count (#4)

https://claude.ai/code/session_01EiYh5ZiuWAnpo1PND45Yi1

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-03 15:17:58 -07:00
Chris Parsons
2bad3dd75e refactor: migrate server code from JavaScript to TypeScript with build pipeline 2025-10-18 22:16:04 -07:00