What's new
Security — internal error details no longer surfaced
Status: Pending enablement (deploys with the next release)
- When something goes wrong on the server, the app used to occasionally pass
the raw underlying database/system error text back to the browser. Across the whole API that's now scrubbed — you get a clear, generic "something went wrong" message instead, while the full technical detail is logged securely on the server for us to diagnose
- This closes an information-disclosure gap on 159 API routes (sign-up,
billing, invoices, households, the member portal, staff management, events, automations, voice notes and more) without changing any behaviour: the same actions still succeed or fail in exactly the same way, with the same status codes — only the error *wording* shown to the browser is tightened
- Friendly, action-specific messages you actually need (e.g. "This person is
already a staff member of this club", "effective_date must be YYYY-MM-DD") are preserved untouched — only leaked internal detail is removed
- A new automated guard keeps it that way: the build now fails if a future
change reintroduces a raw internal error message into an API response
Part of an ongoing security-hardening pass. No prices, permissions, or workflows are changed — this is purely a tightening of what error information leaves the server.
Security — staff permissions always reflect your role in *this* club
Status: Pending enablement (deploys with the next release)
- Across payment connections, module/billing settings, certificate templates,
grading publish/certificates and event actions, the app now always checks the role you hold in the club you're working in — read from the authoritative per-club membership — rather than an older "primary club" role that could be out of date
- This closes a gap where someone demoted in a club could briefly keep a
higher level of access there, and fixes the opposite case where staff who help at more than one club were sometimes wrongly blocked from a club they genuinely manage
- For the vast majority of staff (a single club, one role) nothing changes —
same access, same screens. No permissions are widened; if anything this is slightly stricter and more accurate
- A new automated check keeps every staff-facing route on this single, correct
source of truth so the inconsistency can't creep back in
Security — demo, public links and club boundaries, locked down
Status: Pending enablement (deploys with the next release)
- The demo is now fully look-but-don't-touch. Anyone exploring the
try-it-out demo club is in a genuine sandbox — every save, edit and delete across the whole app is blocked from ever changing demo data, so the demo always looks clean for the next visitor and can never spill into a real club
- Shared/public links now carry only what they need. Where the app hands out
a link that doesn't require a login (e.g. an invitation or a form), the page behind it now receives just the data needed to do that one job — nothing extra about other members or your club is sent to the browser
- Your club's data stays inside your club — automatically. We've added an
automated guard that checks every place the server writes data and confirms it is tied to a specific club. If a future change ever tried to write without that club boundary, the build stops it before it can ship. This makes "one club can never see or touch another club's records" a rule the system enforces for us, not something we have to remember
- For you day-to-day, nothing changes — same screens, same actions, same
data. These are guard-rails working quietly in the background to keep every club's information separate and the demo safe
All part of the same security-hardening pass: no prices, permissions or workflows change — just stronger, automatically-enforced boundaries around who can touch what.
Security — grading routes moved onto the shared safety wrapper
Status: Pending enablement (deploys with the next release)
- The grading and examiner endpoints (publish/unpublish results for a single
event or a whole session, scoring criteria, the live "who's on the mat" scoring group, and examiner scoring-link management) now run through the same central safety wrapper the rest of the app uses — one place that checks you're signed in, holds the right role, and isn't the demo club, before any write
- Publishing and unpublishing grading results stays owner/admin-only, exactly
as before; the live scoring tools and criteria stay open to all staff, exactly as before. Nothing about who can do what changes — this just routes those checks through the shared, automatically-tested path instead of hand-written copies in each file
- The login-free examiner scoring links are untouched: still throttled, still
scoped to one club + one session, and still sending the panel only a student's name and rank — never a date of birth or household detail
- New focused tests pin the high-risk grading actions (record an outcome,
publish, unpublish, save a judge's score): another club's record is refused, the demo is blocked, and the right role still succeeds — so these can't quietly regress in future refactors
For you day-to-day, nothing changes — same screens, same actions, same results. This is internal plumbing on the same hardening pass.
Security — public links that age out safely
Status: Pending enablement (deploys with the next release)
- We reviewed every login-free link the app sends out — examiner scoring
links, insurance-renewal links, enrollment invites, competition-entry invites, trial cancel/reschedule links, invoice PDFs, the family calendar feed and unsubscribe links — and confirmed each one is throttled against abuse and only ever shows data for the right club
- Competition-entry invite links now age out. A very old, unused
competition-entry invitation link is now politely declined instead of staying live indefinitely — staff can simply re-send a fresh one. The window is deliberately generous (far longer than any real entry deadline), so links parents are actually using are completely unaffected
- Nothing already in your inbox breaks. This was done carefully so that
links already sent out keep working exactly as before — we only close down links that are effectively dead anyway
- A new automated guard keeps an inventory of every one of these public links
and fails the build if a future link ever ships without abuse-throttling or a documented reason — so the standard is enforced for us, not just remembered
Security — admin-only actions locked down server-side
Status: Pending enablement (deploys with the next release)
- Bulk member import and transferring a student to another club now
require an admin role on the server, not just in the screen. These were always admin-only buttons in the app, but a determined non-admin could previously have triggered them by other means — now the server enforces it too. If you use these features as an owner or admin, nothing changes
- Behind the scenes we moved refunds, GDPR erasure, student transfer and
several grading actions onto a single shared permission-and-safety checkpoint, so every one of them is consistently blocked on the demo club, consistently scoped to your own club, and returns a consistent "not allowed" message. No change to how any of these work for the right person on the right club