# SalonPro Africa — Core API + Staff Web App
**New:** a real staff-facing web app now ships with this project (in `apps/api/public/`), served automatically from the same backend — no separate deploy, no new Render service. Visit the site's root URL (not `/docs`) and you'll get a login screen instead of Swagger.
Covers the core daily loop: **sign in → see today's schedule → book a walk-in → complete → checkout/take payment**. Inventory, payroll, and reports screens aren't in the web app yet (still Swagger/API-only for those) — next phase.
What's built so far, verified end-to-end (not just "should work"):
- Multi-tenant Postgres schema with Row-Level Security, applied and tested
- DB-level double-booking prevention (exclusion constraint), tested under conflict
- JWT + OTP auth (console "SMS" for dev), RBAC guards, tested for both allow and deny cases
- Bookings: availability engine, create (with "any available staff" fallback), reschedule, cancel, complete
- **POS/Invoicing**: generate invoice from a completed appointment, record split/partial payments (cash, M-Pesa reference, card), auto-transitions UNPAID → PARTIALLY_PAID → PAID
- **Commissions**: per-staff commission rate, auto-calculated per invoice line on full payment, payout tracking, filterable list
- **Reports**: daily revenue + top services (JSON), commissions **downloadable as CSV**
- Every claim above was proven with real HTTP requests against a real running server and real Postgres — see the conversation for the actual request/response logs, including four real bugs found and fixed along the way (guard ordering, an RLS chicken-and-egg problem in login, a Postgres timestamptz/range type mismatch, and an enum/text comparison type error).
## Run it yourself (2 minutes, requires Docker)
```bash
cd salonpro
docker compose up --build
```
This will:
1. Start Postgres
2. Wait for it, then apply all migrations (schema + RLS policies + billing/commissions + the two DB roles used for tenant isolation)
3. Seed …