Files
Salon/docs/architecture.md
T

223 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Salon MVP Roadmap And Architecture Review
## Purpose / Big Picture
This plan reviews the current Salon codebase (Django backend, React/Vite frontend), highlights architectural and design risks, and lays out a pragmatic roadmap to reach an MVP that aligns with **Phase 1: Core MVP Reliability** in `AGENTS.md`: phone-first auth with OTP, robust booking integrity, Moyasar payments, booking lifecycle notifications, localization foundations, and tests for critical flows.
The roadmap assumes a KSA-focused first launch (phone auth and Riyadh timezone defaults) with a clean path to expand later.
## Current State Summary
### Backend (Django, DRF)
- **Project**: `salon_api` in `[backend/salon_api](backend/salon_api)`
- `settings.py` configures `AUTH_USER_MODEL = "accounts.User"`, DRF + SimpleJWT, KSA locale defaults, and custom settings for OTP, notifications, and payments.
- URLs route to app-level APIs at `/api/auth/`, `/api/salons/`, `/api/bookings/`, `/api/payments/`.
- **Auth & Accounts** (`[backend/apps/accounts](backend/apps/accounts)`)
- Custom `User` model with phone-first capabilities (`phone_number`, `is_phone_verified`, `preferred_language`, `role`).
- Phone normalization services tuned for KSA numbers (`[backend/apps/accounts/services/phone.py](backend/apps/accounts/services/phone.py)`).
- OTP domain + service layer with rate limits, cooldowns, expiry, and hashed codes (`[backend/apps/accounts/services/otp.py](backend/apps/accounts/services/otp.py)`).
- Phone-first auth endpoints that issue JWT tokens on successful OTP verification, plus basic email/password registration.
- Social login endpoint is a placeholder that always returns 501.
- **Salons & Catalog** (`[backend/apps/salons](backend/apps/salons)`)
- Models for `Salon`, `Service`, `StaffProfile`, `StaffAvailability`, `Review`, `SalonPhoto`.
- Read-only APIs for salon search, services, staff, and reviews.
- **Bookings** (`[backend/apps/bookings](backend/apps/bookings)`)
- `Booking` model ties together salon, service, staff, customer, time window, price, and status.
- `validate_booking_request` in `[backend/apps/bookings/services.py](backend/apps/bookings/services.py)` enforces staff membership, duration matching, availability windows, and overlap prevention for pending/confirmed bookings.
- `BookingViewSet` in `[backend/apps/bookings/views.py](backend/apps/bookings/views.py)` applies role-based access and hooks into notifications on create and relevant status changes.
- **Payments (Moyasar)** (`[backend/apps/payments](backend/apps/payments)`)
- `Payment` model tracks provider, status (fine-grained transitions), amount, idempotency key, external ID, payload, and timestamps.
- `MoyasarGateway` in `[backend/apps/payments/services/gateway.py](backend/apps/payments/services/gateway.py)` can create payments via HTTP but has `capture_payment`/`refund_payment` as TODOs.
- `create_payment_for_booking` in `[backend/apps/payments/services/payments.py](backend/apps/payments/services/payments.py)` enforces provider choice (Moyasar only), idempotency, and maps webhook events into internal statuses.
- Webhook view in `[backend/apps/payments/views.py](backend/apps/payments/views.py)` authenticates via shared secret and applies provider events idempotently.
- **Notifications** (`[backend/apps/notifications](backend/apps/notifications)`)
- `Notification` model records booking-related notifications and enforces uniqueness per booking/recipient/event/channel.
- Services in `[backend/apps/notifications/services.py](backend/apps/notifications/services.py)` reuse OTP providers to send SMS/WhatsApp messages for booking created/confirmed/cancelled events, with localization via `preferred_language`.
- Booking views call `notify_booking_lifecycle` / `notify_on_status_change` to trigger notifications for customers and staff.
- **Testing**
- Solid tests around:
- Phone normalization, OTP rate limiting, and phone auth flows (`[backend/apps/accounts/tests](backend/apps/accounts/tests)`).
- Booking integrity and overlap rules (`[backend/apps/bookings/tests](backend/apps/bookings/tests)`).
- Payment idempotency and Moyasar webhook handling (`[backend/apps/payments/tests](backend/apps/payments/tests)`).
- Booking notifications on create/status change (`[backend/apps/notifications/tests](backend/apps/notifications/tests)`).
- `docs/risks.md` explicitly tracks several known gaps around auth, booking, payments, data/UX, and ops.
### Frontend (React, Vite)
- **Structure**
- Vite React app at `[frontend](frontend)` with entry in `[frontend/src/main.jsx](frontend/src/main.jsx)` and single top-level component in `[frontend/src/App.jsx](frontend/src/App.jsx)`.
- No `react-router` or multi-page routing; the entire experience is one composed screen.
- **Current Features**
- **Salon search**
- Text search field calling `/salons/?q=<query>` via a small API client in `[frontend/src/api/client.js](frontend/src/api/client.js)`.
- Renders responsive list of salons with rating, city, and phone.
- **Localization/i18n**
- `react-i18next` setup in `[frontend/src/i18n/index.js](frontend/src/i18n/index.js)` with `en` and `ar-sa` translations.
- Locale preference stored in `localStorage`; applies `lang` and `dir` on the document.
- **Payments beta**
- A form in `App.jsx` that sends payment creation requests to `/api/payments/` using the Moyasar-style payload, with configurable `booking_id`, source type, token, and callback URL.
- Optionally includes a Bearer token from a manually-entered access token field.
- On success, can redirect to `redirect_url` and shows the raw JSON response.
- **State & Tests**
- All state is local to `App.jsx` via `useState`/`useEffect`; there is no centralized state management or domain hooks yet.
- A single test file `[frontend/src/App.test.jsx](frontend/src/App.test.jsx)` covers hero copy and locale/RTL behavior, but not search or payments.
## Glaring Design And Architectural Issues
### Backend Risks
- **Incomplete provider implementations for production-critical flows**
- Authentica is the only OTP/notification provider; ensure it is fully configured and exercised in production-like environments.
- `MoyasarGateway` lacks `capture_payment` and `refund_payment` implementations, limiting payment lifecycle coverage.
- **Risk**: Code reads “production ready” at the API level, but the underlying integrations are not, which could cause outages if deployed naively.
- **Tight coupling between OTP and notifications**
- Notification services import the OTP provider mapping and default `NOTIFICATION_PROVIDER` to `OTP_PROVIDER`, binding booking notifications to auth configuration.
- **Risk**: Changing OTP providers or adding a second channel for marketing/ops notifications will be harder and could have unintended side effects.
- **Synchronous IO-heavy work in request/response path**
- OTP sends, booking notifications, and payment gateway calls all occur synchronously inside view methods (`perform_create`, `create`, etc.).
- **Risk**: Slow or flaky providers will degrade API latency and user experience; retries and backoff are hard to implement without background jobs.
- **Cross-app domain coupling without a clear orchestration layer**
- `apps.bookings` depends on salons and notifications; notifications depend on accounts (OTP providers) and bookings; payments depend on bookings.
- **Risk**: As you add more lifecycle rules (e.g., auto-confirm booking on payment, send reminders, handle refunds), the spaghetti of cross-imports will grow unless you introduce clearer service boundaries.
- **Auth model vs login patterns**
- `User.USERNAME_FIELD` is email, while phone-based JWT issuance happens via custom endpoints.
- **Risk**: This split can confuse clients and admin tooling and may complicate future flows like social login or SSO unless you standardize on an identifier strategy.
- **Docs drift around ExecPlans**
- `AGENTS.md` references `docs/execplans/payments-moyasar.md` as the active plan, while `PLANS.md` names `docs/execplans/booking-notifications.md`.
- **Risk**: Contributors may follow different “active” plans, causing architectural inconsistency.
### Frontend Risks
- **Monolithic `App` component with no routing**
- `App.jsx` mixes hero/search, salon listing, payments, and locale controls.
- There is no `react-router` or notion of separate flows (auth, booking, profile, payments).
- **Risk**: Extending to full MVP flows (auth, booking, history, management) will quickly become unmanageable without a routing/page system and domain separation.
- **Domain logic embedded in UI components**
- API payload construction, validation rules (e.g. for source types), and error handling are implemented directly in `App.jsx` rather than reusable hooks or service modules.
- **Risk**: Code reuse, testing, and evolution (e.g., adding booking pages or admin consoles) will be painful.
- **Minimal test coverage for critical flows**
- Only i18n and hero copy are tested; search behavior, API integration, and payments are untested.
- **Risk**: Regressions in search, booking, and payments UX will slip through as MVP grows.
- **Styling & layout fragility**
- `frontend/src/styles.css` uses `::root` instead of `:root`, which likely breaks intended global CSS variables or base styles.
- Global CSS is tightly bound to the monolithic `App` layout.
- **Risk**: Visual regressions and layout churn when introducing additional pages or components.
- **Ad hoc auth token handling**
- The “access token” is a free-form text field that gets persisted as `auth_token` in `localStorage` and injected into payment requests.
- **Risk**: This is a placeholder pattern that does not scale to full auth (refresh tokens, logout, token rotation) and will need to be replaced.
### Cross-Cutting Risks
- **Lack of async/background processing**
- No Celery/RQ or similar job queue; all side effects are synchronous.
- **Risk**: Scaling SMS/WhatsApp notifications, email, and payment webhook fan-out will be difficult.
- **Observability and admin tooling gaps**
- Errors for payments and notifications are recorded in model metadata but not clearly surfaced in logs, dashboards, or admin views.
- **Risk**: Operational debugging during MVP rollout will be slower and more error-prone.
- **Internationalization strategy vs future markets**
- Phone normalization and defaults are tailored to KSA, which is correct for MVP, but `docs/risks.md` already notes the need to broaden later.
- **Risk**: Without clear boundaries between KSA-specific logic and generic logic, future expansion may require invasive changes.
## MVP Roadmap (Aligned To Phase 1)
This roadmap assumes “MVP” is equivalent to **Phase 1: Core MVP Reliability** in `AGENTS.md`, with a thin but robust frontend on top.
### Phase 0 Architecture & Production Readiness Hardening
- **Finalize critical provider implementations**
- Ensure Authentica OTP/SMS is fully configured and validated end-to-end behind the provider abstraction in `[backend/apps/accounts/services/otp.py](backend/apps/accounts/services/otp.py)`, and wired into `[backend/apps/notifications/services.py](backend/apps/notifications/services.py)`.
- Implement or deliberately fence off `capture_payment` and `refund_payment` in `[backend/apps/payments/services/gateway.py](backend/apps/payments/services/gateway.py)` so that the MVP either fully supports or explicitly does not support partial captures/refunds.
- **Clarify and document boundaries**
- Add a short architecture section in `README`/docs describing how `accounts`, `salons`, `bookings`, `payments`, and `notifications` interact, and what each service is responsible for.
- Resolve the ExecPlan drift by making `AGENTS.md` and `PLANS.md` agree on the current active plan.
- **Introduce minimal async infrastructure (optional but recommended)**
- Decide whether MVP will ship with a task queue (e.g., Celery with Redis) or keep everything synchronous for the initial launch.
- If yes, introduce a thin task layer for OTP sends and booking notifications while preserving current APIs; if not, at least add clear timeouts/logging to external calls.
- **Frontend scaffolding for growth**
- Introduce `react-router` and refactor `App.jsx` into route-based pages (e.g., `HomePage`, `BookPage`, `PaymentPage`, `ProfilePage`), with shared layout and navigation.
- Extract salon search, payment form, and locale controls into dedicated components and hooks.
### Phase 1 Core MVP Features (Backend + Frontend)
- **Phone-first auth UX**
- Backend: reuse existing phone auth endpoints; ensure error messages and rate-limit responses are predictable and localized.
- Frontend:
- Build OTP-based login/registration screens that drive `/api/auth/phone/request/` and `/api/auth/phone/verify/`.
- Introduce an auth context (or similar) to store access/refresh tokens, current user profile, and handle logout.
- Defer social login beyond MVP, but keep API surface ready for it.
- **Booking search and creation**
- Backend is largely ready (booking validation and role-based access); review booking serializers in `[backend/apps/bookings/serializers.py](backend/apps/bookings/serializers.py)` to ensure they expose all fields needed for frontend booking forms.
- Frontend:
- Build a **booking flow**: pick a salon → choose service → select staff (optional) → select date/time slot (based on availability endpoints) → confirm booking.
- Add a “My bookings” page showing upcoming and past bookings, tied into the existing `/api/bookings/` endpoints.
- **Payments via Moyasar**
- Backend: confirm `create_payment_for_booking` contracts (inputs/outputs) are stable and documented.
- Frontend:
- Evolve the payments beta UI into a **post-booking payment step** that starts from a selected booking and guides the user into Moyasars hosted flow, then shows a status page.
- Handle callback/return from Moyasar (even if via manual redirect URL in MVP) and surface payment success/failure to the user.
- **Booking lifecycle notifications**
- Backend already sends notifications on booking create and status changes; align messaging templates with product UX and ensure localization strings exist.
- Frontend: surface notification results implicitly via booking status changes and explicit messages on the booking details page.
- **Localization foundations**
- Backend: ensure `UserLocaleMiddleware` and translation strings cover all user-visible errors in auth, bookings, payments, and notifications.
- Frontend: expand `en/ar-sa` translations to cover auth, booking, and payment flows; verify RTL layouts on the new screens.
- **Tests for critical flows**
- Backend: extend tests where needed to cover new booking/payment edge cases (e.g., tying booking status to payment status if/when introduced).
- Frontend: add Vitest tests for:
- Phone auth screen flows (request/verify success + errors).
- Booking flow (form validation, happy path, displaying server-side errors).
- Payment initiation from an existing booking.
### Phase 2 Manager Ops Lite (Post-MVP, partially covered now)
- **Salon and staff management UI**
- Use existing salon and staff models to build basic management pages for salon owners/managers (create/update services, staff, availability).
- **Calendar views and rescheduling**
- Provide calendar views for staff/managers to view daily/weekly bookings and reschedule or cancel within defined rules.
- **Reviews and ratings**
- Implement review submission and rating recalculation on the backend, with corresponding frontend components.
- **Reporting basics**
- Lightweight reports for managers (upcoming bookings, simple revenue summaries based on payment status) using existing payments data.
### Phase 3 Scale & Compliance (Later)
- **Audit logging** for admin actions and booking/payment state changes.
- **PDPL/GDPR retention policies** and data export tooling.
- **Observability**: structured logging, metrics, and basic dashboards for auth failures, OTP send failures, payment errors, and notification outcomes.
## Architecture Overview Diagram
A simplified view of the target MVP data flow:
```mermaid
flowchart LR
user["User (web/mobile)"] --> frontend["ReactFrontend"]
frontend --> api["DjangoAPI"]
api --> accounts["AccountsApp"]
api --> salons["SalonsApp"]
api --> bookings["BookingsApp"]
api --> payments["PaymentsApp"]
api --> notifications["NotificationsApp"]
accounts --> otpProviders["OtpProviders"]
notifications --> otpProviders
payments --> moyasar["MoyasarGateway"]
bookings --> notifications
bookings --> payments
salons --> bookings
```
This diagram clarifies current coupling and highlights where future refactors (e.g., a dedicated messaging service or payment orchestrator) could sit.
## Validation And Acceptance For This Plan
- The roadmap is accepted when:
- It clearly maps current backend and frontend capabilities to the Phase 1 MVP goals in `AGENTS.md`.
- It identifies the highest-risk design/architecture issues that could impede MVP reliability or future evolution.
- It provides a phased, concrete sequence of work packages that can be implemented via ExecPlans (e.g., booking notifications, Moyasar payments, phone auth UX).
- Each major feature area (auth, bookings, payments, notifications, localization, tests) should have or adopt an ExecPlan under `docs/execplans/` in line with `PLANS.md` before implementation begins.