Files
gridpilot.gg/docs/SCHEMA_STRATEGY.md
2025-12-29 00:24:56 +01:00

3.0 KiB

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:

  • 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():

  • 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, which configures TypeORM with:

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

In docker-compose.dev.yml, 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 and optional persistence override (commented) in .env.development.example.

Dev seeding behavior (high level)

Seeding/bootstrap runs at API startup via BootstrapModule, unless disabled with GRIDPILOT_API_BOOTSTRAP=0 (parsed by getEnableBootstrap()).

At startup:

This keeps dev environments usable without requiring manual seed steps, while avoiding unexpected reseeding in production.