Changelog

What we shipped, when. Newest first.

Update — 2026-06-29

29 June 2026

2026-06-29

Booking Status for gradings

The grading event screen has a new Booking Status button, sitting next to Belts required in the Print & prep group. It opens a calm, scannable view of how your grading is filling up — per grade, how many students you've invited versus how many have actually booked, with running totals at the bottom.

  • Expand any grade with the chevron to see the underlying students, their status

(Booked, Invited, Waitlisted or Cancelled) and when they were invited.

  • Resend an invite to a student who hasn't booked yet — it goes out only after the

server confirms, so you never get a false "sent".

  • Cancel a booking that has no payment attached, straight from the row (with a

confirmation prompt). Paid bookings are intentionally left to the event screen so a cancellation never triggers a refund from here.

Permissions tightened along the way: resending an invite now needs event-booking permission (instructor and up), and the staff cancel action needs the event-financial permission (admin and up — it can issue refunds). Members cancelling their own booking via their personal link are unaffected.

It's read-only data pulled together on the server and scoped to your club — nothing about inviting, booking, cancelling or payments has changed; this just makes the invited-vs-booked picture easy to see at a glance while you prep for grading day.

Grade chips on linked events

Each linked event in a grading group now shows small belt/grade chips for the grades that event is intended for (from the event type's grade range) — so you can see at a glance which ranks each linked event covers without opening it. Two-tone belts show their real stripe, a long list collapses to +N more (hover for the full list), and an event with no grade filter shows a quiet All grades. Display-only, derived on the server and scoped to your club.

Update — 2026-06-28

28 June 2026

2026-06-28

One Comms Centre

The communications areas now share one navigation so they read as a single Comms Centre instead of separate pages. The same row of sections — Messages · Templates · Automations · Comms Map · Deliverability — appears across the area with your current spot highlighted, so it's always clear where to go to:

  • Messages — send a one-off email, SMS or Telegram (the composer, renamed from

"Comms").

  • Templates — your reusable email/SMS/Telegram messages.
  • Automations — build triggers and check what ran, is queued, or failed. This

area now sits inside the Comms Centre rather than off on its own.

  • Comms Map — see every trigger and what's wired to it.
  • Deliverability — check your email/SMS/Telegram is landing.

SMS Gateway and the advanced email options (Skins, Snippets, Template Matrix) stay in Settings and are linked from where you need them. Nothing about sending, automations or provider setup has changed — this is purely making the area easier to move around.

Automate around Video Review

The Automations builder now has Video Review triggers, so you can set up emails, SMS or Telegram messages to fire when:

  • a member is granted or has revoked Video Review access,
  • a member submits a video,
  • a coach reviews one, or
  • a clip is flagged.

Each trigger comes with Video Review merge tags (syllabus item, score, feedback, status, and more). Automations are a side effect only — if one fails it never stops the actual grant, upload or review.

Automations now live in one place

Building automations has moved fully into the Automations area. The old Settings → Automations tab has been retired — opening it now shows a short notice pointing you to the new home (and the migration console for bringing old rules across). Any automation rules you already set up keep running exactly as before; nothing has been turned off.

Voice Notes has been retired

Voice Notes is no longer an active feature. It's been removed from the sidebar, and new voice notes, audio uploads, pasted transcripts, and class recordings can no longer be created. Any notes and audio you already have remain fully viewable — open /voice-notes directly to review them. Nothing has been deleted.

Event cards now show invited *and* booked

Event cards in the calendar's day view now read "X invited · Y booked" (e.g. *8 invited · 3 booked / 20*), so you can see take-up at a glance — how many you invited versus how many have actually booked — without opening the event.

"Classes attended since last grading" now matches everywhere

The blue ATT count on the Assessment grid was under-counting — it only counted classes tagged to that belt system and skipped untagged or no-lesson attendance. It now counts all attended classes since the student's last grading, using the exact same calculation as the Grading page, so the two screens always agree.

No more dashboard "flash" when pages load

Navigating to Automations — or opening a public link like a trial booking — no longer briefly flashes the dashboard layout while the page loads. Public pages now show a clean Allsorted-branded loader, and each staff section shows its own section shell. Links from staff pages into public flows (add a student) now load the public page fresh, without the staff frame wrapping it.

Automations: a better Email & Telegram step

Building an email step now starts with a clear choice:

  • Use a template — pick a saved email template, then preview it to confirm it's the

right one before saving.

  • Create new — the same editor as the Communications composer: merge-tag picker

(showing only tags that resolve for the trigger), visual/HTML editing, and a live preview.

Telegram steps gain a "Notify club owner" option — tick it to also send the message to the club's admin Telegram recipients.

Automations email/Telegram step — follow-ups

  • Create-email "Preview text" now works. The preheader (inbox snippet) field in the

embedded composer is wired end-to-end, so you can type into it and it's sent as the email's preview text.

  • Telegram "who gets this" choice. A Telegram step can now send to: the member only;

the member *and* notify the club owner; or only notify the club owner / admins — for alerts (e.g. trial bookings) where the member shouldn't receive anything. Owner/admin notifications go to your club's Telegram admin recipients and are production-gated.

Automations: Discard a draft you didn't mean to keep

Building a new automation creates a draft as soon as you start. There's now a Discard button in the builder (both Simple and Advanced) — it deletes the draft and takes you back to the list, so you don't leave behind an automation you never finished. It's only offered for never-published drafts; anything with run history or a previous publish must be Archived instead (so its history is preserved).

Fix: grading results can't be published before outcomes are confirmed

When the grading review/confirm flow is on, recording an outcome creates a DRAFT — the rank, history and certificate side-effects only apply when you Confirm. Publishing now checks for confirmation, not just "an outcome exists", so draft outcomes can no longer be published before they're confirmed. (Clubs without the confirm flow are unaffected.)

Fix: SMS & Telegram automations send the right message

An SMS or Telegram automation step that used a saved template was rendering the template's EMAIL body instead of its SMS/Telegram text — risking blank or wrong sends. SMS now uses the template's SMS text and Telegram uses its Telegram text.

Automations: send yourself a test of any message step

Each Email, SMS and Telegram step in the automation builder now has a "Send a test" box at the bottom — type a recipient (email/mobile) and send the actual message with sample data filled in, so you can check it renders before going live. Telegram tests go to your club's admin Telegram recipients. It tests the real content — whether the step uses a saved template or your own text — so what you see is what your members would get.

Automations builder: cleaner list, view-and-edit, and a History link

  • The automations list no longer has a per-row "send test" button (it sent to a fixed address

and wasn't useful) — use the per-step "Send a test" while building, or the end-to-end test in Settings → Automation Enablement.

  • Opening a published trigger now shows it in the builder straight away (no "create a draft to

edit" step) — just make a change and Save, and it creates the draft for you, leaving the live version untouched until you publish.

  • Each trigger now has a "History" link to its recent send activity.

Saves you can trust — no more "looks saved but wasn't

27 June 2026

What's new

Things that look saved really are saved

A reliability pass across the app so the screen never tells you something worked unless it actually did:

  • Register — adding a walk-in. If adding a student to a register doesn't go through (locked register,

weak signal, a future date), the row now rolls back and you get a clear message — instead of a student who looks added but was never saved. Walk-ins still don't count against class limits.

  • Student notes. Adding, editing, or deleting an internal note is now handled by our secured server.

If a save fails, your typed text, your edit, or the note itself stays put with a clear message — nothing silently disappears.

  • Video reviews. A submission is only ever marked "reviewed" once the score is safely recorded, so a

green/amber/red can't go missing while the submission looks done.

  • Closure notifications. Closures added from the calendar now actually notify affected members

(previously only the Settings → Closures path did) — within 14 days they queue a *lesson cancelled* message per affected member. The confirmation says notifications are *queued for affected members* rather than implying guaranteed delivery.

Student Profile → Billing tab no longer breaks on older records

The membership tab could show "We couldn't load this membership information" if a single background detail failed to load. It now shows everything it can and a gentle note about the rest, instead of hiding the whole tab.

Events can't be saved with impossible dates

Creating or editing an event now blocks date combinations that don't make sense — an end before the start, a booking cut-off after the event has started, or an early-bird deadline after the cut-off. You get a clear message and the save is prevented (on the form and on the server), so links can't go out with a cut-off in the past. Existing events are untouched.

Dialogs no longer hide behind the menu

Groundwork to stop pop-up dialogs ever appearing *behind* the side menu or student list: shared dialogs now render above everything on a consistent layering scale.

Automations — "Save draft" works again, and the builder is tidier

  • Fixed: saving a Communications Trigger draft was failing silently (a 405 error) — it now saves

reliably in both the simple and advanced builders. Existing published triggers were unaffected.

  • The trigger builder is now a focused workspace — the section nav pills are hidden while you're

editing, so it doesn't feel like another settings page.

  • Picking when a trigger fires uses clear, scannable cards instead of a dropdown — now with a

search box and category filter pills so the right trigger is quick to find as the list grows. Choosing what it does (Email / SMS / Telegram / Delay) uses matching cards.

  • The right-hand flow summary is restyled as an obvious view-only preview (it no longer looks editable).
  • The builder title now updates live as you rename a trigger — no more stale "Untitled trigger" while

you're editing.

Safer refunds when a paid competition/event entry is cancelled

Cancelling a paid external-event entry is now protected against accidental duplicate refunds: a double-click, page refresh, or network retry can no longer create a second Stripe refund or double-count the refund on a shared (bundled) invoice — the refund is keyed so it happens exactly once. Partial refunds on bundled invoices and paired-entry cancellations are unchanged, and if a refund fails you now get a clear message and the entry is not marked cancelled.

Automations made simpler

The Automations area is now organised around three clear places instead of six engine-flavoured tabs: Build (make and manage your automations — the main screen), Activity (what ran, what's queued and anything that failed, now grouped together), and Settings (safety, sending state, Trigger.dev status, test recipients and any legacy-rule conflict warnings). Opening Automations now lands you on Build. None of the sending behaviour changed — this is purely how it's laid out and labelled.

Calendar week view now reads in time order

In week view, classes and events are now listed together in time order — a 9am event shows above a 6pm class, instead of all classes first then all events. Colours, trial markers, venue/location and click behaviour are unchanged. The day pop-out also scrolls properly now on desktop and mobile (no more cramped/stuck scrolling), with the date header and "Add event" button staying put.

Calendar: a proper full-page day view

Clicking a day in the calendar now opens a dedicated day page (/calendar/day/…) instead of the cramped slide-over, so it scrolls normally on desktop and mobile, has a clear Back to calendar button, and gives classes, events, trials and bookings real room. The day list is in time order, and add/edit/ cancel events, trials, invites and bookings work exactly as before. (Deep-linkable too — you can bookmark a specific day.)

Automations: archive, steadier tables, categories & a Templates home

  • Archive a trigger or flow instead of deleting it. Archived automations stop

running but keep every version, run and delivery record, and you can restore them anytime (they come back as a draft to re-publish). A new Archived view lists them. Drafts that were never published and have no history can be Discarded outright. Archiving and discarding are owner/admin-only and fully audited.

  • Tidier tables everywhere in Automations — long trigger names, error messages,

recipient addresses, provider IDs and cron routes no longer stretch or wrap the columns; they truncate with the full value on hover, and tables scroll sideways on small screens instead of crushing. Status, type, channel, version, date and action columns stay on one line.

  • Categories on the Build list — quick category chips (Membership, Payments,

Trials, Events…) plus a small category tag on each row, and search now matches the category too.

  • Templates under Automations — the message templates your automations send now

have a home right next to Build, alongside the existing Settings location.

A clearer Comms Centre

The communications area now hangs together as a Comms Centre: from the message composer you can jump straight to Templates and Deliverability, which now have their own pages alongside Comms, Automations and the Comms Map — all reusing the same panels you already knew from Settings (Settings keeps them too, so nothing moved out from under you). Email templates are much easier to find from the comms area.

In Automations → Build, each trigger now has a tidy ⋯ More menu to Archive it (it stops running but keeps its history) or Discard an unpublished draft, with an Archived view to restore from. Nothing about how messages send has changed.

Fix: archived legacy automations no longer block new triggers

Archiving a legacy automation in Settings now fully retires it — the new Communications Triggers area no longer flags it as a conflict, and it can never make a builder trigger defer. (The legacy guard now ignores archived rules, and archiving also disables the rule.) No change to how anything sends.

Automation builder: club + member merge tags now resolve

Builder-trigger emails can now use the club and member personalisation tags — {{club_name}}, {{club_logo_url}}, {{club_email}}, {{club_contact}}, plus {{belt_rank}}, {{belt_system}}, {{membership_plan}}, {{mobile}}, {{household_name}}, {{age}} and more — not just the recipient name + each trigger's own tags. The builder's tag picker now offers exactly the tags that will resolve for the selected trigger (so no more tags that render as literal {{…}} text). No change to who is emailed or whether — only what the message can say.

Domain-proof email logos (inline/CID embedding)

For gold-standard multi-tenant deliverability: the club logo can now be embedded directly in each email as an inline (CID) attachment instead of linking to an external image URL. With no external image, there's nothing to mismatch the sending domain — so the "host images on your sending domain" warning can't apply, no matter which domain a club sends from. Behind a flag (EMAIL_INLINE_IMAGES, off by default) and fully fail-safe: if the logo can't be embedded for any reason, the email still sends exactly as before with the logo as a normal image. The in-app "view email" preview keeps the image URL so it still renders in the dashboard.

Fix: no more duplicate booking/automation confirmations

When a club publishes a Communications Trigger for an event (e.g. event booked), the legacy automation engine's built-in default email no longer also fires — so members get ONE confirmation, not two. The legacy default now stands aside whenever a live builder trigger covers the event; clubs that haven't built a trigger keep their default as before.

Automations Activity: see a preview of what was sent

Each delivery row in a run's detail now shows a short preview of the message that went out, so you can tell at a glance what was sent. The full rendered email remains in Communications history.

Cleaner, honest automation merge tags

One canonical merge-tag registry now drives the automation builder, the email-template editor, previews, and docs — so every tag a club is offered genuinely fills in.

  • Builder pickers only show tags that resolve for the chosen trigger. Member details

(belt, plan, etc.) are no longer offered on trial/waiting-list triggers, where there's no member record yet — they'd otherwise have shown up blank.

  • Event automations got the full event pack. An "Event booked" automation can now use

{{event_time}}, {{event_end_time}}, {{event_location}}, {{event_cost}}, {{earlybird_price}}, {{earlybird_deadline}}, {{booking_cutoff}}, {{cancel_link}} and {{invoice_pdf_url}} — the same details the confirmation email already used.

  • Unknown-tag warning in the template editor. If a template uses a tag that won't fill in

(a typo, or a tag that doesn't apply to automations), the editor flags it — without blocking your save.

  • New "Automation tags" reference doc; nothing about how emails actually send has changed.

Paid event bookings are now self-healing after payment

26 June 2026

What's new

More payment flows are now self-healing after a successful payment

  • The same protection that makes paid event bookings recoverable now covers insurance renewals,

waitlist "claim your spot" payments, and external-event entries. If a parent's device drops the connection right after their card is charged, our Stripe safety net finishes the job automatically — the renewal is recorded, the waitlist spot is promoted (or refunded if the event filled in the meantime), and competition entries are confirmed and locked.

  • These public payment pages now never show a "failed / try again" message after a payment has

actually gone through. Instead they show a reassuring "Payment received — we're confirming this automatically" message with a payment reference, so no one is ever prompted to pay twice.

  • A grading/event booking link now refuses to start a second charge if that place is already

booked or paid for.

Staff can confirm an invited student straight onto the booked list

  • On an event's invite list, staff now have a "Confirm" action: it adds the invited student

directly to the booked list without the parent needing to use the public booking link.

  • A confirmation prompt makes the money state obvious — for paid events it warns that *payment

will remain unpaid/pending unless you collect it separately*. It never marks a booking as paid unless a real payment exists.

  • It's safe to click more than once (already-booked is a no-op), respects event capacity (a full event

adds them to the waitlist, and promotes a waitlisted student only if a place is free), and only ever sends one confirmation. Owners/admins can use it; it's blocked in demo mode.

Paid event/grading bookings can no longer "fail" after a successful payment

  • Previously, if the booking step hiccuped *after* a card payment had gone through (a dropped

connection, the page closing), the parent could see a scary "Booking failed" message even though the money had been taken.

  • Now a successful payment is always recoverable. The booking is confirmed by our secured server,

and a Stripe safety net finishes the job automatically even if the parent's device never completes the flow. The confirmation step is idempotent, so retries can never double-book or double-charge.

  • If for any reason the booking can't be confirmed instantly, the parent sees a reassuring **"Payment

received — we're confirming your booking automatically"** message with a payment reference, instead of an error.

  • A booking link can now only ever create one Stripe payment, even if it's opened on two devices.

_Behind the scenes: a shared reconcilePaidEventBooking path is now used by both the payment-confirm route and the Stripe webhook; if an event fills up between the invite and payment, the booking is kept as waitlisted + paid (unchanged behaviour) for staff to promote or refund._

Member data is loaded through our secured server — everywhere

A privacy/data-protection pass: every screen that lists members — including the grading panel roster — now loads names, dates of birth and grade info through our secured server with the club checked on every request, instead of the browser reading the database directly. Nothing changes in how the screens look or work; the data just takes a safer path. (This completes the work so that no member list is read directly by the browser anymore.)

Grading results: tighter controls

  • Recording a grading outcome (pass / late / no-show / unsuccessful) now requires a coach or above

view-only accounts can no longer record results.

  • Grading promotions are being moved so the server decides and validates the awarded grade (you

can't promote a member sideways, backwards, into the wrong belt system, or skip grades unless an examiner deliberately chooses a different belt). The double-promotion option on the panel is unchanged. _(This stronger validation switches on with a database update; until then the existing checks stay in place.)_

  • New: a review-and-confirm step for grading results is being introduced behind a per-club setting (off by

default — nothing changes for your club until it's switched on). When it's on, marking results saves them as drafts; each member shows a status (Draft / Ready / Needs attention / Confirmed / Published); and a Review promotions screen lets an admin see each "current grade → new grade", spot any blocked awards, and Confirm them all at once. After confirming, a change goes through an audited correction (reason required) rather than a silent undo. Publishing and certificates are unchanged for now.

Event booking cut-off dates are checked as you type

The booking cut-off on the event form now validates immediately instead of only when you hit Save:

  • The field shows a friendly inline error the moment a date is out of range, and Save is disabled until

it's fixed — no more typing a whole event then getting rejected on Save.

  • The rules are now clearer and consistent: the cut-off must be on or before the event date, can't be

before today on a new event, and can't be before the date the event was created when you edit one.

  • Move an event's date earlier than its cut-off and the cut-off field highlights so you can correct it.
  • The form also now loads the existing cut-off when you edit an event (it previously didn't show it).
  • Older events with an invalid cut-off still open normally, but you'll be asked to fix the cut-off before

saving any change. The server enforces the exact same rules, so nothing slips through.

Behind the scenes — Progression, Membership and Student Analytics reports now fetch through our secured server

25 June 2026

What's new

Behind the scenes — Settings tabs now fetch their member data through our secured server

  • The Settings tabs that show member-impact info — the Grades & Programs archive warnings ("N

members are on this"), the Schedule Insights capacity planner, and the Closed Dates conflict previews (which trials/regulars a closure affects) — now load that data through our secured server, with your club always taken from your signed-in session.

  • Everything is unchanged: same counts, warnings, capacity figures and conflict lists. The archive

warnings now receive only a count (no member details at all), and member contact details are no longer read directly by the browser. Purely a security/hardening change.

Behind the scenes — the calendar's trial lists and event invites now fetch through our secured server

  • The calendar trial views — the day-detail panel, the Trials list, the calendar trial counts, the

closure-conflict check, and the event-invite student search — now load their data through our secured server, with your club always taken from your signed-in session.

  • Everything behaves exactly as before: same trials, dates, statuses, counts, ordering and search

results. Trial contact details (and members' dates of birth, except where the "convert to student" step genuinely needs them) are no longer read directly by the browser. Purely a security/hardening change.

Behind the scenes — search, the dashboard activity feed and the staff inbox now fetch through our secured server

  • The ⌘K command palette search index, the dashboard's Recent Activity feed, and the **staff

action inbox** now load their member data through our secured server, with your club always taken from your signed-in session.

  • Everything looks and works the same — same search results, labels, ordering and inbox items. Member

contact details and SMS message text are no longer read directly by the browser. Purely a security/hardening change.

Behind the scenes — the Student Analytics report now fetches its students through our secured server

  • The Student Analytics report (age/grade/tenure distributions, attendance alerts, promotion

analytics, timetable utilisation and the top-attenders/overdue tables) now pulls its student roster through our secured server, with the club always taken from your signed-in session.

  • Members' dates of birth no longer leave the server for this report. The age groups and ages it

shows are now worked out server-side and only the age (and age band) are sent to your browser — the raw date of birth stays put. Every figure, chart bucket and the programme-lens behaviour are identical; only where the date of birth is handled changed. A privacy/data-minimisation improvement.

Behind the scenes — the Progression report now fetches its members through our secured server

  • The Progression report (rank distribution, promotions, grading pass rate, the per-event

breakdown and the overdue-for-grading list) now pulls its student roster through our secured server instead of reading it directly in your browser. The club + permission checks live on the server, and your club is always determined from your signed-in session.

  • Nothing on the report changes — every count, label, colour and the programme-lens filter behave

exactly as before. This is purely a security/hardening change.

Behind the scenes — the Membership report now fetches its members through our secured server

  • The Membership report (active/joiner/leaver/retention stats, plan and syllabus distribution,

the plan-breakdown revenue table and the joiners-vs-leavers charts) now pulls its student roster and its household-membership records through our secured server, with the club always taken from your signed-in session.

  • Every figure is identical — including Total Monthly Revenue and the per-plan revenue column.

The revenue calculation itself is unchanged; we only moved where the member and household lists are read from. Purely a security/hardening change.