PRD v4.1 · March 2026

White-Label Salon Booking Platform

Branded iOS & Android apps for hair salons in Romania & CEE — powered by a serverless-first architecture with a 99% gross margin at scale.

99%
Gross Margin at Scale
−65%
Backend Code vs Traditional
5
Deploy Targets, 1 Repo
6mo
To First Paying Client
Product Overview

What We're Building

A self-service platform that spins up fully-branded App Store apps for salons — with booking, CRM, and an optional AI phone receptionist.

For Salon Owners
Professional App Store presence · Automated bookings · Real-time dashboard · Zero IT management
For End Users
Native iOS & Android booking · Push reminders · Stylist portfolios · Easy rescheduling
For You (Owner)
One monorepo · Add-on upsells €50–100/mo · Self-service onboarding · High-margin SaaS
Target Markets
🇷🇴 Romania — Primary
🇭🇺 Hungary / Transylvania
🇵🇱 Poland
🇨🇿 Czech Republic
🌍 B2B International (EN)

Development Timeline

6-Phase Roadmap

From zero to first paying client in ~6 months as a solo developer.

Phase 1 — Foundation Months 1–2

Core infrastructure, mobile basics, booking flow, and dashboard skeleton.

Weeks 1–2: Monorepo setup + Supabase schema + RLS policies + auth
Weeks 3–4: Expo mobile app shell + Expo Router + NativeWind + gluestack-ui
Weeks 5–6: Core booking flow on mobile (service → staff → slot → confirm)
Weeks 7–8: Admin dashboard first cut (Expo web) — calendar, bookings list
Weeks 9–10: Brand config system + per-tenant config.json + DTCG token pipeline
Weeks 11–12: NestJS orchestration layer — OnboardingModule, BuildsModule

Phase 2 — White-Label Automation Month 3

Edge functions for SMS + self-service onboarding wizard.

Weeks 13–14: SMS confirmation/reminder Edge Functions (Twilio + Deno)
Weeks 15–16: 8-step onboarding wizard UI + NestJS automation triggers

Phase 3 — AI Phone Integration Month 4

Twilio number provisioning + Eleven Labs conversational agent wiring.

Weeks 17–18: Twilio webhook handler + per-salon number routing in NestJS
Weeks 19–20: Eleven Labs dynamic variable injection + availability/booking API endpoints

Phase 4 — Production Readiness Month 5

Redis slot locking, Stripe billing, EAS auto-submit, QA hardening.

Weeks 21–22: SlotLockingModule (Redis 90s TTL), Stripe base subscription, EAS Build pipeline end-to-end

Phase 5 — Polish + First Client Launch Month 6

Pilot with 3–5 salons, App Store submissions, OTA update flow live.

Weeks 23–24: Soft launch · App Store reviews · feedback loop · V1.1 planning

Phase 6 — V1.1 Add-Ons Months 7–9

Add-on marketplace, AI Receptionist billing, Client Reactivation, marketing site.

Weeks 25–26: tenant_addons table + AddonGuard + BillingModule + Stripe SubscriptionItems
Weeks 27–28: AI Receptionist add-on (guarded by @RequiresAddon)
Weeks 29–30: Client Reactivation campaigns (push + SMS)
Weeks 31–34: Platform marketing site (Next.js, i18n, 5 locales, MDX blog)

Scope Definition

Feature Tiers

Four tiers define what ships when — and what's intentionally excluded.

V1

Ships Before First Paying Client

~3–4 months
Core booking flow — iOS + Android + Web (Expo managed)
Branded EAS Build + App Store submission per salon
Salon admin dashboard (Expo web export)
8-step self-service onboarding wizard with Design System step
Supabase multi-tenancy with RLS — zero tenant data leakage
SMS booking confirmations + 24h/2h reminders (Twilio Edge Function)
Stripe base plan billing (€50–150/mo per tenant)
tenant_addons table + AddonGuard + @RequiresAddon() decorator
NestJS: OnboardingModule, BuildsModule, SlotLockingModule
V1.1

Ships Within 60 Days of Launch

Months 7–9
AI Receptionist (Eleven Labs + Twilio) — gated by addon_key
Stripe Subscription Items per add-on (one invoice per tenant)
Client Reactivation & Retention campaigns (push + SMS)
Platform marketing site (Next.js 15, i18n ro/en/hu/pl/cs, MDX blog)
Add-Ons management UI in salon admin dashboard
Design System Wizard — token editor, style presets, live component preview
V2

After 10+ Active Salons

Validated demand required
In-App Full Payments (Stripe PaymentIntents + Netopia for Romanian cards)
Stock Management — stock_items table, admin UI, reorder alerts
Loyalty Wallet Pass (Apple PassKit + Google Wallet)
iOS Live Activities (Dynamic Island + Lock Screen) via Config Plugin
Android Home Screen Widgets (expo-widget-kit)
Figma → Platform Token Sync (figmasync addon, DTCG export plugin)
Out of Scope

Documented Anti-Scope

