Desi-Clans/docs/ARCHITECTURE.md
2026-10-08 02:52:58 +05:30

9 KiB

Architecture — Desi Clans

Version: 1.0
Last updated: 2026-04-04


1. System context

┌─────────────┐     HTTPS      ┌──────────────┐     SQL      ┌────────────┐
│   Browser   │ ──────────────► │  FastAPI API │ ◄──────────► │ PostgreSQL │
│  (React)    │                 │  + static    │              └────────────┘
└─────────────┘                 │    media     │
       │                        └──────┬───────┘
       │                               │
       │         optional              ▼
       └──────────────────────► S3 / CDN (prod media)
  • Monorepo: frontend/, backend/, docs/.
  • Deployment unit: API container + static frontend (CDN or same origin) + managed Postgres.
  • No microservices in v1. One API process, clear router boundaries for future split.

2. Architectural principles

  1. API-first content — Public UI never hardcodes event copy or images.
  2. Thin client — Business rules (inventory, check-in) live in the backend.
  3. Explicit phases — Ship discovery + admin before native payments if needed.
  4. Boring tech — Stack locked to PRD; no extra frameworks without ADR.
  5. Security defaults — JWT for auth, parameterized SQL via SQLAlchemy, validated Pydantic I/O.

3. Repository layout (target)

DESI-CLANS/
├── frontend/
│   ├── public/
│   ├── src/
│   │   ├── api/           # Axios clients, types mirroring API_SPEC
│   │   ├── components/    # UI primitives + composites
│   │   ├── hooks/
│   │   ├── layouts/
│   │   ├── pages/         # Route-level views
│   │   ├── styles/        # Tailwind entry, tokens
│   │   ├── utils/         # seo, dates, formatters
│   │   ├── animations/    # GSAP contexts, ScrollTrigger setup
│   │   ├── App.jsx
│   │   └── main.jsx
│   ├── index.html
│   ├── vite.config.js
│   ├── tailwind.config.js
│   └── package.json
├── backend/
│   ├── alembic/
│   ├── app/
│   │   ├── routers/       # public, auth, admin, share, analytics, orders (future)
│   │   ├── services/      # domain logic
│   │   ├── models.py
│   │   ├── schemas.py
│   │   ├── auth.py
│   │   ├── config.py
│   │   ├── database.py
│   │   └── main.py
│   ├── scripts/           # seed, migrate helpers
│   ├── tests/
│   ├── Dockerfile
│   └── requirements.txt
├── docs/
└── README.md

4. Backend layers

Layer Responsibility
Routers HTTP, status codes, dependency injection, no business logic
Services Transactions, orchestration (editions, media, tickets, email)
Models SQLAlchemy ORM, enums
Schemas Pydantic request/response; never expose hashed passwords

Cross-cutting

  • config.py — settings from environment (see .env.example when added).
  • auth.py — JWT create/verify, get_current_admin, future get_current_user.
  • Migrations — Alembic only; avoid create_all in production (dev convenience may exist temporarily).

5. Frontend layers

Layer Responsibility
Pages Data loading per route, SEO hooks, layout composition
Components Presentational; accept props, no direct Axios in leaf components
api/ Base Axios instance, interceptors for admin token
animations/ GSAP timelines registered once; respect prefers-reduced-motion

