Use cases · Classes & memberships
Fitness studio
A boutique studio running scheduled classes — spin, yoga, strength — with hard capacity, waitlists, and check-in. Members pay monthly; drop-ins buy class packs. A no-show on a packed class costs someone else a spot, so the rules around capacity, packs, and fees have to be exact.
The shape
A class is a Seldon EventSession under an EventSeries, projected through an open_capacity Availability that caps seats; a Registration is the roster spot with a waitlist, and Attendance records check-in. Membership tiers and entitlement live in Terminus; class packs are Mallow stored value; recurring dues run through Daneel + Payments.
- Seldon models the timetable as an
EventSeriesofEventSessions. Anopen_capacityAvailability enforces the seat cap;Registrationhandles booking + waitlist;Attendancerecords who actually showed. One-on-one PT uses a variable-duration grid instead. - Terminus holds members as Persons. An "Unlimited" plan is a
RankedGroup(kind=tier)with aTierDefinitionauto-enrolment rule; member-only classes gate oncheckEntitlement. - Mallow runs class packs as stored value — a 10-class pack is a
StoredValueAccount, and each booking burns one with aStoredValueTransaction. Monthly membership dues post to the same ledger. - Payments charges recurring dues on a stored credential (
MIT/ merchant-initiated), so the monthly run doesn't need the member present. - Daneel owns the recurring-billing workflow, waitlist promotion when a seat frees, and the no-show fee that fires off the Seldon
no_showemission. - Speaker sends class reminders and "a spot opened" pushes (consent-gated; the studio's operator app is an installable PWA on the push channel).
Walk-through
Book a class
A member books Saturday's 9am spin. Seldon checks the open_capacity seat cap and, because it's a member-only class, calls Terminus checkEntitlement against her Unlimited tier. Both pass; a Registration lands her on the roster.
Sell out and waitlist
The class fills. The next member to book enters the waitlist (a Registration in a queued state). When someone cancels, Daneel's waitlist-promotion moves the top of the list to confirmed and Speaker pushes "you're in" — consent permitting.
Drop-in on a class pack
A non-member books with a 10-class pack. There's no entitlement tier, so booking redeems one credit from her Mallow StoredValueAccount — a single StoredValueTransaction — and the roster spot is hers. The pack balance is now nine.
Check-in
At the door, the front desk taps her in; Seldon records Attendance against the Registration. A no-show, by contrast, leaves the Registration unattended — the Seldon no_show emission triggers a Daneel workflow that books the studio's late-cancel fee against the member.
Monthly dues
On the first, Daneel's billing workflow runs the membership roster: for each active tier member, Payments charges the stored credential merchant-initiated, Mallow posts the dues to the ledger, and a failed charge opens a dunning sub-flow rather than silently lapsing the membership.
Why this is hard without LatticeKit
Studio software usually bundles scheduling, memberships, and billing into one closed monolith — great until you want the class pack to draw from the same ledger as the retail counter, or the no-show fee to reconcile against the same invoices as dues. Here capacity, entitlement, stored value, and recurring billing are separate primitives that compose: the seat cap is Seldon's, the tier gate is Terminus's, the pack balance is Mallow's stored-value ledger, and the monthly charge is Payments' MIT path — so a refunded class credit and a failed dues charge both land in the one ledger your accountant already reads.