Workflow 1: Booking Validation and Confirmation
Trigger. Any booking attempt, from the Class Booking Widget, from BO by SMS or chat, or from the front desk.
Conditions and branches. Validation runs in this order, and the first failure stops the booking.
- Restriction check. If booking-restricted is applied and Booking Restricted Until is in the future, refuse with: “Bookings are paused on your account until [date] because of [n] missed classes in the last month. If that is not right, reply APPEAL and [Override Person] will look at it today.”
- Entitlement check. If the class type is not in Entitled Class Types, refuse and offer the classes they can book.
- Credits check. If Class Credits Remaining is zero on a pack-based membership, refuse and route to the front desk. Never let BO sell the top-up.
- Hold limit check. If Concurrent Bookings Held is at the limit, refuse with: “You are holding [n] classes already, which is the maximum. Cancel one and I will book this straight away.”
- Capacity check. If places remaining is zero, do not refuse: route to Workflow 2 and join the waitlist. This is the most important branch in the build.
- Booking window check. If the class starts in under 30 minutes, refuse and suggest the next instance.
Actions in order, on a valid booking.
- Create the booking with Attendance Status Booked, write Class Type, Class Start, Coach and Booking Source.
- Increment Concurrent Bookings Held. Decrement Class Credits Remaining if applicable.
- Decrement the calendar's remaining places.
- Send the confirmation SMS immediately: “Booked: [Class Type], [day] [time], with [Coach]. Free cancellation until [actual cutoff time]. Cancel here: [link]” Note the cutoff as a real clock time, not “4 hours before”; members misread the relative version constantly.
- If first-time-booker, send the orientation email as well: where to park, what to bring, arrive 10 minutes early, the coach's name and photo.
- Schedule the reminder sequence: email 24 hours before with a cancel link, SMS 2 hours before with a cancel link.
- If this booking took the class to capacity, update the widget state so the next visitor sees waitlist mode rather than a disabled button.
- If this booking took the class from below to at or above the minimum viable attendance, cancel any pending low-attendance workflow for that instance.
Stop and exit. Exits on confirmation, on refusal, or on the member abandoning. Every refusal path offers an alternative rather than ending in a dead stop.
Workflow 2: Waitlist Join and Queue Management
Trigger. A booking attempt into a class at capacity, or a direct Waitlist Join submission.
Conditions and branches.
- Run the same restriction, entitlement and credits checks as Workflow 1. A restricted member cannot join a waitlist either.
- If the member is already on this class instance's waitlist, confirm their existing position rather than creating a duplicate entry.
- If the member already has a confirmed booking for a class overlapping this one, warn before adding: “You are already booked into [other class] at that time. Want me to waitlist you for this and cancel the other if it comes through?”
- If the waitlist is longer than twice the class capacity, say so honestly and suggest an alternative instance instead. A position of 26 is not a waitlist, it is a disappointment with a delay on it.
Actions in order.
- Create a Waitlist Management opportunity at Waitlisted, with the class instance, the timestamp and the queue position calculated from existing entries.
- Apply waitlist-active.
- Do not decrement Class Credits Remaining or increment Concurrent Bookings Held. A waitlist place costs nothing until it converts.
- SMS: “You are [position] on the waitlist for [Class Type] [day] [time]. If a place opens I will text you and you will have a short window to confirm. Reply SWAP if you would rather look at another class.”
- Offer the nearest alternative with space in the same message where one exists within 24 hours of the requested time.
- On SWAP, hand to BO to find and book an alternative, and remove the waitlist entry.
- Four hours before class start, if still at Waitlisted, send one honest message: “Still [position] on the waitlist for tonight and it is unlikely to open up now. [Alternative class] has space if you want it: [link]”
- At class start, move any remaining entries to Class Passed and remove waitlist-active if the member has no other live waitlist entries.
- Nightly, recalculate Waitlist Expired Count over the rolling 30 days and apply or remove waitlist-no-response at the threshold of 2.
Stop and exit. Exits on promotion (Workflow 3), on SWAP, on the member leaving the waitlist, or at class start.
Workflow 3: Waitlist Promotion
Trigger. A place becomes available on a class with a non-empty waitlist: a member cancels, a booking is canceled by the policy workflow, or capacity is increased by staff.
Conditions and branches.
- Queue order. Offer to the lowest position first, except that anyone carrying waitlist-no-response is moved behind those without it. Fairness to the people who do respond beats strict first-come ordering.
- Response window branch. If the class starts in more than 4 hours, the window is 30 minutes. If it starts in 4 hours or less, the window is 15 minutes. If it starts in under 90 minutes, offer to the top three simultaneously on a first-reply-wins basis and say so explicitly in the message: sequential offers cannot fill a slot that close to start.
- Quiet hours branch. If the promotion would send before 07:00, hold it until 07:00 and shorten the window accordingly. If the class starts before 08:00 and the promotion could not be sent in time, auto-decline the remaining queue and notify the coach that the class is running one short.
- Skip conditions. Skip anyone now restricted, out of credits, or holding a conflicting booking.
Actions in order.
- Select the next eligible member. Move their opportunity to Offered, stamp Promotion Offered At.
- Send SMS immediately: “A place has opened in [Class Type] [day] [time]. Reply YES in the next [window] minutes and it is yours. Reply NO and I will pass it on.” Send a parallel push notification if an app exists.
- Start the response timer.
- On YES: create the booking through Workflow 1's action block with Booking Source Waitlist Promotion and Waitlist Position At Booking set to their original position. Move the opportunity to Confirmed, increment Waitlist Conversion Count, write Promotion Response as Accepted, re-number the remaining queue, and send the standard confirmation with the cutoff time.
- On NO: move to Declined, write Promotion Response as Declined, and offer the place to the next in queue within seconds. A decline is a gift. Thank them for it: “No problem, thanks for the quick reply.”
- On window expiry: move to Expired, increment Waitlist Expired Count, write Promotion Response as No Response, send “The place has gone to the next person on the list. You are still on the waitlist for future openings.” and offer the place to the next in queue.
- Repeat down the queue until the place is filled or the queue is exhausted.
- If the queue is exhausted and the place is still open, release it to the public booking widget and, if the class is within 24 hours and below minimum viable attendance, hand to Workflow 6's fill campaign.
- Log every promotion, response and timing to the reporting layer. The response-window setting should be tuned on this data after a month, not guessed twice.
Stop and exit. Exits when the place is filled, when the queue is exhausted, or at class start. Exits immediately if the original canceling member rebooks inside the offer window. In which case the offer is withdrawn with an apology and the member goes back to position 1 with priority on the next opening.
Workflow 4: Cancellation Handling
Trigger. Submission of the Cancellation Form, a cancel link tap in a reminder, or a cancellation instruction handled by BO.
Conditions and branches.
- In-window branch. More than 4 hours before class start. Free cancellation.
- Late branch. 4 hours or less before start. Counts as a strike.
- Studio cancellation branch. Staff canceling the class itself. Never counts against any member, and triggers a different message entirely.
- Keyword disambiguation. If the instruction arrived as bare CANCEL by SMS, treat it as the global opt-out keyword and process the opt-out, then reply explaining how to cancel a class instead. If it arrived with a class reference, or as a reply to a specific reminder, treat it as a booking cancellation and confirm which class before acting.
In-window actions.
- Set Attendance Status to Canceled In Window.
- Decrement Concurrent Bookings Held, restore Class Credits Remaining if applicable, increment the calendar's remaining places.
- Fire Workflow 3 immediately. Speed here is the whole value of the waitlist.
- SMS: “Canceled: [Class Type] [day] [time]. No charge, credit back on your account. Want me to find you another slot this week?”
- If the member has canceled 3 or more times in window in 30 days, notify the front desk quietly. Not a strike and not a message to the member, but worth a human noticing.
Late branch actions.
- Show the consequence before confirming: “This is inside the [cutoff] window, so it will count as a late cancellation. Still want to cancel?” Require an explicit confirmation.
- On confirmation, set Attendance Status to Canceled Late, increment Late Cancel Count 30 Days, recalculate Total Strikes 30 Days.
- Release the place and fire Workflow 3 with the short response window.
- Hand to Workflow 5 for the strike messaging, so the policy copy lives in one place only.
- Do not charge anything automatically unless your published terms provide for it and the member agreed to those terms.
Studio cancellation actions.
- Set every booking on the instance to Canceled By Studio. No strikes, no credit consumption, credits restored.
- SMS every booked member and every waitlisted member immediately: “Sorry: tonight's [Class Type] is canceled. [Reason in one short clause]. Your credit is back. [Alternative class] has space if you want it: [link]”
- Post to #class-ops and notify the coach.
- Open a Staff Cover request first where the cause is coach illness, and only cancel if cover cannot be found within the configured window.
- 24 hours later, send one follow-up to everyone affected offering help rebooking. Studio-caused disruption is worth over-serving.
Stop and exit. Exits once the cancellation is processed and the waitlist has been fired.
Workflow 5: Attendance Reconciliation and No-Show Policy
Trigger. Scheduled, 90 minutes after every class start. Also triggered by the check-in webhook for the positive case.
Conditions and branches.
- Attended. A check-in event matched the booking.
- No show. Booking still at Booked, no check-in, class has passed.
- Reporting-only mode. A build-level switch that records strikes but sends no member messaging and applies no restrictions. Run this for the first two weeks, always.
- Reliability branch. If the member carries booking-reliable and this is their first strike in the window, record it but send the gentler first-strike copy and do not count it toward restriction. Ten consecutive attendances buys one benefit of the doubt.
- Appeal branch. If appeal-open is applied, record the event but take no action and send nothing.
Attended actions.
- Set Attendance Status to Attended, write Last Class Attended, reset Days Since Last Class.
- Increment Attendance Streak. At 10, apply booking-reliable.
- Decrement Concurrent Bookings Held.
- Recalculate Preferred Class Types and Preferred Times, and the class-favorite- tags.
- If this was a first class with a new coach or class type, wait 3 hours and send the one-question Class Feedback.
- At a streak of 25, send a short recognition message. No gimmicks, no badges: “25 classes in a row booked and attended. Genuinely impressive consistency.”
No-show actions.
- Set Attendance Status to No Show, reset Attendance Streak to zero, remove booking-reliable.
- Increment No Show Count 30 Days, recalculate Total Strikes 30 Days, decrement Concurrent Bookings Held.
- Create an Attendance Exceptions opportunity at No Show Recorded.
- Strike 1: apply strike-1. Wait 1 hour, then SMS: “Missed you at [Class Type] tonight. No issue at all. Just a heads up that canceling more than [cutoff] ahead frees the place for someone on the waitlist. Three missed in a month pauses bookings for a week.” Informational, not punitive.
- Strike 2: apply strike-2, move the opportunity to Warning Sent. Wait 1 hour, then SMS: “That is 2 missed classes in 30 days. One more pauses bookings for 7 days. If something is making classes hard to get to, reply and we will sort it. That is a genuinely better outcome than a pause.”
- Strike 3: apply strike-3 and booking-restricted, write Booking Restricted Until as today plus 7 days, increment Restriction Count Lifetime, move the opportunity to Restriction Applied.
- Cancel every forward booking the member holds, and fire Workflow 3 on each released place. This is where the policy pays for itself.
- SMS: “Bookings are paused on your account until [date]: 3 missed classes in 30 days. Your forward bookings have been released. If any of those were wrong, reply APPEAL and [Override Person] will look at it today.”
- Notify the front desk and #class-ops.
- If Restriction Count Lifetime is 2 or more, do not send the automated message. Create a task for the front desk to call instead. A second restriction is a retention conversation.
- On APPEAL or Strike Appeal form submission: apply appeal-open, suspend all policy automation for that member, route to the Override Person with every strike record attached, and reply “Passed to [Override Person], who will look at it today and come back to you.” Nothing else.
- On a strike being cleared: decrement the relevant counter, recalculate Total Strikes 30 Days, remove the matching strike tag, and if Total Strikes falls below 3 remove booking-restricted, clear Booking Restricted Until, move to Restriction Lifted, and send a short, unhedged confirmation.
- Nightly, recalculate both 30-day counters on the rolling window, drop expired strikes, and lift any restriction whose date has passed with a message: “Bookings are open again on your account. [link]”
Stop and exit. Runs per class instance. The strike ladder exits on an appeal, on a cleared strike, or on the rolling window dropping the event.
Workflow 6: Low Attendance Fill Campaign
Trigger. Scheduled, every 2 hours. Selects class instances starting in the next 48 hours whose booked count is below the minimum viable attendance set for that class type.
Conditions and branches.
- Branch A: 24–48 hours out. Soft fill: one targeted message to the most likely segment.
- Branch B: 4–24 hours out. Broader fill plus a decision prompt to the studio manager on whether to run or cancel.
- Branch C: under 4 hours. No campaign. Notify the coach and the manager with the final count and let them decide.
- Exclude members already booked that day, members with booking-restricted, members out of credits, and members at the hold limit. A fill message to someone who cannot book is pure irritation.
- Cap fill-campaign messages at one per member per week. This is marketing messaging and needs Marketing Consent, not just SMS Consent.
Branch A actions.
- Post to #class-ops: “[Class Type] [day] [time] has [n] booked against a minimum of [m]. Fill campaign going out to [segment size] members.”
- Select members carrying the matching class-favorite- tag whose Preferred Times overlap the slot.
- SMS: “Space in [day]'s [time] [Class Type] if you fancy it: quiet one, good session for working on form. [booking link]”
- Wait 6 hours. If still below minimum, widen the segment to all members with the matching time preference regardless of class type and send the same message with the class described.
Branch B actions.
- Send to the widened segment immediately if Branch A has not already covered them.
- Create a decision task for the studio manager at the 12-hour mark: run, cancel, or merge with an adjacent class.
- If the manager chooses cancel, hand to Workflow 4's studio-cancellation branch, which handles the member messaging properly rather than leaving it to a coach's group text.
- If the manager chooses merge, notify every booked member with the new time and require a confirmation reply, treating non-confirmers as cancellations with no strike.
Stop and exit. Exits when booked count reaches the minimum, when the manager decides, or at class start.
Workflow 7: Reminder, Swap and Member Self-Service
Trigger. Booking confirmed (schedules the reminders), plus inbound member messages handled by BO.
Conditions and branches.
- Suppress the 2-hour SMS reminder if the member has already checked in, early arrivals exist and a reminder after arrival reads as sloppy.
- If the member has do-not-contact, send transactional reminders only where your rules allow and nothing else.
- Branch BO's handling by intent: availability question, book, cancel, swap, waitlist position, credits balance, policy question, or escalate.
Reminder actions.
- 24 hours before: email with class, time, coach, address, what to bring, and a cancel link.
- 2 hours before: SMS with time, coach and a cancel link. Keep it under two lines.
- If the class is a member's first ever, add a 12-hour-before SMS with the arrival instruction: “Come 10 minutes early tomorrow and ask for [Coach]. They will show you where everything is.”
- 30 minutes after class start with no check-in and no cancellation, send nothing. The reconciliation workflow handles it at 90 minutes; a mid-class “where are you” message is intrusive and often wrong.
Swap actions.
- On a swap request, BO identifies the current booking and the desired alternative.
- Check capacity on the target. If space exists, book the new class first, then cancel the old one. Order matters, canceling first can lose both places to a waitlist in the seconds between.
- If the target is full, offer the waitlist on the target while keeping the existing booking: “[Target] is full: I have put you 2nd on the waitlist and kept your [existing class] booking. If the swap comes through I will cancel the other one.”
- If the original class starts within the cancellation cutoff, warn that the swap will count as a late cancellation before doing anything, and require confirmation.
Self-service actions.
- Availability questions: answer with real remaining places and offer to book in the same message. Never answer with a link alone when the answer is known.
- Waitlist position: state the position and the honest likelihood based on historical promotion rates for that class instance pattern.
- Credits balance: state the number and the expiry date. Route any top-up to the front desk.
- Policy questions: answer in plain language with the actual cutoff times and strike counts, and link to the published policy.
- Anything about money, injury, membership cancellation, or a disputed strike: escalate per the guardrails, same day.
Stop and exit. Reminders exit at class start or on cancellation. BO's handling exits on resolution or escalation.
Workflow 8: Weekly Capacity Review and Timetable Intelligence
Trigger. Scheduled, Mondays at 07:00.
Conditions and branches. The digest always sends. Separate branches fire for persistent over-demand and persistent under-demand.
Digest actions.
- Calculate per class instance for the previous week: capacity, booked, attended, no-shows, late cancellations, waitlist length at peak, waitlist conversions.
- Compute utilization as attended divided by capacity, and the gap between booked and attended, which is the no-show cost in places.
- List the five most over-subscribed slots by peak waitlist length, and the five most under-subscribed by utilization.
- Summarize strike activity: new strikes, restrictions applied, appeals raised, strikes cleared.
- Summarize waitlist performance: offers made, accepted, declined, expired, and median response time.
- Email the studio manager and post to #class-ops.
- Include the week's Timetable Request submissions verbatim. Members asking for a 9:30am Tuesday class is the cheapest market research available.
Over-demand branch.
- If a class instance pattern has had a waitlist of 5 or more for 3 consecutive weeks, create a task for the manager with the recommendation to add a second instance or raise capacity if the space safely allows.
- Notify the members who were repeatedly waitlisted on that pattern when a new instance is added, before it goes on the public timetable: “You have been on the waitlist for Wednesday 6:30pm a few times. We have added a 7:45pm on Wednesdays. First look goes to you: [link]”
Under-demand branch.
- If a class instance pattern has run below minimum viable attendance for 3 consecutive weeks, create a task for the manager with the utilization history and the Timetable Request data for alternative times.
- If a decision is made to retire the slot, notify every member who attended it in the last 8 weeks individually, with the nearest alternatives and an offer to talk to a human. Quietly removing a class somebody organizes their week around is a churn event.
Stop and exit. One-shot weekly. The over- and under-demand branches exit when the manager closes the task.