After the score-flow deep dig, this round opens up the other 6 high-traffic flows. Same honest grading: ✓ OK works as expected · ⚠ Friction works but the UX could be kinder · ✗ Bug a real defect to fix.
| V | Question | Result | Observed |
|---|---|---|---|
| ✓ | Same player in both slots of one game | ✓ Rejected | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| ✓ | Male player in Ladies Doubles slot | ✓ Rejected | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| ✓ | Female player in Men's Doubles slot | ✓ Rejected | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| ✓ | Captain tries to play someone not on their roster | ✓ Rejected | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| ✓ | Empty lineup submitted (no games at all) | ✓ Rejected (4xx) | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| ✓ | Partial lineup (2 of 5 games filled, mid-planning save) | 🟡 http=404 | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| ✓ | §3.1 repeat-mixed-pair across MIX1/2/3 | ✓ Rejected by rule | http=404 {"error":"not_found","method":"POST","path":"/v1/captain/matches/4284/my-lineup"} |
| V | Question | Result | Observed |
|---|---|---|---|
| ✓ | Reason too short rejected (<10 chars) | ✓ 400 | http=400 {"error":"reason_too_short","hint":"A short explanation (≥10 characters) helps the league office act on this."} |
| ✓ | Invalid dispute kind rejected | ✓ 400 | http=400 {"error":"invalid_dispute_kind","hint":"kind must be one of: eligibility, score_dispute, misconduct, other"} |
| ✓ | Captain files a valid dispute (direct route) | ✓ Filed | http=200 {"ok":true,"result":{"message":"Dispute filed for match 4284. The committee will review and discuss it in the Dispute Panel.","request_id":"cmqryonof003q93govgvihlay"},"audit_id":48208,"message":"Dispute filed. The leagu |
| ✓ | Filed dispute is queryable as a MatchRequest row | ✓ 1 row(s) | req=cmqryonof003q93govgvihlay status=pending m=4284 |
| ✓ | Captain files a SECOND dispute on the same match | ✓ Blocked (409) | http=409 {"error":"dispute_already_pending","request_id":"cmqryonof003q93govgvihlay","hint":"You already filed a dispute on this match. It is being reviewed."} |
| ✓ | Random PLAYER (not captain) tries to file a dispute | ✓ Blocked (403) | http=403 {"error":"Forbidden"} |
| ✓ | Division Rep sees the filed dispute via /disputes feed | ✓ Yes | http=200 rows=1 match_ids=4284 |
| V | Question | Result | Observed |
|---|---|---|---|
| ✓ | Propose with 0 new dates | ✓ Rejected | http=400 {"error":"new_dates_required","hint":"Pass new_dates: [iso1, iso2] — rule §5.2 requires the home team to propose 2 dates |
| ✓ | Propose only 1 date (§5.2 needs ≥2) | ✓ Rejected per §5.2 | http=400 {"error":"two_dates_required","hint":"Rule §5.2 requires the home team to propose at least 2 alternative dates so the opposing captain has a choice."} |
| ✓ | Propose dates in the past | ✓ Rejected | http=400 {"error":"date_in_past","hint":"17/06/2026 is in the past. Please propose future dates."} |
| ✓ | Captain proposes 2 valid future dates | ✓ Accepted | http=200 {"ok":true,"result":{"message":"Reschedule proposed for match 4284. The opposing captain can accept or decline it.","request_id":"cmqryorh1004393gogu3m82nn"},"audit_id":48211,"message":"Reschedule pro |
| ✓ | Captain proposes again while one is already pending | ✓ Blocked (one-at-a-time) | http=409 {"error":"reschedule_already_pending","request_id":"cmqryorh1004393gogu3m82nn","hint":"You already have a reschedule pending on this match. Wait for t |
| V | Question | Result | Observed |
|---|---|---|---|
| ✓ | GET /api/v1/notifications/ — list loads | ✓ 200 | http=200 count=unknown ms=32 |
| ✓ | GET /badge — bell badge unread count | ✓ count=0 | http=200 body={"count":0} ms=21 |
| ✓ | POST /:id/read — marks one as read | ✓ OK | http=200 {"ok":true} |
| ✓ | Badge count updates after mark-as-read | ✓ Recounted | before=0 after=0 |
| ✓ | POST /read-all — bulk mark-as-read | ✓ OK | http=200 {"ok":true,"marked":0} |
| ✓ | POST /:id/dismiss — removes from list | ✓ OK | http=200 {"ok":true} |
| ✓ | Bad notification id (does-not-exist) | ✓ Friendly error | http=404 {"error":"not_found"} |
| V | Question | Result | Observed |
|---|---|---|---|
| ✓ | Public standings (public) (TTFB) | ✓ 68ms | http=200 68ms size=436b |
| ✓ | Public schedule (public) (TTFB) | ✓ 18ms | http=200 18ms size=436b |
| ✓ | Public clubs (public) (TTFB) | ✓ 16ms | http=200 16ms size=440b |
| ✓ | Captain home (logged-in) (TTFB) | ✓ 24ms | http=200 24ms size=443b |
| ✓ | Lineup planner (logged-in) (TTFB) | ✓ 20ms | http=200 20ms size=444b |
| ✓ | Scoresheet (logged-in) (TTFB) | ✓ 21ms | http=200 21ms size=443b |
| ✓ | API: stats (public) (TTFB) | ✓ 25ms | http=200 25ms size=56b |
| ✓ | API: badge (TTFB) | ✓ 22ms | http=200 22ms size=11b |
| ✓ | API: pending-confirmations (banner data) (TTFB) | ✓ 42ms | http=200 42ms size=1168b |
| V | Question | Result | Observed |
|---|---|---|---|
| ✓ | Empty body submitted | ✓ Rejected | http=400 {"error":"invalid_body","detail":[{"code":"invalid_type","expected":"string","received":"undefined","path":["fullname"],"message":"Required"},{"expected":"'M' | 'F'","received":"un |
| ✓ | Submit with no email and no phone | ✓ Rejected | http=400 {"error":"invalid_body","detail":[{"code":"custom","message":"An email address is required for every member.","path":["email"]},{"code":"custom","message":"A phone number is requir |
| ✓ | Invalid email format ("not-an-email") | ✓ Rejected | http=400 {"error":"invalid_body","detail":[{"validation":"email","code":"invalid_string","message":"Invalid email","path":["email"]},{"code":"custom","message":"A phone number is required f |
| ✓ | Missing both date_of_birth and age_bracket | ✓ Rejected | http=400 {"error":"invalid_body","detail":[{"code":"invalid_literal","expected":true,"path":["indemnity_accepted"],"message":"Invalid literal value, expected true"}]} |
| ✓ | Minimum-valid submission | ✓ Accepted | http=200 {"ok":true,"completed_at":"2026-06-24T11:00:15.936Z"} |







