3Serious integrity holes closed
10+“No support call” fixes
6User angles walked
Everyrole covered — with proof
Opponent line-ups could be peeked before the matchIntegrity — fixed
A captain wants to win. We found that any captain could open a different match on the officials’ screen and read both teams’ unrevealed line-ups — then relay a rival’s plan to their opponent to counter-pick. The “both reveal at once” promise was defeatable.
What we didPlayer line-ups are now hidden from any non-official on every screen (scoresheet, printable form, judge console, and the officials’ match screen) until both sides reveal, a score is entered, or the match is over. We keyed it on “are you an official?”, not a role label, so a manager who also captains a team can’t slip through.
Verified liveUninvolved captain requesting the match bundle → line-up fields come back blank (opponent_lineup_hidden: true). A judge on the same match → sees the real players. Confirmed on match 5506.
Two captains could move a match without HKPLIntegrity — fixed
The “both captains and HKPL must agree” rule for rescheduling was still bypassable through an older “postpone” path — two captains could quietly agree a new date with no HKPL sign-off (e.g. to dodge a strong opponent’s availability).
What we didThe old two-party postpone/accept routes are retired. All reschedules now go through the one negotiation where both captains and HKPL each tap Agree — HKPL can’t be skipped. The old buttons now point to the new flow.
Verified liveThe retired routes return “gone / use the reschedule discussion.” The new flow correctly refuses to move a match after only the two captains agree — HKPL is still required.
Try it → sign in as Captain, open a match’s Reschedule
Our own program code & private player data were publicly downloadableSecurity — fixed
Several server files (including our sign-in logic) had been left in the public web folder and could be downloaded by anyone. Separately, a public player page returned an 84 KB blob of raw provider data — legal name, age, address.
What we didMoved the stray code out of the public folder, and made the player page return only the tidy public fields (rating, display name) — never the raw personal block. On UAT we also switched player profiles to members-only.
Verified liveThe old file URLs now return the normal web page, not code (0 matches for any login/secret keyword). Anonymous player lookup dropped from 84 KB → 572 bytes with the raw block gone; on UAT it now asks you to sign in first.
Standings points now agree everywhereFixed
Two places computed standings and disagreed on how a forfeit loss scored — the same team could sit at a different rank on different screens, which can shift a playoff/relegation cut.
What we didAligned both so a forfeit loss scores the same way in the league table and the playoff seeding.
A division rep couldn’t stray outside their own divisionsFixed
One dispute action (the rulebook helper) wasn’t scoped, so a division rep could post into a dispute outside the divisions they’re assigned to.
What we didScoped it like every other dispute action — reps only touch their own divisions.
Accidentally locking an empty line-upFixed
Tapping “Reveal” locks your line-up. A captain who tapped it early or by mistake — with nothing filled in — locked an empty line-up and was told “contact an admin.” A guaranteed phone call.
What we didYou can no longer reveal an incomplete line-up. If any game is missing a player, it stops you with a plain message instead of locking you out.
Verified liveRevealing a 0/5 line-up now returns: “Your line-up is not complete yet — 0 of 5 games have both players. Fill every game before you reveal, because revealing locks your line-up.”
Try it → Captain → Plan Line-up → Reveal
Trying to reschedule a match that was already playedFixed
Opening the reschedule page for a finished match still showed the “start a reschedule” options, then failed with a raw pop-up after you’d picked a date — with no hint of what to do instead.
What we didThe page now checks up front. For an already-played match it explains it can’t be rescheduled and points you to raise it from the match sheet (the correct self-service path) — no dead pop-up.
Verified liveCompleted match 4847 now returns “can’t open — already played” and shows the match-sheet link instead of the action cards.
The “scoresheet overdue” pile looked resolved but did nothingFixed
Almost the whole registrar queue was “scoresheet not uploaded” auto-flags with a big green Approve — but Approve changed nothing on the match. A registrar clearing the pile believed the matches were handled; standings quietly stayed wrong.
What we didThe button now reads Acknowledge (with a note that it does not score the match), and we stopped hiding the guidance that says the real fix is Score / Forfeit / Extend.
Try it → sign in as Registrar
Old payment receipts couldn’t be viewedFixed
Finance clicking “View receipt” on most existing teams got an error — the majority of real receipts (migrated from the old system) simply wouldn’t open.
What we didThose receipts now open again (they’re redirected to where the file actually lives). Receipt photos saved as .jfif (a common phone format) also upload cleanly now instead of being rejected.
Verified liveA migrated receipt now opens (redirects to storage); ~129 of the affected teams recovered.
The oversight committee couldn’t open their own viewFixed
The read-only Oversight account was sent to the admin page but then blocked by it — a dead bounce.
What we didOversight now opens the admin dashboard read-only (they can see everything, change nothing). Friendlier “please sign in / not found” messages replaced raw error codes in several places too.
Scoresheet & line-up — the small snags that trip people upFixed
On the match-day screens: a “Lock line-up” button that didn’t actually lock (and prompted “play now?” even with nothing filled in); a finished match still showing the “enter the result / both sign” steps; a broken/old match link landing on a bare error; and a wrong score only rejected after you pressed Submit.
What we didThe button now reads Save line-up and only offers “start the match” once all five games are filled. A completed match hides the entry instructions. A broken or out-of-date link shows a friendly “Match not found” with a way back. And an impossible or unfinished score is now flagged in red as you type — not only at Submit.
Verified liveCompleted match → instructions hidden, read-only banner shown; a bad link → “Match not found” card with a Back button (no raw code); an incomplete line-up can’t be revealed and locked.
Try it → Captain → Plan Line-up / Enter your scores
Player & captain hub — the small snagsFixed
A stale “match starts in 30 min” reminder from days ago left the notification bell stuck; the “More” menu showed captain-only tools to plain players, which then hit a role wall; and captains wanted “Plan line-up” right on the match card.
What we didOld reminders now expire automatically (and the bell filters them out), so it never shows a match that has already been played. The “More” menu shows a plain player only the tools meant for them — no role-wall dead-ends. Captains get a “Plan line-up” action on their next-match card. And a player who is already on a team no longer sees “find a team to join.”
Verified live733 stale reminders cleared; the “More” menu shows 4 captain tools to a captain and 0 to a plain player.
Admin can reveal line-ups on the captains’ behalfBuilt
What we didReveal stays the captains’ own action — but for the “nobody on court has a phone” case, an admin can now reveal both line-ups on their behalf from the officials’ match screen. Every use is logged.
Verified liveAdmin “reveal both” succeeds and is recorded in the audit trail; a plain captain still can’t reveal someone else’s side.
“Uphold” a dispute no longer implies the score changesBuilt
What we didThe button now reads Uphold with a note that the score correction is a separate step — so no one assumes the result was auto-fixed.
Cleaner phonesBuilt
What we didFixed the admin header wrapping into a broken column on phones, the portal buttons clipping off-screen, the feedback pill covering the top of the standings, the club portal’s empty stat tiles, blank “Captain —” labels, and long approval lists now page 25 at a time.
Paying members can’t see what they owe, how to pay, or whether it landedBuilding next
Today the registration form asks for a payment receipt but never shows the amount, the bank/FPS details, or a deadline; a captain can’t see their own invoice; and there’s no “✓ Paid” confirmation anywhere. Each is a guaranteed phone call.
PlanShow the fee + how-to-pay before the upload, let the payer open their own invoice, and add a clear Paid / Under-review / Rejected status on the team. (Billing is simple — manual receipts, no subscriptions.) This is the next build.
A few calls that are the committee’s to makeNeeds committee
For discussionA manual “stop match” button for HKPL during a typhoon; enforcing the “played ≥ 50% of matches” playoff eligibility rule; and confirming club managers’ self-service scope (they run their club page & teams; league approvals stay with HKPL). A short decision sheet is ready.