How a real human would test this platform · sandbox at uat.silkvo.com
The platform is being graded by what a real person would actually try to do, not by counting buttons. Every role, every important action, has been walked by an automated puppeteer + verified by hand. The blue links below jump to the live results.
Open /qa.html, one-click into any role (Captain, Player, Registrar, Finance, Division-Rep, Judge, Admin, Editorial, Super-Admin). No password.
/committee-test.html — every feature with a screenshot + "how to test" step. The way most testers prefer.
This page — every screen each role lands on, graded and screenshotted. Click any role below.
Floating "Send feedback" button on every page — voice + screenshots + auto-captures the page state. Reaches us directly.
Audited: what a real Captain / Player / Registrar / Finance / Division-Rep / Judge / Editorial / Admin / Super-Admin / Public visitor lands on. Verified: every chat & broadcast channel × permission case. Walked end-to-end: filing a dispute, opening an office thread, ordering a rematch, sending a broadcast, verifying eligibility, sending a payment reminder.
Click each title to open the live page with every screenshot.
Targeted the last untouched bedrock classes: multi-tenant data isolation (ID-based, not name — uat is a clone so names collide), scoresheet co-sign code brute-force (6-hex codes = 16.7M combinations × 5 games + per-IP rate-limit 429 on flood), live-scoring (start/point/undo + role gates for PLAYER/SPECTATOR), JSON DoS (11MB body rejected, 100k array survives, prototype pollution attempt blocked, 2000-deep nesting survives), injury substitution rule path, and admin mass actions (broadcast). All 30 tests green with no bugs found — the bedrock holds.
Open round 5 →
Bedrock-level probes on the platform-security classes still untouched: CSRF (Origin/Referer tampering — 6/6 ✓ all blocked), file upload (SVG-XSS, MIME-spoof, 5MB cap, path-traversal — sanitized), WebSocket (anon connect, foreign Origin, cross-team subscribe — all denied), DUPR webhook (malformed payload, fake RATING for non-existent player — no DB pollution), session (logout invalidation, suspended-user cookie, HttpOnly flag — all enforced), rate limiting (60× QA flood, 35× chat flood — both 429), auth edges (email enumeration, path-traversal role, empty pw, script-tag userId — all blocked). Found and fixed: /qa/:role was the ONLY login route that didn't call _qaRecordFailure(req) on wrong password — making QA-password brute-force effectively unrestricted. Now matches the other 5 QA routes.
Comprehensive stress-test of Lineup, Dispute, Reschedule, Notifications, Performance, Onboarding. Surfaced and fixed 3 real bugs in this round: (1) reschedule accepted past dates, (2) the §5.2 "two dates required" rule was only a hint, (3) captains had no non-AI route to file a dispute (added POST /captain/matches/:id/dispute). Also added a one-at-a-time duplicate-proposal guard. Every endpoint TTFB ≤ 70 ms.
Validation, recovery, permissions, dispute discoverability, mobile UX, empty states — 25 tests in total. Found and fixed a real bug: deuce scores (22-20, 23-21) were being rejected by the score_target rule which required winner == exactly 21. Now allows "win by 2". Added a ⚠️ Dispute link to the scoresheet topbar (was no in-page affordance before). Bumped match-winner radios from 13×13px to 22px (mobile-tappable).
Open the score deep-dig →
Real walk on a real uat match, from the home captain entering scores through the away captain confirming → match auto-completes → standings update → both teams' leaders notified. Every phase live-captured, including a non-captain teammate seeing the banner with "↳ Ask your captain to confirm" (closed the impersonation caveat with a sandbox `/qa/as/:userId` route), and the away captain's view showing the "Review & confirm" button + the actual submitted scoresheet. Proves the workflow Richard cares about most: zero admin action, instant DUPR upload. The §3.1 (no-repeat-mixed-pair) rule even fired correctly on a bad submission and blocked it cleanly.
Open the score walk →
33 screens across 10 roles. Each captured + auto-checked (HTTP, console errors, broken images, clear heading, primary action). The two ⚠ are cosmetic auto-check edge cases (feed empty-state placeholder + my-lineup topbar style) — both reviewed by hand; no real user-facing issue.
Open desktop audit →
iPhone-width capture of the screens mobile-first users actually use. Watches for horizontal overflow, broken images, missing primary actions. All pages pass.
Open mobile audit →
For comparison: the current production hkpl.silkvo.com public pages. All 6 flagged for horizontal scroll at desktop sizes (the home page is 1282px wide on a 1100px viewport — about 182px of extra scroll). The new platform doesn't have this. Useful "before / after" framing for the committee.
Beyond "the page loads," six full workflows: office message → registrar reply, reschedule → opposing captain accepts, dispute → workgroup + R&R assistant, eligibility verify, unpaid reminder, admin broadcast → player's bell. Each performed via the real server, then the recipient's screen captured.
Open action walks →A systematic sweep of every messaging channel, both who CAN read it and who CAN'T. The kind of permission test that's easy to skip and where most platforms leak.
| Category | What's tested | Result |
|---|---|---|
| Direct messages | Player → captain DM works; unrelated user blocked; Super-Admin moderation read works (fixed this round — was hanging forever). | 4 / 4 ✓ |
| Team channels | Captain posts; admin reads OK; non-member blocked. | 3 / 3 ✓ |
| Office threads | Member opens a topic; the right role + admins read; the wrong role is blocked; staff replies surface to the member. | 6 / 6 ✓ |
| Dispute rooms | Filer + opposing captain + workgroup + admins all read; outsider blocked. | 5 / 5 ✓ |
| Admin broadcast → role | Admin broadcasts to all PLAYERs; every player sees it in their notifications bell (fixed this round — was silently dropping). | 2 / 2 ✓ |
| Cross-tenant isolation | A uat user cannot read the hkpl tenant's channel. | 2 / 2 ✓ |
| Workflow notifications | Filing a dispute notifies the opposing captain. | 1 / 1 ✓ |
| CSRF / cross-origin | A foreign-origin POST to /chat/send is rejected (fixed this round — was accepted). | 1 / 1 ✓ |
Real bugs the audit caught that earlier passes missed. All fixed and re-verified.
tenant_id: null, but ChatMessage.tenant_id is NOT NULL → Prisma threw a malformed-query error that never came back as a response. Cross-tenant moderation was broken. Fixed: skip the tenant filter when the user is Super-Admin (canRead already gates which channels they can see). FIXEDonerror handler hides the broken icon. FIXEDdocs/RR_CLAUSES_DRAFT.md — committee to review & adopt. POLICYA 15-minute walk that covers the platform end to end.
| Step | Open | Do this |
|---|---|---|
| 1. | /qa.html | Tap "Captain" — you're in. The top banner shows pending actions for YOUR team. |
| 2. | /app.html | Find a scheduled match → Reschedule → propose new dates → switch to the other captain → accept in the banner. |
| 3. | /messages.html | Tap 🏛️ Office → pick a topic → send. Then sign in as Registrar (/qa.html) → 🏛️ Office inbox → reply. |
| 4. | /disputes.html | File a dispute on a match (as Captain), then as Tenant-Admin → open the discussion room, ask the R&R Assistant, and try Uphold / Dismiss / ⚖️ Order rematch. |
| 5. | /registrar.html | As Registrar → Eligibility tab → verify a player. As Finance → Unpaid tab → Send reminder. |
| 6. | /standings.html | The page everyone checks — fast load, team logos, scroll-free at any size. |
| 7. | Floating button | Tap "Send feedback" anywhere — voice + screenshot + text. Reports go straight to us. |
Desktop audit · Mobile audit · Live HKPL audit · Action walks
/committee-test.html — every feature with how-to-test
Dispute Panel · Office Inbox · Approvals queue · Admin shell
/qa.html — one-click any role, no password