V3+ or strategic pivot
Per-tenant SEO website (Next.js per salon) — reserved addon_key: seo_web_presence
Bluetooth scale integration (smart_stock) — needs stock_management adoption first
Romanian SAF-T fiscal compliance — V3 blocker for full PoS
Marketplace / salon discovery directory
Multi-location / franchise management
POS hardware (fiscal printers, card terminals)

Technical Architecture

Three-Layer Backend

Not a monolith, not microservices — a distributed system in one monorepo with three distinct runtime layers.

Layer 1 — Supabase Direct

60% OF BACKEND

PostgREST auto-generates REST endpoints. RLS enforces tenant isolation at the DB level. Zero NestJS CRUD code.

Auth (JWT/OAuth) Realtime WebSockets Storage (CDN) All CRUD endpoints −1,500 lines of code

Layer 2 — Edge Functions (Deno)

20% OF BACKEND

Stateless, short-lived (under 5s). TypeScript native, no node_modules, <5ms cold start. Triggered by webhooks or DB events.

send-confirmation-sms send-reminder (cron) stripe-webhook validate-design-tokens verify-phone-number calculate-cancellation-fee

Layer 3 — NestJS (Node.js)

20% OF BACKEND

Complex multi-step orchestration. Long-running flows, Redis locks, external API coordination with rollback logic.

OnboardingModule BuildsModule SlotLockingModule WebhooksModule BillingModule DesignSystemModule
KEY SERVICES
📱
Expo Managed + Expo Router
iOS · Android · Web — one codebase, Hermes runtime
V1
🌐
Next.js 15 App Router
Marketing site — SSG/SSR, i18n, MDX blog, Vercel deploy
V1.1
🎨
NativeWind v5 + gluestack-ui v2
Tailwind for RN · per-tenant ThemeProvider · DTCG token swap
V1
🛢️
Supabase PostgreSQL + RLS
Managed DB · automatic tenant isolation · connection pooling
V1
Supabase Realtime
WebSocket subscriptions · live calendar updates · tab election
V1
🏗️
EAS Build + Submit + Update
Automated App Store submissions · OTA JS updates in 24h
V1
📞
Twilio + Eleven Labs
Dedicated booking line per salon · AI conversational agent
V1.1
🔴
Redis (Upstash Serverless)
Slot reservation locks only · 90s TTL · atomic SET NX
V1
💳
Stripe Billing
One subscription per tenant · SubscriptionItems for add-ons
V1
🎨
Style Dictionary v4
DTCG tokens.json → NativeWind @theme CSS vars + Tailwind keys
V1

Self-Service Onboarding

8-Step Wizard

A salon goes from sign-up to live App Store app — largely automated — in 1–3 days.

1
Business Info
Salon name, email, slug → Supabase tenants table
2
Brand Identity
Logo, icon, splash → Supabase Storage · colors migrate to DTCG token format
3
Design System NEW v4.1
Style preset selection · token overrides (colors, radii, typography) · live gluestack-ui preview
Validated
4
Services Catalog
Service names, durations, prices → services table
5
Staff Setup
Stylist profiles, working hours, services offered → staff table
6
Booking Rules
Cancellation policy, advance notice, slot duration → tenants.config JSONB
7
Add-Ons Selection
AI Receptionist, Retention campaigns → tenant_addons + Stripe SubscriptionItems
Stripe API
8
Store Credentials
Apple/Google dev account creds → encrypted storage → EAS Build trigger
EAS Build
⚡ Automated Post-Wizard
→ Vercel domain provisioned (app.salonname.com)
→ DTCG tokens written to tenant.config.designSystem
→ Style Dictionary generates theme.css → brands/{slug}/
→ EAS Build triggered → auto-submitted to App Store + Play Store
→ Apps live in 1–3 days (Apple review time)

Add-On Marketplace

Extensible Revenue Streams

Open/closed architecture: new add-ons ship without touching core business logic. One guard, one table, one decorator.

🤖
AI Receptionist 24/7
Eleven Labs conversational agent · per-salon Twilio number · dynamic context injection
+€50–100/mo
V1.1
📣
Client Reactivation
Automated push + SMS campaigns for dormant clients
+€20–30/mo
V1.1
💳
In-App Full Payments
Stripe PaymentIntents + Netopia for Romanian cards · per booking
% txn
V2
📦
Stock Management
stock_items table · admin UI · reorder alerts · CSV export · BLE scales later
+€20/mo
V2
🎫
Loyalty Wallet Pass
Apple Wallet + Google Wallet · APNs push on completed bookings
+€15/mo
V2
🏝️
Live Activities + Widgets
iOS Dynamic Island / Lock Screen · Android widgets · APNs push at 60m + 15m
Bundled
V2
🎨
Figma Design Sync
DTCG export plugin upload → auto EAS Build trigger · figmasync addon_key
+€20/mo
V2
🌐
Per-Tenant SEO Site
Next.js ISR per salon · reserved for V3+ strategic decision
V3+
OOS

