feat: Sprint 1 remainder — Postgres store, Docker client, warm pool, sessions route
Mirror to GitHub / mirror (push) Canceled after 0s
Mirror to GitHub / mirror (push) Canceled after 0s
- PostgresUserStore (Queryable) + migration + env-gated wiring - DockerodeClient behind injected DockerEngine - ImageManager, WarmPool, Dockerfile.wordpress, docker-compose - POST /sessions spins up sandbox (503 when unconfigured) - ADRs 0014-0015; 68 unit tests green
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# 14. Postgres user store via a Queryable boundary; schema in SQL migrations
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-08-15
|
||||
|
||||
## Context
|
||||
|
||||
ADR 0012 deferred Postgres behind the `UserStore` interface. Sprint 1 now ships the real implementation. Postgres is not available in the dev environment, so the store had to be testable without a database.
|
||||
|
||||
## Decision
|
||||
|
||||
`PostgresUserStore` uses `node-postgres` (`pg`) but depends on a minimal `Queryable` interface (`query(text, values)`) instead of `pg.Pool` directly. `UserStore` methods became async. The `users` table lives in `api/migrations/001_init.sql`. `index.ts` selects Postgres when `DATABASE_URL` is set, else the in-memory store.
|
||||
|
||||
### Options considered
|
||||
|
||||
- ORM (Prisma/Drizzle) with migrations.
|
||||
- Raw `pg` behind a `Queryable` interface (chosen).
|
||||
|
||||
### Rejected
|
||||
|
||||
- ORM — adds tooling and a codegen step for a two-statement surface; the raw SQL is reviewable and the interface keeps tests database-free.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `InMemoryUserStore` and `PostgresUserStore` share the same async `UserStore` contract; swapping is env-driven.
|
||||
- Auth data is durable when `DATABASE_URL` is configured; the migration must be applied before first use.
|
||||
@@ -0,0 +1,27 @@
|
||||
# 15. Docker daemon client via dockerode behind an injected engine; sandbox gated by env
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-08-15
|
||||
|
||||
## Context
|
||||
|
||||
ADR 0013 deferred the real Docker client. Sprint 1 now ships it. There is still no Docker daemon in the dev environment, so the client had to be testable without one.
|
||||
|
||||
## Decision
|
||||
|
||||
`DockerodeClient` implements `DockerClient` using `dockerode`, but depends on an injected `DockerEngine` (a minimal `createContainer`/`getContainer` surface) instead of `dockerode` directly. The API enables it via `WUR_ENABLE_SANDBOX=1`; when off, `POST /sessions` returns 503. `index.ts` constructs `new Docker()` (dockerode auto-detects `DOCKER_HOST` or the unix socket).
|
||||
|
||||
### Options considered
|
||||
|
||||
- Raw Docker Engine HTTP over the unix socket.
|
||||
- dockerode behind an injected engine (chosen).
|
||||
|
||||
### Rejected
|
||||
|
||||
- Raw HTTP — dockerode already handles unix sockets, TLS, and API version negotiation; reimplementing it is pure waste.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `DockerodeClient` is unit-tested with a fake engine; only the daemon wiring remains to be verified on a Docker host.
|
||||
- Sandbox spin-up is opt-in, so local dev without Docker still boots and `auth`/`sessions` behave predictably (503 on sessions).
|
||||
- Port mapping is a Sprint 1 placeholder (single fixed host port); dynamic port allocation and preview proxying are follow-ups.
|
||||
@@ -27,6 +27,8 @@ Each ADR is a single file following the [Nygard format](https://cognitect.com/bl
|
||||
| [0011](0011-fastify-react-stack.md) | Fastify is the API server; React + Vite is the web shell | Accepted |
|
||||
| [0012](0012-in-memory-user-store.md) | In-memory user store behind a UserStore interface; Postgres deferred | Accepted |
|
||||
| [0013](0013-docker-boundary-mock.md) | Sandbox orchestration mocks the Docker boundary; real daemon client deferred | Accepted |
|
||||
| [0014](0014-postgres-queryable.md) | Postgres user store via a Queryable boundary; schema in SQL migrations | Accepted |
|
||||
| [0015](0015-dockerode-engine-gating.md) | Docker daemon client via dockerode behind an injected engine; sandbox gated by env | Accepted |
|
||||
|
||||
## How to add one
|
||||
|
||||
|
||||
Reference in New Issue
Block a user