Repository navigation
feat(everything-dev): PGlite is the only local database — retire docker-compose (ADR 0038) - #676
Open
elliotBraem wants to merge 4 commits into
Open
elliotBraem wants to merge 4 commits into
elliotBraem wants to merge 4 commits into
Conversation
…er-compose (ADR 0038) The zero-config dev default is now a persistent, file-backed PGlite data dir (pglite:.bos/db, per workspace process). docker-compose is retired entirely: root + scaffold template + CLI auto-start + child scripts + CI service containers + deploy-smoke host Postgres. bos dev migrates leftover compose-era state once (.env URL rewrites, scaffold compose relocated to .bos/compose-retired). db:* commands select the drizzle-kit pglite dialect by URL scheme; the driver mkdirs the data dir recursively (pglite only creates the leaf). Tests run on in-memory pglite; TEST_DATABASE=postgres + an external URL remains the parity escape hatch. Production postgres:// URLs unchanged.
…eam + stale-guard cleanup (ADR 0038) With in-memory pglite the stack database lives in its own process, so the direct-DB regression fixtures could never reach it and several tests still assumed the compose era. This lands the follow-ups that make CI green: - HTTP seeding (tests/regression/lib/http-seed.mjs): sessions minted via sign-in/anonymous, orgs created via Better Auth routes, approvals and role grants through the admin routes with a boot-time bootstrap admin API key; cookie snaps keep the same .bos/regression/*.json artifacts - bootstrap-admin seam (plugins/auth): when AUTH_BOOTSTRAP_ADMIN_API_KEY is set, the auth plugin ensures a platform admin + real API key row (hashed like @better-auth/api-key's default hasher, key must be ≥64 chars) at boot; dev/test-only, loud WARN, declared in bos.app.ts + plugin.dev.ts so stack env reaches the plugin - AdminUsersService.setRole: API-key callers update the DB directly — better-auth admin endpoints re-read the server session store and null the api-key hook's hydration, so they can never authorize an API-key caller; the typed requireAdmin guard already checked the role - start-container.mjs: skip non-postgres URLs in the DB probe (mirrors start-stack.mjs), fixing "test database never became reachable: " in the start-mode stacks - init.compose.test.ts rewritten as a negative guard (init never emits docker-compose.yml); compose assertions stripped from init.relative-directory.test.ts and the .env.example wording updated - stale docs: CONTRIBUTING.md docker step + bun→pnpm commands, host/.env.example compose-era postgres URL, docs/agents/testing.md fixture guidance, framework env.go comment, ADR 0038 addendum - dead code: docker COMMAND_TIMEOUTS entry, "generate env/docker" label Verified locally: typecheck (12), lint (0 errors), framework tests (1695), Go HTTP regression dev suite (full pass incl. TestSeedRegressionData), regression lib node tests, and a live dev:ssr stack seeded end-to-end through the new HTTP path.
…v boots; HTTP-ify onboard-rescan spec - onboard-rescan.spec.ts is now pure HTTP (ADR 0038): organizer + joiner sessions via anonymous sign-in helpers from http-seed.mjs, org approval through reviewOrganization (bootstrap key), and the "member removed but stale active-org" state produced by the organizer removing the joiner (removeMember leaves the removed user's session intact). Fixes the start:ssr shard crash from the deleted auth-test-instance.ts import. - concurrent bos dev sessions in one config dir no longer fail artifact generation: writeResolvedConfig now writes .bos/bos.resolved-config.json atomically (tmp + rename) so a sibling session can't read a torn file (a torn read resolved plugins without localPath and made the stale sweep delete another boot's fresh gen files), and the sweep's rmSync gains force:true so a file vanishing between existsSync and the removal cannot crash the boot with "ENOENT … lstat". - codegen under concurrency pinned by a unit test running two real syncApiContractBridge syncs plus a resolved-config write in parallel against one temp config dir, plus the stale-sweep removal guard. Verified: onboard-rescan spec green twice against a live dev:ssr stack, framework Go suite (BOS_TEARDOWN_ADOPTION=1, 2 stack slots) green, framework vitest suite green (1697), typecheck + lint clean.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every scaffolded app ships a
docker-compose.ymlwith hardcoded host ports 5432–5435, so concurrent local projects collide (Bind for 0.0.0.0:5433 failed: port is already allocated— observed between two local apps). The zero-config default was ephemeral pglite (pglite:.bos/<slug>/:memory:— data lost every restart), which is why operators opted into compose Postgres just to persist data.Decision (ADR 0038, grill-confirmed)
Delete compose entirely; make local persistence a file-backed PGlite data dir.
pglite:.bos/dbper workspace process (api/.bos/db,plugins/<id>/.bos/db…). No ports, no docker — cross-project collision is structurally impossible. Data survives restarts.plugin_<slug>schema isolation (the same-URL fallback now yields shared data instead of disjoint in-memory islands). Multi-instance access per data dir verified for pglite 0.4.6 — same-process and cross-process (sodb:*while dev runs works).bos devonce rewrites compose-erapostgres://everythingdev:…@localhost:{5432–5435}/…URLs in.env(dev →pglite:.bos/db, test →pglite::memory:; drift ports matched by database name) and relocates a scaffold-shapeddocker-compose.ymlto.bos/compose-retired/. Operator-authored URLs/compose files untouched.db:*on pglite:drizzleCredentialsFor(url)selects the drizzle-kit pglite dialect by URL scheme (all six workspacedrizzle.config.ts);pnpm run init(=db:migrate) works zero-config;resolveDatabaseUrlfalls back to the persistent default. Driver mkdirs the data dir recursively (PGlite only creates the leaf — boot-time ENOENT bug fixed)..env.testcarries only the test secret + in-memory URLs; regression_env's dev-data guard now refusespglite:.bos/dband legacy dev postgres URLs; the four CI regression jobs run zero-config pglite (service containers removed); the deploy smoke boots the image on in-container pglite (host Postgres +host.docker.internaldependency gone).TEST_DATABASE=postgres+ an explicit external URL (pglite/pg savepoint semantics diverge — plan 008). No committed compose anywhere.Production unchanged:
postgres://URLs, Neon/Railway (ADR 0035).Verification
pnpm run typecheck(14 packages) andpnpm run lintgreen; oxlint warnings at HEAD baseline (36).APP READYwith zero docker;api/.bos/db,plugins/auth/.bos/db, per-plugin dirs created; plugin dists confirmed carrying the new defaults.Notes for children
Children receive this via
bos upgrade(changeset: minor oneverything-dev). Stale compose-era.envURLs self-migrate on the nextbos devin each repo; olddocker-compose.ymlfiles are moved aside, not deleted.TEST_DATABASE=postgresremains available against any external postgres.Tickets + outcomes:
.scratch/pglite-only-local-db/(local issue-tracker convention, gitignored).