Business Model

Revenue Model

Setup fee + monthly SaaS base + high-margin add-on upsells.

Setup Fee

€500 – €1,500

One-time per salon onboarding, brand config, EAS build + App Store submission

Monthly SaaS

€50 – €150/mo

Base plan — booking, dashboard, SMS reminders, CRM, OTA updates

AI Receptionist

€50 – €100/mo

Target 60% attach rate at 100+ salons. Eleven Labs flat cost at scale.

Target ARPS

€175/mo avg

Base plan + AI Receptionist + one retention add-on = typical high-value client

REVENUE MILESTONES
6 mo
10 salons
Pilot clients · 83% margin · proof of concept
€1,750 MRR
12 mo
50 salons
Hire part-time support · negotiate Eleven Labs enterprise
€8,750 MRR
24 mo
200 salons
92% margin · Twilio volume pricing · V2 add-ons live
€35,000 MRR
36 mo
500 salons
97% margin · scale NestJS 2x instances
€87,500 MRR
48 mo
1,000 salons
99% margin · Supabase Team plan · franchise potential
€175,000 MRR

Infrastructure & Scaling

Cost vs Growth Model

Infra cost is nearly flat until 2,000 salons. Margins improve as salons grow.

Stage Salons MRR Infra/mo Margin
Launch 10 €1,750 €305
83%
Early 100 €17,500 €1,414
92%
Growth 500 €92,500 €2,554
97%
Scale 2,000 €390,000 €5,148
99%
Mature 5,000 €1,000,000 €9,649
99%
Upgrade Triggers
🏷️ 80 salons: Eleven Labs enterprise (€1k flat)
📞 100 salons: Twilio volume pricing (−20–30%)
⚙️ 500 salons: NestJS 2× instances (€80/mo)
🛢️ 2,000 salons: Supabase Team (€599/mo)

Data Model

Core Database Schema

All tables are RLS-isolated per tenant. No manual WHERE tenant_id — the DB enforces it from the JWT.

tenants source of truth for all config
id: UUID PK slug: VARCHAR(50) UNIQUE salon_name email domain twilio_number status: onboarding|active|suspended config: JSONB (designSystem DTCG tokens) stripe_customer_id stripe_subscription_id
tenant_addons add-on entitlement registry
id: UUID PK tenant_id: FK → tenants addon_key: TEXT is_active: BOOLEAN price_monthly (display cache) stripe_subscription_item_id activated_at UNIQUE(tenant_id, addon_key)
bookings source of truth for appointments
id: UUID PK tenant_id · staff_id · service_id · client_id start_time · end_time status: pending|confirmed|completed|cancelled|no_show payment_status: unpaid|paid|refunded stripe_payment_intent_id live_activity_token (V2) booking_source: app|phone_ai|dashboard|walk_in UNIQUE(staff_id, start_time)
staff stylists & roles
id: UUID PK tenant_id: FK name · role · photo_url working_hours: JSONB services_offered: UUID[] active: BOOLEAN
clients CRM — per-tenant, phone unique
id: UUID PK tenant_id: FK first_name · last_name phone: VARCHAR UNIQUE(tenant_id, phone) preferred_staff_id total_visits · total_spent · last_visit_date blacklisted: BOOLEAN
services catalog per tenant
id: UUID PK tenant_id: FK name · description duration_minutes · price active: BOOLEAN

Risk Assessment

Top Risks & Mitigations

Documented for proactive management — not to worry about, but to have a plan.

Apple "copycat app" rejection
Use client-owned developer accounts + unique branding per salon — each app is independently listed
High impact
Concurrent double-booking race condition
Redis slot locking with 90s TTL + atomic SET NX operation — works across multiple NestJS instances
Medium
Supabase Realtime connection limit
Tab election reduces connections by 20×. Upgrade to Team plan at 2,000 salons.
Medium
Eleven Labs cost explosion
Negotiate enterprise flat at 80 salons (€1k/mo). Price AI add-on at €50–100/mo — profitable at ~15 salons.
High impact
Low salon adoption / low add-on attach
Start with 3–5 pilots, free setup for first clients, offer add-on free trials with clear ROI messaging
Medium
NestJS server downtime
Railway auto-restart + health checks. 60% of backend is Supabase-direct — most app functionality survives NestJS being down.
Low prob
Competition from Fresha / Booksy / Treatwell
CEE-first, Romanian language, white-label App Store presence (no commissions), AI receptionist differentiator
Medium
Competitive Positioning
Fresha
Generic UI, limited customization, takes commission fees
Fully white-labeled App Store app, no commissions, modular add-on pricing
Booksy
Not white-label, 8–12% commission per booking
Client owns their brand, flat monthly fee, AI receptionist built-in
Treatwell
15–30% commission, high marketplace dependency
Predictable flat pricing, direct client relationship, no marketplace cut
SimplyBook.me
Web-based only, no native iOS/Android apps
Native iOS + Android apps per client, better mobile UX