racing typeorm
This commit is contained in:
50
docs/SCHEMA_STRATEGY.md
Normal file
50
docs/SCHEMA_STRATEGY.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Schema strategy (dev) and persistence switching
|
||||
## Goal
|
||||
Keep the core domain independent from persistence details, while still providing a fast dev loop. Persistence and schema behavior are configured at the application boundary (the API app), not inside the domain.
|
||||
|
||||
## Persistence modes (API runtime)
|
||||
The API supports two persistence modes, controlled by [`ProcessEnv.GRIDPILOT_API_PERSISTENCE`](apps/api/src/env.d.ts:7):
|
||||
|
||||
- **`inmemory`**: no database required; the API runs with in-memory adapters.
|
||||
- **`postgres`**: the API uses Postgres via TypeORM.
|
||||
|
||||
### Default inference (dev ergonomics)
|
||||
If `GRIDPILOT_API_PERSISTENCE` is **unset**, the API infers persistence from `DATABASE_URL` via [`getApiPersistence()`](apps/api/src/env.ts:33):
|
||||
|
||||
- If `DATABASE_URL` is set → `postgres`
|
||||
- Otherwise → `inmemory`
|
||||
|
||||
This is why dev compose should not hard-code `GRIDPILOT_API_PERSISTENCE`; it should allow inference unless explicitly overridden.
|
||||
|
||||
## Schema strategy in development (TypeORM `synchronize`)
|
||||
When the API runs in Postgres mode, it loads [`DatabaseModule`](apps/api/src/domain/database/DatabaseModule.ts:1), which configures TypeORM with:
|
||||
|
||||
- `synchronize: process.env.NODE_ENV !== 'production'` in [`TypeOrmModule.forRoot()`](apps/api/src/domain/database/DatabaseModule.ts:6)
|
||||
|
||||
Practical meaning:
|
||||
- **Development/test:** TypeORM `synchronize` is enabled to keep schema aligned automatically during iteration.
|
||||
- **Production:** TypeORM `synchronize` is disabled.
|
||||
|
||||
### Migrations (deferred)
|
||||
Migrations are intentionally deferred for now: local dev relies on `synchronize` for speed, while production-grade migrations will be introduced later at the infrastructure boundary (without changing the domain).
|
||||
|
||||
## Switching modes locally
|
||||
### Docker dev (recommended)
|
||||
In [`docker-compose.dev.yml`](docker-compose.dev.yml:1), `GRIDPILOT_API_PERSISTENCE` should be optional so the default inference works.
|
||||
|
||||
To force a mode, set one of:
|
||||
- `GRIDPILOT_API_PERSISTENCE=inmemory`
|
||||
- `GRIDPILOT_API_PERSISTENCE=postgres`
|
||||
|
||||
Example environment reference (dev): [`DATABASE_URL`](.env.development.example:20) and optional persistence override (commented) in [`.env.development.example`](.env.development.example:17).
|
||||
|
||||
## Dev seeding behavior (high level)
|
||||
Seeding/bootstrap runs at API startup via [`BootstrapModule`](apps/api/src/domain/bootstrap/BootstrapModule.ts:1), unless disabled with `GRIDPILOT_API_BOOTSTRAP=0` (parsed by [`getEnableBootstrap()`](apps/api/src/env.ts:49)).
|
||||
|
||||
At startup:
|
||||
- Always runs `EnsureInitialData.execute()` in [`BootstrapModule.onModuleInit()`](apps/api/src/domain/bootstrap/BootstrapModule.ts:21).
|
||||
- Seeds racing data via `SeedRacingData` when:
|
||||
- persistence is `inmemory`, or
|
||||
- persistence is `postgres` AND `NODE_ENV !== 'production'` AND the racing DB appears empty (checked via the league repository) in [`BootstrapModule.shouldSeedRacingData()`](apps/api/src/domain/bootstrap/BootstrapModule.ts:42).
|
||||
|
||||
This keeps dev environments usable without requiring manual seed steps, while avoiding unexpected reseeding in production.
|
||||
Reference in New Issue
Block a user