Files
paliad/tests/smoke-2026-04-25.md
m 761e350261 test(smoke): production smoke report + register Playwright MCP (t-paliad-033)
Anonymous-surface smoke test of paliad.de — all 11 legacy DE→EN redirects,
9 gated routes, /login form, and / marketing landing healthy. Two minor
findings noted in the report (knowledge platform is auth-gated contrary
to brief expectation; anon / fires a 401 on /api/changelog/unseen-count).
Authenticated flows untested — needs follow-up worker with creds.

Also registers @playwright/mcp in .mcp.json so future smoke runs can use
the /mai-tester skill's mcp__playwright__* tools directly instead of
falling back to a bunx script.
2026-04-25 23:01:48 +02:00

8.3 KiB
Raw Blame History

Paliad Production Smoke Test — 2026-04-25

Target: https://paliad.de Run by: ritchie/curie (t-paliad-033) Method: curl preflight + Playwright headless (Chromium 1.59.1, viewport 1280×900) Trigger: verify three features that shipped today — project tree (t-paliad-028), team directory (t-paliad-029), reminder fix (t-paliad-032). Auth state: anonymous only (no test credentials available)

Summary

  • 11/11 legacy German redirects return 301 with correct English target.
  • Subpath + querystring preservation works (/akten/abc/deadlines?x=1/projects/abc/deadlines?x=1).
  • 9/9 gated routes correctly 302 → /login.
  • /login renders cleanly: name@hlc.com placeholder, DE/EN toggle, HLC hint, lime branding, no console errors.
  • / renders the Patent Knowledge marketing landing (HTTP 200, lime branding intact, layout clean).
  • ⚠️ / fires a 401 on /api/changelog/unseen-count for anon visitors — surfaces as a console error even though the JS catch is silent.
  • ⚠️ Task brief assumed /tools/*, /glossary, /courts, /links, /downloads, /checklists, /onboarding were ungated. They are not. Auth-gated since the original Fristenrechner commit (d94f8e7, 2026-04-14). CLAUDE.md says these don't need DATABASE_URL, not that they don't need auth — brief misread.
  • 🔒 Authenticated surface (where the three new features actually live: project tree, team directory, reminder UI) is not covered — needs follow-up worker with creds, as anticipated in the brief's "out of scope" section.

No regressions found in the surface that can be tested anonymously. The three shipped features cannot be validated without login.

Per-URL Results

Public / landing

URL HTTP Final Errs Failed reqs Visual Notes
/ 200 / ⚠️ 1 ⚠️ 1 OK Marketing landing renders; 401 on /api/changelog/unseen-count
/login 200 /login 0 0 OK Form renders, placeholder name@hlc.com, DE/EN toggle, HLC hint, lime branding
/onboarding ⚠️ 302 /login 0 0 n/a Gated. Brief expected public; matches code which has no public /onboarding route

Knowledge platform (auth-gated, contrary to brief expectation)

All return 302 → /login (HTTP 200 after redirect, ending on the login page):

URL Final URL Title Errs Failed reqs
/tools/fristenrechner /login Anmelden — Paliad 0 0
/tools/kostenrechner /login Anmelden — Paliad 0 0
/tools/gebuehrentabellen /login Anmelden — Paliad 0 0
/checklists /login Anmelden — Paliad 0 0
/glossary /login Anmelden — Paliad 0 0
/courts /login Anmelden — Paliad 0 0
/links /login Anmelden — Paliad 0 0
/downloads /login Anmelden — Paliad 0 0

Per internal/handlers/handlers.go:79-115, these are registered on the protected mux; that's been the case since d94f8e7 (2026-04-14). Not a regression — brief expectation was wrong.

Legacy German → English redirects (301, all )

Legacy → Target Result
/fristen /deadlines 301
/akten /projects 301
/termine /appointments 301
/notizen /notes 301
/einstellungen /settings 301
/projekte /projects 301
/dezernate /departments 301
/parteien /parties 301
/checklisten /checklists 301
/glossar /glossary 301
/gerichte /courts 301
/akten/abc/deadlines?x=1 /projects/abc/deadlines?x=1 301 (subpath + qs preserved)

Gated routes (302 → /login, all )

/dashboard, /projects, /deadlines, /appointments, /team, /agenda, /settings, /whatsnew, /search — every one redirects to /login. Auth gate is functional.

Console errors observed

Only one across all tested pages — on /:

Failed to load resource: the server responded with a status of 401 ()
URL: https://paliad.de/api/changelog/unseen-count

Root cause: frontend/src/client/sidebar.ts:135-153 initChangelogBadge() fires unconditionally on every page that includes <Sidebar />. The catch swallows the error in JS, but the browser still logs the 401 in DevTools.

Why the marketing landing has the sidebar at all: the public / serves dist/index.html (handled in internal/handlers/dashboard.go:47-52) — same shell as the authenticated app, just without a session. Sidebar JS therefore runs in anon context and the changelog fetch hits a protected route.

Severity: cosmetic / log noise. Does not break the page. Worth fixing because (a) it surfaces a 401 that looks alarming in DevTools, and (b) it costs an HTTP round-trip for every anonymous landing visit.

Suggested fix (one-liner): inside initChangelogBadge(), early-return when the changelog badge link itself isn't present, OR check for a session cookie marker before fetching, OR move the marketing landing to its own minimal shell.

Failing network requests

Same 401 — only one across all pages tested:

Page Request Status
/ GET /api/changelog/unseen-count 401

No 4xx or 5xx anywhere else. Asset pipeline (/assets/*) returns 200s.

Screenshots

Stored in /tmp/mai-tester/:

  • paliad-root.png — marketing landing, lime hero, sidebar icon-rail visible on left
  • paliad-login.png — clean login card, name@hlc.com placeholder, DE/EN toggle top-right
  • paliad-onboarding.png, paliad-tools-*.png, paliad-glossary.png, paliad-courts.png, paliad-links.png, paliad-downloads.png, paliad-checklists.png — all show the login form (302 redirected there); identical to paliad-login.png (≈28 KB each, vs. 74 KB for the rendered marketing landing — quick file-size sanity check confirms they are all the login screen)

Visual sanity: layout intact on all rendered pages, no half-rendered content, no broken images on /login or /.

Top issues, ranked by severity

  1. Brief vs. reality mismatch — knowledge platform is auth-gated. Brief said "ungated, per CLAUDE.md"; CLAUDE.md actually only says these routes don't need DATABASE_URL. The product requires login for everything except /, /login, /logout, /assets/*. Action: either (a) clarify CLAUDE.md so future briefs don't repeat this misread, or (b) decide that the product wants a public knowledge tier and move those routes to the unprotected mux. Today's behaviour matches the code.
  2. Anon / triggers 401 on /api/changelog/unseen-count. Console noise; minor. Fix in frontend/src/client/sidebar.ts — gate the fetch behind a session marker, or scope initChangelogBadge to authenticated-only pages.
  3. Anon /onboarding 302s to /login. Brief's expectation was a "sane" anon behaviour; redirecting to login is sane, but if the product later wants self-serve onboarding (e.g. via invite link), the route doesn't currently support that flow.
  4. Three new features (t-paliad-028, -029, -032) untested. All sit behind auth — project tree at /projects, team directory at /team, reminders inside Akten/Frist UI. Need a follow-up worker with credentials. Unit + handler tests are presumably green (they shipped), but no live-prod verification has happened.
  5. No further issues found in the anonymous surface. Login form, redirects, auth gate, marketing landing all behave as coded.

Acceptance checklist

  • All public + knowledge URLs in scope visited
  • All legacy redirects verified (11/11 + subpath/qs case)
  • All gated routes verified to 302 to /login
  • Report file written
  • Per-URL screenshots captured at /tmp/mai-tester/paliad-<slug>.png
  • No raw logs in chat — summary only

Out of scope (explicitly deferred)

  • Authenticated flows: project tree (t-paliad-028), team directory (t-paliad-029), reminder fix (t-paliad-032), Dashboard, Agenda, Search, Whatsnew, Settings.
  • Email send (no SMTP creds), CalDAV sync (no CalDAV creds).
  • Multi-language end-to-end (only DE rendered, EN toggle visually present but interaction not exercised).

Hand off to a follow-up worker once m provides test credentials.