Two unrelated root-causes were keeping the Integration tests and e2e
workflows red on every push to main since `d8c549e` (50+ runs).
1. Integration: `.github/workflows/integration.yml` had `ENCRYPTION_KEY:
0000…` as a bare YAML scalar. YAML 1.2 parses a run of zeros as the
integer 0 — so the runner exported `ENCRYPTION_KEY=0`, and
`decodeKey()` rejected it as "must be hex (>= 32 chars) or base64
(32 bytes)". 6 tests in admin-backups-* and integration-status
failed at module load. Quoting the value forces a literal string.
2. e2e: the global-setup seeded user had `onboarding_tour_completed`
left at its default `false`, so the spotlight tour mounted a
full-viewport `role="dialog"` overlay (z-index 200) on every
authenticated spec. Playwright's hit-test then caught the tour's
skip-button instead of the intended target — every spec that
clicked sidebar / quick-add / logo timed out. Setting the column
to `true` in the upsert keeps the tour off the dashboard for the
rest of the suite. The two `onboarding-flicker.spec.ts` mocks
that fulfil `/api/auth/me` from inside the spec also need the
field, since they replace the seeded payload.
Workflow change is comment + quoted strings only — no secrets, no
runtime cost.
Authenticated specs need a deterministic user and a persistent session
cookie. global-setup.ts upserts an `e2e-tester` admin via raw `pg` (the
generated Prisma client uses ESM `import.meta.url`, which Playwright's
TS loader cannot resolve), then logs the user in once and writes
`storageState.json` so every authenticated spec reuses the same
session — the per-IP login rate-limit (5 attempts / 15 min) would
otherwise lock out the suite the moment six specs run in parallel.
Adds `pg` + `@types/pg` as devDependencies — required for the seed
step. `pg` is already used by `scripts/seed-demo.ts` for the same
loader-incompatibility reason, so we're not introducing a new
dependency footprint, only making it explicit in the lockfile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>