Database¶
FastReact uses PostgreSQL with a multi-tenant schema and Sqitch for migrations. Repositories use raw SQL (no ORM), so you always see exactly what runs.
Multi-tenant schema¶
All business data is scoped to an organization (the tenant boundary). Core entities:
user— individual accountsorganization— the tenant; all business data belongs to onerole—readonly,member,org_admin,sys_admin(see Authentication)session— server-side sessionsplan/organization_plan— subscription tiers and the org's current plan
This supports both individual users and teams without changing the data model. See Multi-Tenancy (B2B) for the organization/invitation model.
Connection config¶
Connection settings come from backend/.env (FS_DB_URL, FS_DB_SCHEMA) via backend/app/config/settings.py, and are injected through the DI container's db_config into every repository — so repositories never construct their own connections.
Migrations with Sqitch¶
Migrations are plain SQL files in backend/db/, versioned with Sqitch and reviewed alongside code in pull requests.
Create a migration:
This creates three files:
deploy/add_feature.sql— how to apply the changerevert/add_feature.sql— how to undo itverify/add_feature.sql— how to verify it worked
Deploy:
The sqitch.sh wrapper adds FastReact-specific safety: per-environment database URLs (dev/beta/gamma/prod/test), a check that every migration is wrapped in BEGIN;/COMMIT;, revert protection (requires --to), and .env loading per environment.
Why Sqitch and raw SQL?¶
Sqitch is language-agnostic and works with plain SQL — no ORM lock-in. You review and optimize the exact SQL that runs, and can still adopt SQLAlchemy or another tool later if your project needs it. See Architecture for the repository-layer reasoning.