2.8 KiB
Architecture
Overview
The Salon platform is a Django REST API backend with a React/Vite frontend, optimized for KSA (phone auth, Riyadh timezone, Arabic locale).
Backend Apps and Responsibilities
| App | Responsibility |
|---|---|
| accounts | User model, phone/OTP auth, JWT tokens, locale preferences. OTP providers (console, Twilio, Unifonic) send SMS/WhatsApp. |
| salons | Salon catalog, services, staff, availability windows, reviews. Read-only public APIs. |
| bookings | Booking model, validation (availability, overlap prevention), status transitions. Triggers notifications on create and status change. |
| payments | Payment model, Moyasar integration (create, capture, refund), webhook reconciliation, idempotency. |
| notifications | Booking lifecycle notifications (SMS/WhatsApp). Reuses OTP providers; sends on booking created/confirmed/cancelled. |
Data Model Overview
The core data model centers on users, salons, and time-bound bookings. A booking ties a customer to a service, a staff member, and a scheduled time. Payments are recorded per booking and reconcile to the external gateway. Notifications are stored for every booking lifecycle message for auditability.
accounts.Userowns phone, locale, and auth preferences.salons.Salon,salons.Service, andsalons.Staffdefine the catalog and scheduling surface.bookings.Bookinglinks customer, staff, service, and scheduled time, with status transitions.payments.Paymenttracks gateway state and idempotency per booking.notifications.Notificationrecords each SMS/WhatsApp send attempt tied to a booking event.
Data Flow
User → React Frontend → Django API
↓
accounts (auth) ──→ OTP providers (Twilio/Unifonic/console)
salons (catalog)
bookings ──→ notifications ──→ OTP providers
payments ──→ Moyasar gateway
Async and Observability (MVP Decision)
Decision (MVP): All OTP sends, booking notifications, and payment gateway calls run synchronously in the request/response path. No Celery, RQ, or other task queue for the initial launch.
This is captured in ADR 0001 (docs/adr/0001-synchronous-external-calls-mvp.md).
Rationale:
- Reduces deployment complexity (no Redis, no worker processes).
- MVP traffic is expected to be low; synchronous latency is acceptable.
- External calls already use timeouts (e.g. Moyasar: 10s, Twilio: SDK default).
Future: When scaling, introduce a task queue (e.g. Celery + Redis) for OTP and notification sends. Payment creation and webhooks should remain synchronous for immediate feedback and idempotency.
Observability: Errors are logged via Python logging and stored in model metadata (e.g. Payment.metadata["gateway_error"], Notification.error_message). Structured logging and metrics are Phase 3 work.