Six phases claimed the product runs on SQLite and on Postgres. Nothing
had ever run it on Postgres. TEST_DATABASE_URL now points the whole
suite at a real server and CI runs both arms.
The first run found a bug that would have shipped. better-auth's banned
flag is integer 0/1 on SQLite and a real boolean on Postgres, and the
code read it as `banned === 1`, so on Postgres an account someone asked
us to freeze went on receiving email. Both of those flags are now typed
for either dialect and read through isFlagSet.
It also found the migration advisory lock being taken on a pool. An
advisory lock belongs to the session that took it, so a lock on one
pooled connection and an unlock on another leaves it held. Two replicas
migrating at once is the ordinary case in k8s and is precisely what it
was there to protect.
New for the scaled mode: k8s manifests with migrations as an
initContainer, one poller in its own worker Deployment rather than one
per API replica, and an Ingress that exposes the web app only. The
storage drivers finally have tests, S3 included, since scaled mode
requires it and it had never been exercised.
Two acceptance tests, both checked against a deliberately broken build
first: two workers claiming a hundred jobs report 188 claims with SKIP
LOCKED removed, and the in-flight request is cut off with the drain wait
removed.
340 tests on SQLite, 341 on Postgres, 70 Playwright, rules coverage 100%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Monorepo (pnpm workspaces) with two deployable apps and three pure packages.
apps/api (Hono on Node): Zod validated env that fails fast and names the problem,
Kysely factories for SQLite and Postgres chosen by DATABASE_URL scheme, portable
migrations covering the whole SPEC section 5 schema, Better Auth with the four
roles and seeded demo accounts, localized error envelope, /healthz and /readyz,
graceful SIGTERM drain. Dialect specific SQL is confined to the two factories.
apps/web (Next.js App Router): locale routed shell in es and en with a language
switcher, sign in screen, and a runtime /api proxy so the browser only ever sees
one origin and cookies stay first party.
packages/i18n ships both catalogs complete; es is generated from COPY.md and a
test re-derives it from the document on every run so it cannot drift.
packages/contracts holds the Zod schemas and the typed client the web app uses.
Verified: 43 vitest tests, 14 Playwright tests on mobile and desktop, typecheck
and lint clean, migrate and seed from a clean database, sign in through the proxy
with CSRF rejection of foreign origins.
Not verified here: docker compose. This user has no access to the docker socket.
RULES.md is absent from docs/, so packages/rules exports only RULES_VERSION and
no tax rule, check digit or deadline was invented. See DECISIONS.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>