19 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| salon-mvp-roadmap | High-level roadmap to bring the existing Salon Django/React codebase to a reliable MVP aligned with Phase 1 goals in AGENTS.md, plus a review of current architecture and major risks. |
|
false |
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_apiin[backend/salon_api](backend/salon_api)settings.pyconfiguresAUTH_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
Usermodel 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.
- Custom
- 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.
- Models for
- Bookings (
[backend/apps/bookings](backend/apps/bookings))Bookingmodel ties together salon, service, staff, customer, time window, price, and status.validate_booking_requestin[backend/apps/bookings/services.py](backend/apps/bookings/services.py)enforces staff membership, duration matching, availability windows, and overlap prevention for pending/confirmed bookings.BookingViewSetin[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))Paymentmodel tracks provider, status (fine-grained transitions), amount, idempotency key, external ID, payload, and timestamps.MoyasarGatewayin[backend/apps/payments/services/gateway.py](backend/apps/payments/services/gateway.py)can create payments via HTTP but hascapture_payment/refund_paymentas TODOs.create_payment_for_bookingin[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))Notificationmodel 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 viapreferred_language. - Booking views call
notify_booking_lifecycle/notify_on_status_changeto 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)).
- Phone normalization, OTP rate limiting, and phone auth flows (
docs/risks.mdexplicitly tracks several known gaps around auth, booking, payments, data/UX, and ops.
- Solid tests around:
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-routeror multi-page routing; the entire experience is one composed screen.
- Vite React app at
- 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.
- Text search field calling
- Localization/i18n
react-i18nextsetup in[frontend/src/i18n/index.js](frontend/src/i18n/index.js)withenandar-satranslations.- Locale preference stored in
localStorage; applieslanganddiron the document.
- Payments beta
- A form in
App.jsxthat sends payment creation requests to/api/payments/using the Moyasar-style payload, with configurablebooking_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_urland shows the raw JSON response.
- A form in
- Salon search
- State & Tests
- All state is local to
App.jsxviauseState/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.
- All state is local to
Glaring Design And Architectural Issues
Backend Risks
- Incomplete provider implementations for production-critical flows
- Twilio/Unifonic providers in
[backend/apps/accounts/services/otp.py](backend/apps/accounts/services/otp.py)are stubs withNotImplementedErrorfor send methods, yet they are the backbone for both OTP and booking notifications. MoyasarGatewaylackscapture_paymentandrefund_paymentimplementations, 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.
- Twilio/Unifonic providers in
- Tight coupling between OTP and notifications
- Notification services import the OTP provider mapping and default
NOTIFICATION_PROVIDERtoOTP_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.
- Notification services import the OTP provider mapping and default
- 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.
- OTP sends, booking notifications, and payment gateway calls all occur synchronously inside view methods (
- Cross-app domain coupling without a clear orchestration layer
apps.bookingsdepends 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_FIELDis 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.mdreferencesdocs/execplans/payments-moyasar.mdas the active plan, whilePLANS.mdnamesdocs/execplans/booking-notifications.md.- Risk: Contributors may follow different “active” plans, causing architectural inconsistency.
Frontend Risks
- Monolithic
Appcomponent with no routingApp.jsxmixes hero/search, salon listing, payments, and locale controls.- There is no
react-routeror 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.jsxrather than reusable hooks or service modules. - Risk: Code reuse, testing, and evolution (e.g., adding booking pages or admin consoles) will be painful.
- API payload construction, validation rules (e.g. for source types), and error handling are implemented directly in
- 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.cssuses::rootinstead of:root, which likely breaks intended global CSS variables or base styles.- Global CSS is tightly bound to the monolithic
Applayout. - 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_tokeninlocalStorageand 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.
- The “access token” is a free-form text field that gets persisted as
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.mdalready notes the need to broaden later. - Risk: Without clear boundaries between KSA-specific logic and generic logic, future expansion may require invasive changes.
- Phone normalization and defaults are tailored to KSA, which is correct for MVP, but
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
- Implement at least one real SMS/WhatsApp provider (Twilio or Unifonic) end-to-end, behind the existing provider abstraction in
[backend/apps/accounts/services/otp.py](backend/apps/accounts/services/otp.py), and wire it into[backend/apps/notifications/services.py](backend/apps/notifications/services.py). - Implement or deliberately fence off
capture_paymentandrefund_paymentin[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.
- Implement at least one real SMS/WhatsApp provider (Twilio or Unifonic) end-to-end, behind the existing provider abstraction in
- Clarify and document boundaries
- Add a short architecture section in
README/docs describing howaccounts,salons,bookings,payments, andnotificationsinteract, and what each service is responsible for. - Resolve the ExecPlan drift by making
AGENTS.mdandPLANS.mdagree on the current active plan.
- Add a short architecture section in
- 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-routerand refactorApp.jsxinto 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.
- Introduce
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.
- Build OTP-based login/registration screens that drive
- 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.
- Backend is largely ready (booking validation and role-based access); review booking serializers in
- Payments via Moyasar
- Backend: confirm
create_payment_for_bookingcontracts (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 Moyasar’s 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.
- Backend: confirm
- 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
UserLocaleMiddlewareand translation strings cover all user-visible errors in auth, bookings, payments, and notifications. - Frontend: expand
en/ar-satranslations to cover auth, booking, and payment flows; verify RTL layouts on the new screens.
- Backend: ensure
- 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:
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).
- It clearly maps current backend and frontend capabilities to the Phase 1 MVP goals in
- Each major feature area (auth, bookings, payments, notifications, localization, tests) should have or adopt an ExecPlan under
docs/execplans/in line withPLANS.mdbefore implementation begins.