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.
8.3 KiB
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. - ✅
/loginrenders cleanly:name@hlc.complaceholder, 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-countfor anon visitors — surfaces as a console error even though the JS catch is silent. - ⚠️ Task brief assumed
/tools/*,/glossary,/courts,/links,/downloads,/checklists,/onboardingwere ungated. They are not. Auth-gated since the original Fristenrechner commit (d94f8e7, 2026-04-14). CLAUDE.md says these don't needDATABASE_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 leftpaliad-login.png— clean login card, name@hlc.com placeholder, DE/EN toggle top-rightpaliad-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 topaliad-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
- 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. - Anon
/triggers 401 on/api/changelog/unseen-count. Console noise; minor. Fix infrontend/src/client/sidebar.ts— gate the fetch behind a session marker, or scopeinitChangelogBadgeto authenticated-only pages. - Anon
/onboarding302s 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. - 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. - 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.