For Developers
Operations
Environments & secrets
- Local envs live in
/environments/.env.<env>(not committed). Root scripts copy into.envfor 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/schema) - 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_URLandVITE_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 touserstable records via email - Permissions stored in DB (
userPermissionsenum), 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)