- e2e/dev-system/nav-smoke.spec.ts: new Playwright spec in the dev-system
suite; iterates every href from navSections + adminNavEntries, asserts
HTTP status ≠ 404 and no "page not found" text for an authenticated admin
- e2e/navigation.spec.ts: add "all nav routes resolve" smoke block covering
16 routes not previously tested in the isolated test suite
All 35 routes pass against live dev server. Catches dead nav links before
users encounter them.
Co-Authored-By: claude-flow <ruv@ruv.net>
- global-setup.ts: create reset-test@planarchy.dev directly via DB
(argon2id hash computed in Node.js, inserted via docker exec psql stdin
with correct camelCase quoted column names + createdAt/updatedAt;
ON_ERROR_STOP=1 so failures propagate rather than being swallowed)
- helpers.ts: resetPasswordViaApi now updates passwordHash directly in DB
(bypasses tRPC batch mutation format issues entirely);
getLatestEmailTo decodes MIME parts per Content-Transfer-Encoding
(quoted-printable soft line breaks were truncating 64-char tokens to ~14 chars)
- invite-flow.spec.ts: use fresh unauthenticated browser context for
the invite accept page (admin context was inheriting cookies)
- docker-compose.yml: hardcode SMTP_HOST=mailhog for Docker app service
(host .env value localhost doesn't reach Mailhog inside Docker network)
All 3 email E2E tests pass: invite flow, password reset flow, invalid token.
Co-Authored-By: claude-flow <ruv@ruv.net>
- SMTP: SMTP_HOST/PORT/USER/FROM/TLS now all have ENV override support
(previously only SMTP_PASSWORD was env-aware). ENV takes priority over DB.
- docker-compose.yml: forward all SMTP_* env vars to app container + add
Mailhog service (ports 1025 SMTP / 8025 HTTP, always available in dev)
- Password reset: PasswordResetToken Prisma model + authRouter with
requestPasswordReset (timing-safe, no email enumeration) + resetPassword
- UI: /auth/forgot-password, /auth/reset-password/[token] pages +
"Forgot password?" link on sign-in page
- E2E: Mailhog helpers (getLatestEmailTo, clearMailhog, extractUrlFromEmail)
+ invite-flow.spec.ts + password-reset.spec.ts
Co-Authored-By: claude-flow <ruv@ruv.net>
New users on a shared device were picking up a previous user's stale
(potentially empty) dashboard layout from localStorage because the key
"capakraken_dashboard_v1" was not user-scoped.
- useDashboardLayout: key is now capakraken_dashboard_v1_{userId};
userId is resolved via trpc.user.me before touching localStorage
- Initial state falls back to createDefaultDashboardLayout() until
userId resolves, then hydrates from the user-scoped key
- DB layout still wins over localStorage when it has data (unchanged)
- E2E test suite covers: new-user flow, modal widget list, add widget
persists after reload, cross-user localStorage isolation
- plan.md: added ticket #27 implementation plan
Co-Authored-By: claude-flow <ruv@ruv.net>
Fixes 8 failures from the first test run:
1. Rate limiter exhaustion (5/8 failures)
Admin was logged in 9× across the suite, hitting the 5/15min auth
limit. Fix: global-setup.ts logs in once per role and saves storage
state; all non-login tests use storageState so they skip the form.
Total admin logins per suite run: 3 (global setup + 2 explicit tests).
2. Strict-mode violations (2/8 failures)
toBeVisible() matched 3 email cells / 2 permission-error nodes.
Fix: .first() on both locators.
3. Auth.js v5 signout confirmation page (1/8 failures)
GET /auth/signout renders a confirm form rather than immediately
redirecting. Fix: signOut() helper clicks the submit button.
Note: running the suite right after a previous run may fail if the
in-memory rate limit hasn't reset (15-min window). Restart the dev
server, or add E2E_TEST_MODE=true to apps/web/.env.local to bypass.
Co-Authored-By: claude-flow <ruv@ruv.net>
Auth.js v5 manages token.jti internally and overwrites it after the jwt
callback. Storing our session UUID in token.sid ensures the value we
persist in active_sessions matches what the signed cookie carries.
- jwt callback: token.sid = jti (was token.jti)
- session callback: read from token.sid
- signOut event: falls back to token.jti for backward compat with any
sessions created before this change
Also adds Playwright dev-system test suite (playwright.dev.config.ts +
e2e/dev-system/) that validates login, session registry health, and
RBAC enforcement against the running localhost:3100 dev server.
Co-Authored-By: claude-flow <ruv@ruv.net>