Changelog

What we shipped, when. Newest first.

Saves that fail now tell you — plus server-side venues, timetable, tasks and more

24 June 2026

What's new

Saves now fail loudly, not silently

  • If a save ever doesn't go through — your session quietly expired, the connection dropped, or the

server said no — the app now tells you and undoes the change on screen, instead of looking saved when it wasn't. Tap again once you're back and it'll save properly.

  • This now covers: register (sealing/unsealing a class, adding coaches/volunteers and their

status, marking event attendance, adding an ad-hoc booking), trials (status changes from the trials list, the pipeline, and the register), grading (the examiner equipment/criteria checklist), tasks (create, edit, status, delete), and venues + timetable (add, edit, archive, restore).

  • On the register, if an event's attendee list can't load, you'll now see a clear "couldn't load —

retry" message instead of an empty list that looks like nobody's booked.

  • All of these now save through our secured server with the same club + permission checks as the

rest of the app — so nothing important relies on the browser quietly succeeding.

Behind the scenes — the Insurance report now fetches through our secured server

  • The Insurance report (valid / expiring / expired counts and the renewal rate) now pulls its

member data through our secured server, the same way the other reports already do.

  • Your numbers are unchanged — only where the data is fetched moved. The figures are still

calculated exactly as before, so every total stays identical.

  • This continues the work of keeping member information off the browser and behind server checks.

Security — stronger throttling on public links

  • Some public links (the insurance renewal page and the external-event cancellation page)

now apply the same rate-limiting on their initial load that they already used on submit — closing a small gap so the links can't be hammered or enumerated.

  • No links changed or expired; this is purely an extra layer of protection.

Behind the scenes (no action needed)

  • Completed a full audit pass of the platform's reports, public links, file storage, and the

workflows that touch money — documenting exactly where data is shaped server-side, where public links stand on expiry/throttling, and which money workflows still need extra protection. These audits guide the next rounds of hardening; nothing in them changes how the app behaves today.

Reports now load through our secured server — and a new safety check for member data

23 June 2026

What's new

Fix — "On the mat now" in Assessments now shows everyone present

  • In Assessments, the "On the mat now" filter could leave some grades looking empty even

when members of that grade were marked Present/Late on today's register — most noticeably for certain tag grades.

  • The cause: that filter was also (incorrectly) requiring the member's class to be tagged to the

grade's programme. If today's class was untagged, or tagged to a different programme, the member was hidden — even though they were clearly on the mat.

  • Now fixed — "On the mat now" shows any member of that grade who's Present/Late today,

regardless of which class it was logged against. The separate "lessons since last grading" count still only counts that programme's classes (so a member's other-discipline sessions don't inflate it), and that count now reads the programme from the grade itself rather than guessing from the first student in the list — so one mis-tagged member can no longer skew a whole grade.

Behind the scenes — your Reports now fetch data through our secured server

  • Every figure on the Reports screen — Trial Funnel, Events, Households, the Owner

Overview dashboard, and the Financial report — now pulls its underlying data through our secured server rather than directly from your browser. This keeps each club's member and money data more strictly separated.

  • Nothing about the numbers has changed. Every total, conversion rate, revenue figure,

household count and chart is calculated exactly as before — we only changed *where* the raw data is fetched, not the maths. The programme lens (filtering a report to one programme) works exactly as it did.

  • Money is still counted to the penny, and the Financial report still falls back gracefully

if an optional feature isn't switched on — so you'll never see a misleading "£0".

  • If a report ever can't load, it fails safely with no risk of showing another club's data.

Behind the scenes — a new automatic safety check

  • We added an automatic check to our build process that **flags any new screen that tries to

read sensitive member data (child details, payment records, safeguarding notes) directly in the browser** instead of through the secured server.

  • This is purely an internal safeguard for us as we keep tightening data protection ahead of

the wider rollout — there is no change to anything you see or do in the app.

Fixed trial-booking embed websites not showing after reload

22 June 2026

What's new

Fix — your allowed embed websites now stay visible in Settings

  • In Settings → Club details, the list of websites allowed to embed your trial

booking form (the "embed origins") saved correctly, but after leaving the page and coming back the list could appear empty — even though the saved sites were still in place and still working on your real booking pages.

  • This was a load-order glitch on the settings page: the page loaded your saved sites,

then a moment later overwrote the on-screen list with a blank one. Your data was never lost — only the on-screen display was wrong.

  • Now fixed — the saved websites reload and stay shown every time you open the page.

Nothing about how the trial booking embed actually works has changed.

Behind the scenes — stronger protection for member data

  • We continued moving sensitive member information (membership details and now **grading /

assessment progress) so it's fetched through our secured server** rather than directly by your browser. This tightens how member data is kept separate between clubs.

  • No change to what you see or do — your grading screen, RAG syllabus scoring, belt history

and rank switching all work exactly as before, and grading, rank changes and publishing are untouched.

  • If one of these screens ever fails to load, you'll now see a clear **"couldn't load — try

again"** message instead of a screen that silently stays blank.

Behind the scenes — student notes now load through the secured server

  • Student profile → Notes now loads the notes list through our secured server (same as the

grading and membership data), keeping member information cleanly separated between clubs.

  • No change to what you see or do — notes look the same, the newest stays on top, "important"

notes are still highlighted, and adding/editing/deleting a note works exactly as before. If the list ever fails to load you'll now see a clear "couldn't load — try again" message.

Behind the scenes — class enrolment list loads through the secured server

  • On a student's Membership / assessment screen, the class enrolment list and member types

now load through our secured server (same approach as the other member screens), keeping each club's data cleanly separated.

  • No change to what you see or do — your classes show in the same order, the day filter and the

