Files
Salon/external-review.md
T
2026-02-28 15:33:18 +03:00

19 KiB
Raw Blame History

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.
id content status
backend-providers-readiness Harden backend providers: implement at least one real SMS/WhatsApp provider and clarify Moyasar capture/refund behavior for MVP. pending
id content status
async-and-observability Decide on async task infrastructure and observability basics for OTP, notifications, and payments, and document the choice. pending
id content status
frontend-structure-and-routing Refactor frontend into routed pages with separated components/hooks for search, auth, booking, and payments. pending
id content status
auth-and-booking-flows Implement phone-first auth and end-to-end booking flows on the frontend using existing backend APIs. pending
id content status
payments-and-notifications-ux Integrate payment initiation and booking lifecycle notifications into user-facing flows, including success/error handling. pending
id content status
tests-for-critical-flows Expand backend and frontend tests to cover auth, booking, payment, and notification critical paths for MVP reliability. pending
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_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
    • Twilio/Unifonic providers in [backend/apps/accounts/services/otp.py](backend/apps/accounts/services/otp.py) are stubs with NotImplementedError for send methods, yet they are the backbone for both OTP and booking notifications.
    • 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
    • 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_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:

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.