Logo

Sharing Excess

Food Rescue Platform
For Developers

Operations

Environments & secrets

  • Local envs live in /environments/.env.<env> (not committed). Root scripts copy into .env for dev and db pushes
  • Railway manages per-service env vars for staging and production
  • Never store secrets in the repo; rotate regularly in Railway and 1Password

Database (Neon PostgreSQL)

  • Branching model: main (prod), staging (test), plus per-developer branches
  • Drizzle schema is the source of truth (packages/db/src/db.schema.ts)
  • Push schema updates with root scripts:
    • bun run db_push:development | staging | production
  • Test DB URLs (TEST_DATABASE_URL) should never point to production

File & object storage (S3)

  • Paths stored in DB; environment base URL provided via STORAGE_BASE_URL and VITE_STORAGE_BASE_URL
  • S3 buckets hosted and configured by Railway
  • Partner and user images have "public" permissions; backup files have "private" permissions
  • Daily backups written to pg-backups/ in private S3 storage (no encryption needed)
  • Cleanup cron deletes backups older than 1 year

Authentication & authorization (Clerk)

  • Client uses @clerk/clerk-react
  • Server validates with @clerk/backend; maps to users table records via email
  • Permissions stored in DB (userPermissions enum), enforced per-route

Observability

  • Sentry DSNs per service: SENTRY_DSN_API, SENTRY_DSN_CRON_BACKUP, SENTRY_DSN_CRON_CLEANUP
  • API metrics via apitally (configured in server dependencies)

Backups & restore

  • Primary: Neon point-in-time restore (console). Create a branch before restore to preserve state for analysis
  • Secondary: S3 backups (private, unencrypted). Download latest set under pg-backups/ and restore to a Neon branch

Scripts (/scripts)

  • User and DB reconciliation utilities (Clerk and DB sync, cleanup of orphans)
  • Run with Bun (bun run tsx <script> or adapt as needed)