If a membership plan includes a fixed number of visits per period (e.g. 'Care Club Standard — 2 included tune-ups per year'), the customer's enrollment tracks how many they've used vs the cap. The smart-slot booking composer surfaces the perk so the dispatcher can redeem one with a click.
What you see in the booking composer
When you pick an existing customer who has an active membership, a Care Club card appears below the customer info block. It shows the plan name + remaining visits + a checkbox:
- Care Club Standard ($19/mo)
- 1 of 2 included visits remaining this period
- ☐ Redeem one for this appointment (no charge — counter goes to 2 of 2)
Tick the box → save the booking → the membership counter increments atomically + the appointment row is tagged with `is_membership_redemption=true`. If you don't tick the box, it's a regular paid appointment.
What happens when there are no visits left
If the customer has used all their included visits, the card still shows with the count ("0 of 2 included visits remaining — counter resets <date>") but the redeem checkbox is hidden. The next period's rollover (daily 5:30 UTC cron) automatically refreshes the counter, so it'll come back the day after their period ends.
Race-safe consumption
Two simultaneous bookings — say the dispatcher in /portal AND the AI receptionist on a phone call — can't both redeem the last available visit. The increment is gated by an atomic SQL filter that re-checks the cap inside the same statement that updates. One booking gets the visit; the other gets a 'no visits remaining' error and the dispatcher sees a clear message.
What the redemption flag does downstream
Redeeming a visit doesn't automatically zero-out the line items on the eventual invoice. v1 stores the flag for audit + reporting; the contractor decides whether to add a 'Care Club included visit — no charge' line, or a 100% per-line discount, or to skip invoicing entirely. A future polish phase will auto-mark the matching service line as no-charge on invoice creation.
If a redeemed appointment is cancelled, the membership counter stays at the consumed count for v1 — the visit is treated as 'used.' If you need to give the customer their visit back, manually decrement `included_visits_used` on their enrollment row via the customer detail page → Memberships section, or open a support ticket. Phase D.2 will add automated reverse-decrement on cancellation if a clear pattern emerges from real customer use.
v1 deferred from this phase: voice-tool integration (Hannah/Jessica still book regular appointments — they can't see or redeem included visits in the transcript yet), service-type restriction filter (any service can redeem an included visit, even if the plan was meant for tune-ups only), and auto-100%-discount on invoice line items. All three land in follow-up phases.