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
andVITE_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 tousers
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)