What
Let Steward keep its own records (users, sessions, the Decionis workspace connection, signal sources, decisions, reviews, activities) on PostgreSQL, selected by STEWARD_DATABASE_URL=postgres://…. Plan: docs/Persistence.md, decisions P1 (TypeORM), P2 (all drivers shipped in the image) and workstream DB6.
The embedded database (SQLite) lands first and defines the portable schema and the migration style; this issue makes the same migrations and the same repositories pass on PostgreSQL.
Scope
- Add the driver
pg (MIT) as a production dependency; it must pass pnpm licenses:check.
- Wire the dialect in
infra/persistence/StewardDataSource.ts from the URL scheme, with TLS and pool options from URL parameters.
- Run every migration under
infra/persistence/migrations/ on PostgreSQL and fix any non-portable column type or index in the shared migration, never with dialect-specific SQL outside the dialect adapter.
- Run the persistence test suite against a PostgreSQL service container in CI: a nightly job (and on demand) rather than on every pull request.
- A section in
docs/Docker.md: the URL shape, a compose example, what the operator must provision, and the note that the database licence is the operator's.
- Ship the driver in the image and confirm the image starts against PostgreSQL (
docker run … -e STEWARD_DATABASE_URL=postgres://…).
- PostgreSQL is the default for any shared deployment: the compose file in
docs/Docker.md gains a postgres service and a volume, and the README's quickstart for live mode points at it.
Done when
- Migrations apply from empty and re-apply as a no-op on PostgreSQL;
STEWARD_DATABASE_MIGRATE=off with a pending migration refuses to serve.
- The persistence tests pass on PostgreSQL in the nightly matrix.
GET /api/health reports the dialect and the migration state.
- The Docker guide and
public/llms-full.txt name PostgreSQL as supported.
How to pick this up
- Comment on this issue so nobody else starts it, then branch from
master with one branch per issue; the bot opens the pull request when you push.
- Follow CONTRIBUTING.md:
pnpm verify green, every commit signed off with -s (DCO), no telemetry, no dependency outside the license policy in scripts/CheckLicensePolicy.mjs.
- Fixtures and samples follow the demo conventions: organisations from the NATO alphabet, people surnamed Example, references shaped
CRM-DEMO-000n, no real host, email, phone or URL. The tests enforce it.
- Update the documents that make a claim about what you changed in the same pull request: README, the Docker guide, ThreatModel, and the discovery files
public/llms*.txt (with pnpm discovery).
What
Let Steward keep its own records (users, sessions, the Decionis workspace connection, signal sources, decisions, reviews, activities) on PostgreSQL, selected by
STEWARD_DATABASE_URL=postgres://…. Plan: docs/Persistence.md, decisions P1 (TypeORM), P2 (all drivers shipped in the image) and workstream DB6.The embedded database (SQLite) lands first and defines the portable schema and the migration style; this issue makes the same migrations and the same repositories pass on PostgreSQL.
Scope
pg(MIT) as a production dependency; it must passpnpm licenses:check.infra/persistence/StewardDataSource.tsfrom the URL scheme, with TLS and pool options from URL parameters.infra/persistence/migrations/on PostgreSQL and fix any non-portable column type or index in the shared migration, never with dialect-specific SQL outside the dialect adapter.docs/Docker.md: the URL shape, a compose example, what the operator must provision, and the note that the database licence is the operator's.docker run … -e STEWARD_DATABASE_URL=postgres://…).docs/Docker.mdgains apostgresservice and a volume, and the README's quickstart for live mode points at it.Done when
STEWARD_DATABASE_MIGRATE=offwith a pending migration refuses to serve.GET /api/healthreports the dialect and the migration state.public/llms-full.txtname PostgreSQL as supported.How to pick this up
masterwith one branch per issue; the bot opens the pull request when you push.pnpm verifygreen, every commit signed off with-s(DCO), no telemetry, no dependency outside the license policy inscripts/CheckLicensePolicy.mjs.CRM-DEMO-000n, no real host, email, phone or URL. The tests enforce it.public/llms*.txt(withpnpm discovery).