enrol/edit controls work exactly as before. If the class list ever fails to load you'll see a small "couldn't load — try again" prompt.

Behind the scenes — membership details on the assessment screen

  • On a student's Membership / assessment screen, the **plan, household plan, and

family-discount details** now load through the same secured server route as the main Membership tab, keeping each club's data cleanly separated.

  • No change to what you see — the current plan, household plan panel, family-discount price and

sibling position all display exactly as before. A small "couldn't load — try again" prompt now shows if that information fails to load.

Behind the scenes — grading details on the assessment screen

  • On a student's Membership / assessment screen, the **syllabus grid, RAG scores, classes-since-

grade and belt history** now load through the same secured server route as the standalone Grading tab, keeping each club's data cleanly separated.

  • No change to what you see or do — the RAG grid, readiness percentage, rank switching, belt

history and assessor names display exactly as before, and scoring/grading actions work unchanged. A small "couldn't load — try again" prompt shows if grading info fails to load.

Settings & config changes now saved server-side (behind the scenes)

21 June 2026

What's new

Security — settings/config writes moved behind guarded server routes

Status: Pending enablement (deploys with the next release)

  • Several Settings screens used to save straight from the browser to the

database. They now go through guarded server routes that check your role, block the demo club, scope every change to your own club, and record an audit entry — the same as billing, member and automation changes already do.

  • Covered in this release: email templates (create / edit / archive /

restore / duplicate), closure dates (including the "add UK bank holidays" bulk action and calendar closures), event types, coach availability windows, and club terms.

  • Nothing changes in how these screens work for you — the same buttons save

the same things with the same results. The difference is that the server is now the authority: it sets the club, validates the input, and ignores anything it isn't expecting, so a stale browser tab or a non-admin account can't make a change it shouldn't.

  • A small hardening along the way: removing a coach availability window is now

scoped to your club on the server, so a window can only ever be removed from your own club.

Security — grades & syllabus setup now saved server-side

Status: Pending enablement (deploys with the next release)

  • The Grades, Syllabus, Requirements and Grade-types setup screens

(plus the matching onboarding steps) used to save straight from the browser. They now go through guarded server routes that check your role, block the demo club, and record an audit entry — exactly like the other settings screens.

  • Covered: belt systems / programs, grades (belt ranks), syllabus items, grade

types, and program requirements — create, edit, archive, restore, reorder, and the grading checklist/requirements configuration.

  • No change to how grading itself works — recording results, scores,

rank changes, publishing and the register are untouched. This release only moves where the *setup* of your grades and syllabus is saved.

  • The server also checks that a grade belongs to one of your own belt systems (and a

syllabus item to one of your own grades) before saving, so nothing from another club can ever be referenced.

Security — the register now saves attendance through a guarded route

Status: Pending enablement (deploys with the next release)

  • Marking the register (present / absent / late, adding or removing an ad-hoc

member) used to write to the database straight from the browser. It now goes through a guarded server route that checks your role, blocks the demo club, and confirms the class and member belong to your club before saving.

  • The register works exactly as before — same buttons, same speed, same

optimistic updates, same class-usage counting, lens/programme filtering, and trial marking (trials are saved the same way they always were). Nothing about how you take a register changes.

  • Marking is idempotent: tapping a member twice, or two coaches marking the

same member, always lands on the latest status — it can never create duplicate attendance rows (the database already enforces one row per class / member / day).

Security — assessment scores now saved through a guarded route

Status: Pending enablement (deploys with the next release)

  • Recording syllabus assessment scores (the red / amber / green taps on the

assessment grid, the student grading tab, and the membership assessment tab) used to write straight from the browser. They now go through a guarded server route that checks your role, blocks the demo club, and confirms the member and syllabus item belong to your club before saving.

  • Assessing works exactly as before — same red/amber/green taps, comments,

tapping a score again to clear it, and the same instant (optimistic) updates. Nothing about how you assess changes.

  • A score tap can only ever write a score — it can't touch a member's rank, grade,

grading result, or anything that gets published. Scoring stays cleanly separate from grading outcomes.

  • Scores are idempotent (one row per member + syllabus item): re-tapping, or two

coaches scoring the same item, always lands on the latest value — never duplicates.

Security — first-run club setup now saved through a guarded route

Status: Pending enablement (deploys with the next release)

  • The new-club setup wizard (your club name / contact / email / currency on the first

step, and the "finish setup" step) used to save straight from the browser. It now goes through a guarded server route that confirms you're signed in and only ever updates your own club, with a strict list of allowed fields — it can't be used to touch anything else about a club.

  • Setting up a new club works exactly as before — same steps, same result.
  • With this change, every sensitive write across the app now goes through a checked

server route. None of these are behaviour changes for you — they're the last pieces of a behind-the-scenes hardening pass that makes the app safer to run for multiple clubs.

Reliability — class-usage counting can no longer be over-counted on the register

Status: Pending enablement (deploys with the next release)

  • For members on a per-class or class-limited plan, the register counts how many

classes they've used. Previously the browser worked out whether a mark should add or remove a class from that count, using its own (possibly out-of-date) view of the member's last status. If two coaches marked the same member at the same moment, both could add a class — over-counting their usage.

  • Marking the register now records the attendance and adjusts the class-usage

count in one server step, worked out from the member's true saved status — so a class is counted exactly once, no matter how many coaches or taps land together. Re-tapping the same status, or switching Present ↔ Late, never changes the count; the count never drops below zero.

  • Taking a register feels exactly the same — same buttons, same speed, same

optimistic updates, the same "reached their class limit" warning. The fix is entirely behind the scenes.

Hardened API error responses (behind the scenes)

20 June 2026

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