Temporary working checklist (dies with the epic) · mirrors PBI #30029 under Feature #30017 · updated 2026-08-05 — HAND-OFF #30018 PROVEN END-TO-END on dev (passwordless login + auto-book future-spot shows in the app) · mobile dev pipeline stood up · mocks.fitprotracker.com live
SLICE 2 COMPLETE (gate closed 2026-08-01) · 2026-08-02: Slice 3 first increment shipped · credits chain PROVEN (contact #160394: 3 Available credits at purchase — punch-card mode works for the first time ever) · memberships betas live · 2026-08-03/04: tenant landing page /sessions/booking/:slug went full-professional (hero/logo/contact) + gym picker for multi-location owners + instructor/class-type filters + week paging · BRANDING v1 shipped end-to-end (!23737 DB · !23738 backend · !23739 landing · !23740 SPA card — all merged, deployed, and E2E-verified with claude-dev: card save → public page flips in ~2s) · 2026-08-04 EVE: widget went mobile/PWA-native (5 iterations w/ real-phone screenshots, zero libraries) · AUTO-BOOK #30016 BUILT + TESTED — the Real Wellness retention answer · reservations epic = board idea #15 · merge queue: !23743 (auto-book) + !23741 (full-bleed mobile landing) · board ceremony still owed: #30034/#30036/PBI #30029 → Done + PBIs for branding/memberships/#30015/#30016.
The Epic map — where "Feature N" lives (DevOps: Epic #30013)
Feature 2 · Embeddable widget + QR#30015MOSTLY BUILT: fpt-book.js live on the Pay dev enclave (gym picker · filters · week paging · auto-brand) + tenant landing page live · remaining: QR short link + prod cutover (prod enclave + env switch) + PBI ceremony
✅
Feature 3 · Auto-book the clicked class#30016DONE + DB-PROVEN 2026-08-04 (PR !23743 merged + deployed): widget sends the tapped classInstanceId; server books via the app's own CustomerBookingProcess · best-effort (full class / no credit → friendly reason, checkout never fails) · PROOF contact #160395: $5 trial purchase → "You're booked!" · ContactClassAttendance row (instance 62133, StatusId 1) · 3 credits granted, 1 consumed by the booking, 2 Available · capacity ticked 0/20→1/20 on the public widget. "Payment and scheduling in one stop" is now literally true — the Real Wellness ask, shipped.
✅
Feature 4 · "Booking Widget" journey builder#30017SLICE 2 DONE 2026-08-01. PBI #30029: builder live in admin UI · widget renders exactly its config · purchase-verified planId (server whitelist) · gate DB-proven (contact #160391, plan 205, $5 tx, invite)
🔧
Feature 5 · Hand-off: iliv.fit→mobile + SMS-OTP#30018PROVEN END-TO-END on dev 2026-08-05. mobile !23747 MERGED (invite deep links · /r/:code · /activate email+code screen · universal-link prep ×7 brands · install-resume hook) · backend !23746 (SMS smart link · single-use code · POST /api/auth/mobile/activate) · staff SPA !23744 · LIVE PROOF on mobile.fitprotracker-dev.com: real widget purchase (Boxing Cardio, future Aug-5 class) → passwordless activate (email+code → JWT, no password) → landed logged-in with the held spot showing under "Next Session". Auto-book + hand-off work together, verified on the deployed app. Remaining long pole: OPS — Azure ClientAppDomain per env · 301 iliv.fit→mobile · Apple TEAM_ID + Play SHA-256s · ×7 store releases.
🔧
Feature 6 · SAQ / FPT Pay enclave#30019ongoing foundation — NEW tasks found tonight: durable SessionStore (in-memory + consumption plan = intermittent invalid_session) + Pay CI/CD pipeline (retire direct publish)
Rule of thumb: Features = the map (stable, on the DevOps board) · Slices = the order we build · this page tracks the active slice's tasks. When Slice 1 closes, this section flips Feature 4 to ACTIVE and the checklist below gets replaced.
✔ Done — setup
✅
Consolidate working directory5 repos on feature/client-onboarding, pushed · saq-hardening carried over
✅
Cut the DevOps boardEpic #30013 · Features #30014–30019 · PBI #30020 + Tasks · #29915 re-parented · all root-iteration
✅
Design validated against real screens + databuilder mock on live dev schedule · SELL shortlist + facets · journey association traced
Slice 2 — PBI #30029 tasks
✅
Backend: BookingWidget journey type + payload model#30030DONE (code-complete, uncommitted): constant + step factory (lead 1 / checkout 2 disabled / widget-config 3) + payload classes + POST api/public/widget/{slug}/sessions filtering server-side on IdFatherClass (=ClassStructure id, verified in Kiosk.cs SQL) · 400 on missing body · builds 0 err (Monster.Web after nuget restore fixed stale packages/)
✅
SPA: Booking Widget card + type-aware editor branch#30031DONE: card in journey-add-panel + editor branch on tabPosition==='BookingWidget' (!23708/!23710)
✅
SPA: 3-step builder — SHOW / SELL / PUBLISH#30032DONE: 3-step builder live on dev · SELL = shared fpt-plan-picker (server facets, derived TYPE badge, shortlist) · agreement facet proven 482→112 server-side
✅
Wire widget mock to a real BookingWidget journey#30033DONE: widget mode (?journey=slug) renders the journey's exact sessions + offers from the anonymous router/offers endpoints · PAY&BOOK posts the widget journey + chosen planId
✅
purchase-verified planId extension (buy the CHOSEN offer)#30036server-validated against the journey's own planIds · 400 before idempotency claim · price/terms load from the plan record LocationId-scoped · 106/106 tests · +membership-branch fix (!23712) after the gate caught the silent no-op sale
✅
QA — Slice 2 proof gate on dev#30034CLOSED 2026-08-01: negatives passed (foreign planId 400 · non-widget journey 400) · final purchase DB-proven: contact #160391 · sub on plan 205 $5.00 · AP+RI transactions · SendAppInvite:true
🎯 Slice-2 proof gate: a gym admin builds a Booking Widget journey in the real admin UI and the widget renders exactly that config — sessions, plans, purchase. Builder becomes the single source of truth.
✔ Done — Slice 1 (PBI #30020, closed 2026-07-31)
✅
The spine: #30021–#30026 all DoneZiftCheckoutBase + purchase-verified + [pay].EmbedConfig + idempotency/rate-limit + mock wiring + QA gate · 3 real buyers · idempotency DB-proven · classic regression green · full evidence on PBI #30020
∥ Parallel wins (no dependency)
⬜
Promote #29915 auto-invite Dev → Test → Prodbuilt + E2E-verified on dev · purely pipeline · first shippable value of the epic
⬜
SAQ iframe on existing checkout → toward prodFeature #30019 · commits on branch · standalone PCI win
Trace StartingCreditsAmount write timingDONE 2026-08-02 — findings: credits write SYNCHRONOUSLY at checkout · both landmines found (gate skips starting-only plans · builder needs session-rules warning)
✅
Credits chain FIXED + PROVEN end-to-endALL DEPLOYED 2026-08-02: gate widened ×3 (!23715) · sessionRules endpoint + offers credits (!23715) · builder SELL amber warning (!23716) · widget StartImmediately fix (!23719 — QA caught: sub + $5 charge but ZERO credits, FirstBillingDate=9999 placeholder skipped the block) · FINAL PROOF contact #160394: bought the starting-credits-only plan 341 via the widget → 3 Available credits in SessionCreditCustomer at purchase, 14-day expiry. The punch-card mode works for the first time in FPT history.
✅
Slice 3 first increment — fpt-book.js + host route SHIPPEDDEPLOYED 2026-08-02: fpt-book.js v1 live at the Pay enclave /book/v1/fpt-book.js (E2E-proven on the embed test page, contact #160392) · host route /sessions/booking/:slug merged (!23714) + PublicDomain pipeline green · still open: QR target, prod cutover, PBI ceremony for #30015
NEW TRACK spun out 2026-08-02 — memberships redesign (own PBI, outside the epic)
✅
Recipe wizard (CREATE) — beta on dev"What are you selling?" → 3-4 plain-English questions → confirm sentence → the classic form's exact plan/upsert payload · mock incl. the "Anything else?" add-on step (fee / contract / tax / subgroup) · API QA caught 3 real bugs before any human: dead addPlan route · required-subgroup rejection · widget credits skip — all fixed + deployed (!23718 / !23719) · Done screen hands off to Advanced edit · test artifact: plan #341 in auto-created "Intro Offers"
✅
Memberships beta view (MANAGE) — beta on dev/billing/memberships/new = plan-picker manage mode: TYPE badges · facet rail · server search/paging · archived toggle · EDIT hands off to the classic form (!23717) · design mock · credits explainer = the education companion
"Anything else?" step — deployed = PROD-ADEQUACY GATE PASSED!23721 (2026-08-03): 4 add-on chips live in the real wizard — Signup fee (client sends dollars, server stores cents — proven) · Contract length (cycleLength + auto-renew off, server derives "12 Month(s)") · Charge tax (location tax list, neutral copy) · Subgroup (proactive + error-driven backstop) · every add-on API-verified on plan #67022 pre-merge · wizard now expresses ~95% of prod plan shapes
⬜
Then: PBI ceremony · recipe-aware edit · duplicates finder · lifecycle facetscut the memberships-redesign PBI with the mocks as spec; recipe-aware EDIT only after the wizard proves itself on creates
Tenant public landing page — live on devDEPLOYED: /sessions/booking/:slug is now a professional default page (Cloudinary logo hero · address/phone/email · tagline · footer) for gyms with no website — live example · design preview
✅
Gym picker + filters + week paging in fpt-book.jsDEPLOYED to the Pay dev enclave: multi-location owners get a "choose your gym" switcher (widget/{slug}/locations, !23735-era backend) · instructor + class-type filters (auto-hidden until 2+ distinct) · ‹ › week arrows
✅
BRANDING v1 — table → API → widget/landing/settings card, E2E-verifiedALL MERGED + DEPLOYED + TESTED (claude-dev): dbo.BrandProfile org/location hierarchy w/ enforce (!23737) · resolution + GET/POST api/location/branding + branding node on the public router payload (!23738) · landing tagline (!23739) · self-serve Branding card at Location → Settings → Branding [Beta] w/ 3 pickers, contrast guardrail, live previews, org-lock banner (!23740) · proof: change color in card → Save → public booking page flips in ~2 seconds · widget auto-brands from the payload (no data-brand attr needed) · mock · schema already carries the Branded App Request form's fields (tertiary + 4 asset slots) → future v3: generate the mobile app's clients/ theme folders from the table
⬜
Branding next phases (when called)v1.5 data-brand="auto" host-site matching · v2 AI color extraction from URL/screenshot + org screen w/ enforce toggle + PUBLISH brand selector · v3 clients-folder generation (pitch to the app team: table replaces tickets) · email [BrandColor] token · asset uploads on the card
Widget matches the approved mock + went PWA-native on phonesDEPLOYED to the enclave over 5 iterations w/ Antonio's phone screenshots: card-per-class + avatar + bold CTA · responsive restack via container query (works in skinny embeds too) · all-7-days compact day picker · sticky day bar · bottom-sheet checkout w/ drag handle · in-strip ‹ › week pagers · touch polish · ZERO libraries (native scroll-snap/sticky/container-queries — embeds stay ~16KB, conflict-free) · full-bleed landing card on phones = PR !23741 awaiting merge
✅
Auto-book #30016 — the "one stop" promise made literalPR !23743 (see Feature 3 above) · driven by the Real Wellness retention signal (Raisa via Christen: "payment and scheduling in one stop") · post-merge proof: 1 dev purchase → ContactClassAttendance row + credit consumed + capacity ticks on the public widget
✅
Reservations platform epic captured (board idea #15)the three tiers of "reserve a spot": headcount (have) → pick-your-spot map (bike/reformer/bed — Mariana Tek parity; cryo = 1-spot case) → appointments (free-slot on staff/resource/room availability — widget has never touched the admin appointment system) · ask back through Christen: does Real Wellness run cryo as set slots (works at auto-book) or any-open-time (tier 3, new scope)?
✅
Launch kit + team enablementpromo kit (anchor: "Your website now sells the first visit for you.") + 11-slide branded training deck (renders verified) at C:\FPT\client-onboarding\promo\ · team guide page w/ every feature's how-to links · embed test page now runs the REAL enclave script + real Branding colors (mock brand removed)
✔ Done 2026-08-05 — hand-off proven + mobile dev pipeline + mocks domain
✅
Mobile dev pipeline — client PWA now auto-deploys to a standing dev siteRevived the dead mobile dev branch (fast-forwarded to main, 0/1007 → current) · built + registered pipeline def #119 (CD-Client-Mobile-PWA-Dev): every push to dev builds the client PWA and deploys to mobile.fitprotracker-dev.com · 2 CI fixes to green (npx ng build !23762 · Node 18→20 for Angular 20 !23763) · mobile finally has feature → dev → release → main discipline. This is what made #30018 testable.
✅
Hand-off #30018 validated end-to-end on the real deployed appPasswordless SMS-code login proven on mobile.fitprotracker-dev.com (activation screen → /api/auth/mobile/activate → JWT bound to the right contact+location → logged in, code single-use consumed) · auto-book holds the future spot: real widget purchase of Boxing Cardio (Aug 5, 6 PM) → logged in → the class shows under "Next Session / 1 Upcoming". Answered the "does it actually hold the spot?" question live.
✅
Booking-window research + competitor analysis → 2 new board ideasMapped FPT's booking-window config (AllowedBooking/RequiredBooking policies · TimeFlag H/D + Interval · Zone 6 = ~26-policy junk drawer) vs Mariana Tek + Mindbody · new idea #16 (dashboard "happening now / today" — in-progress/same-day classes shouldn't read as "no upcoming") · new idea #17 (Reservations window enhancements: drop windows + waitlist auto-promote + VIP early access, tied to epic idea #15).
✅
mocks.fitprotracker.com — shareable, search-blocked mock hostingCustom domain on the prototypes SWA (Cloudflare CNAME + az staticwebapp hostname set, HTTPS cert Ready) · X-Robots-Tag: noindex on every page (invisible to Google) · storyboard brand-picker removed so a shared link never exposes the client roster; ?org= theming still works · ready for the FBBC conference: mocks.fitprotracker.com/journey-storyboard.html?org=fbbc
Up next
⬜
Slice 3 remainder — QR target + prod cutoverQR = fitpro.io short link → /sessions/booking/:slug · prod needs widget endpoints on prod Monster.Web (release train) + a prod Pay enclave (Feature #30019) + fpt-book env switch
🔁 The deploy loop (per increment): review → small commit w/ AB#task on feature/client-onboarding → push origin → PR → Dev → pipeline deploys → test on dev. Same branch every time, never a new branch name, never direct-push.