Routing (React Router)

  • Public: /, /events, /events/:slug, /subscribe (optional dedicated page)
  • Admin: /admin/login, /admin/* (protected)
  • Account (phase): /account, /account/tickets/:id
  • Check-in (phase): /admin/check-in or staff-only route

SEO

  • Vite SPA: use react-helmet-async only if needed; prefer minimal approach:
    • Default meta in index.html
    • Per-route document.title + meta updates in page useEffect
    • Backend /share/events/{slug} HTML for crawlers (already planned in API)

6. API boundaries

Namespace Auth Purpose
/api/public/* None Read editions, config, subscribe, outbound redirect, calendar
/api/auth/* Credentials Admin login (attendee login added with ticketing)
/api/admin/* Admin JWT CRUD editions, media, links, users, subscribers
/api/admin/analytics/* Admin JWT Click summaries
/share/events/{slug} None OG HTML for social crawlers
/api/orders/* (future) User JWT Checkout, my tickets
/api/check-in/* (future) Staff JWT Validate QR, mark checked in

Public reads are cache-friendly (CDN Cache-Control on GET editions list with short TTL).


7. Media pipeline

  1. Admin uploads via multipart → service stores file.
  2. Local: upload_dir served at /media/...
  3. Production: S3 bucket + public or signed URLs; store file_path key in DB.
  4. Optional thumbnails generated on upload (service layer); expose thumb_url in API.

8. Ticketing architecture (target)

EventEdition ──< TicketTier
                    │
Order ──────────────┼──< OrderLine (tier, qty, unit_price)
  │
  └──< Ticket (code, qr_secret, status, checked_in_at)

Checkout flow (native)

  1. Client POST order intent with tier + quantity.
  2. Server validates window, inventory; creates pending order; returns payment session (phase B).
  3. Webhook confirms payment → status paid → issue tickets with unique codes.
  4. Email service sends QR (PNG or link to ticket page).

QR validation

  • Payload: ticket_id + HMAC signature (server secret).
  • Scan endpoint: verify signature, edition match, status issued → checked_in.

Outbound mode (per edition flag)

  • ticketing_mode: outbound | native
  • Outbound uses existing bookmyshow_url, district_url, etc., via /api/public/go click tracking.

9. Security

  • Passwords: bcrypt via passlib.
  • JWT: HS256, ACCESS_TOKEN_EXPIRE_MINUTES configurable.
  • CORS: explicit origin list from env.
  • Rate limit: add at reverse proxy (nginx/Cloudflare) for public POST subscribe and auth login.
  • Admin actions audited via structured logs (user id, action, entity id).

10. Performance requirements

Area Target
Public GET editions p95 < 300ms @ warm DB
Image delivery WebP/AVIF where supported; width variants
Frontend bundle Route-based code splitting for admin
DB Indexes on slug, event_type, is_published, event_date
Animation GSAP only on hero/key sections; disable heavy ScrollTrigger on mobile low power

11. Observability

  • Health: GET /api/public/health
  • Structured JSON logs (request id, path, status, duration)
  • Production: disable OpenAPI UI (openapi_url = None when environment=production)

12. Coding conventions

Python (backend)

  • Python 3.11+
  • Type hints on public functions
  • ruff or flake8 + black (pick one formatter in CI)
  • Router functions: max ~30 lines; delegate to services
  • Enums in models.py for DB enums; mirror in Pydantic where needed

JavaScript (frontend)

  • React 18 functional components only
  • Named exports for components; default export for pages optional
  • Tailwind for styling; no CSS-in-JS library
  • Axios instance with baseURL from import.meta.env.VITE_API_URL
  • Env vars prefixed VITE_ only for client-safe values

Git

  • Conventional commits encouraged: feat:, fix:, docs:
  • One Alembic revision per schema change

13. Implementation phases

Phase 0 — Constitution (current)

Documentation only; no new application features.

Phase 1 — Public experience + admin content

  • Vite + React + Tailwind + Router
  • Wire public API: home, list, detail, subscribe, outbound go links
  • Admin: login, edition CRUD, media upload
  • Share previews + basic SEO
  • Aligns with partial backend already in repo

Phase 2 — Polish & performance

  • GSAP hero + scroll sections with reduced-motion guard
  • Image lazy loading, skeleton states
  • Accessibility pass (focus, contrast, aria labels)

Phase 3 — Native ticketing

  • DB: tiers, orders, tickets
  • Attendee auth
  • Checkout + payment webhook
  • Ticket page + QR generation
  • Staff check-in UI

Phase 4 — Hardening

  • E2E smoke tests, load test on read paths
  • CDN, backup strategy, runbooks

14. ADR policy

Significant deviations (new dependency, new service, auth model change) require a short docs/adr/NNN-title.md before implementation.