Five problems shaped the whole project.
Face mapping had no off-the-shelf solution. Aesthetic clinics need clinical-grade face diagrams where practitioners mark injection sites with dose and product, then attach the annotated diagram to a patient record. Nothing on the market fit the workflow. The editor had to be built from scratch.
Patient deposits had to flow to each clinic's own Stripe account, not Callidus'. Each clinic is the legal merchant-of-record for medical services they perform. Pooling deposits on Callidus' account would transfer liability in the wrong direction. This meant Stripe Connect Standard with Direct Charges, per-tenant Connect onboarding, application-fee logic, the full webhook matrix including 3D Secure escalation, and regulatory isolation baked into every flow.
Six roles had to coexist without drift. Super admin, owner, admin, manager, practitioner, receptionist — each with distinct access to clinical data, financial data, settings, and billing. Inline role checks rot the moment the matrix changes. The codebase is built around role helpers (hasClinicalAccess, hasManagerAccess, hasAdminAccess) so every access gate stays consistent.
Clinics had to embed a booking widget on their own marketing sites. That meant Shadow DOM isolation, an unhashed bundle name for stability across deploys, a Service Worker with NetworkOnly strategy for Firebase and Stripe to stay GDPR-compliant, tenant binding by slug, and a scroll-trap fix for iframe behaviour on arbitrary host pages.
Trial-to-active-to-suspended had to run itself. A 14-day trial with a four-stage email and grace lifecycle: 3-day reminder, 1-day reminder, expiry with a 3-day grace window, then suspension. Payment escalation for active tenants running past due. Grace-period mutations blocked server-side, pages viewable but writes refused — belt-and-braces between client route gates and Firestore rules.