# Architecture AzioneLab is a public website for a theatre company with a small booking system for performances. The architecture is intentionally simple: one Django backend, one Angular frontend, one PostgreSQL database, and nginx as the public reverse proxy. There is no Celery, Redis, message broker, or separate worker service at this stage. ## Components ### Public frontend The public frontend is an Angular application using Angular Material. Responsibilities: - render descriptive pages for the theatre company; - render the public list of shows; - render public show and performance detail pages; - provide the booking form for a selected performance; - show reservation submission, confirmation, and check-in feedback states; - call the backend through REST APIs. The frontend must not calculate authoritative availability. It may display availability returned by the backend, but the backend remains responsible for final capacity validation. ### Backend API The backend is a Django 5.2 LTS application using Django REST Framework. The initial backend skeleton lives under `backend/` and includes the Django project, Django admin, the `shows`, `bookings`, and `checkins` apps, CORS configuration for the Angular frontend, PostgreSQL configuration through environment variables, and a health endpoint at `/api/health/`. Responsibilities: - expose public read APIs for shows, venues, and performances; - expose public booking and reservation confirmation APIs; - expose an authenticated check-in verification API; - provide Django admin or an equivalent authenticated administration area; - store reservations, tokens, and check-in state; - calculate performance availability server-side; - send reservation confirmation emails; - generate QR codes after reservation confirmation. The backend runs with gunicorn in production. ### Administration area The first administration area should use Django admin unless a custom Angular admin becomes necessary later. Administrators can manage: - shows; - venues; - performances; - total room capacity; - manually occupied seats; - optional additional seats available during booking; - reservation status and check-in records when operationally necessary. Admin functionality must require authenticated staff access. ### Database PostgreSQL is the system of record. It stores: - show and venue content; - performance scheduling and capacity configuration; - reservations and explicit reservation status; - reservation tokens used for confirmation and QR verification; - check-in records. Capacity checks must happen inside database transactions to avoid overbooking when multiple users book at the same time. ### Email The backend sends transactional emails for: - reservation confirmation link after booking submission; - optional confirmation success email containing the QR code or QR verification link. Email delivery can use Django's email backend configuration. No asynchronous email worker is required initially; failures should be logged without exposing tokens or personal data. ### QR code generation The backend generates QR codes using a small Python library such as `qrcode` or `segno`. QR codes must contain only an opaque token or verification URL. They must not contain names, email addresses, phone numbers, notes, or other personal data. ### nginx nginx is the public entry point. Responsibilities: - terminate HTTP traffic, and TLS when configured; - serve the built Angular static assets; - reverse proxy API and admin requests to gunicorn; - serve static and media files according to the deployment configuration. ## Runtime Dependencies Required runtime dependencies: - Python; - Django 5.2 LTS; - Django REST Framework; - gunicorn; - PostgreSQL; - Angular; - Angular Material; - nginx; - Docker Compose; - a Python QR code library such as `qrcode` or `segno`; - an SMTP-compatible email provider or relay. Not included at this stage: - Celery; - Redis; - background workers; - separate search, cache, or queue services. ## Data Flow 1. A visitor opens the website through nginx. 2. nginx serves the Angular frontend. 3. The frontend calls public backend API endpoints for shows and performances. 4. The visitor submits a booking form for a specific performance. 5. The backend validates input, checks capacity server-side, creates a pending reservation, creates a confirmation token, and sends a confirmation email. 6. The visitor opens the confirmation link. 7. The backend validates the token, confirms the reservation if capacity is still available, and generates a QR code token or QR code image. 8. The visitor presents the QR code at the venue using a smartphone or printed copy. 9. Staff scans the QR code. 10. The backend validates the token and records a check-in if the reservation is confirmed and not already checked in. ## Deployment Topology The initial deployment uses Docker Compose with these services: - `nginx`: public reverse proxy and static frontend server; - `frontend`: Angular build stage or static asset build source; - `backend`: Django application served by gunicorn; - `postgres`: PostgreSQL database. Only nginx should be publicly exposed. The backend and database should be reachable only on the internal Compose network. The initial Compose files live under `infra/docker/`. The backend and frontend images are placeholders until the Django and Angular applications are implemented. ## Architectural Constraints - Keep the booking workflow synchronous and explicit. - Keep all capacity validation on the backend. - Store reservation status explicitly. - Use opaque, random, non-guessable tokens. - Do not place personal data in QR codes. - Avoid optional infrastructure until the project needs it. - Prefer Django admin for internal management before building custom admin UI. ## Relevant ADRs - [ADR-0001: Use Django Monolith](adr/0001-use-django-monolith.md) - [ADR-0002: Do Not Add an Async Task Queue Yet](adr/0002-no-async-task-queue.md) - [ADR-0003: Use Opaque Tokens in QR Codes](adr/0003-qr-code-token-strategy.md) - [ADR-0004: Use Email Confirmation for Reservations](adr/0004-email-confirmation-flow.md) - [ADR-0007: Use Docker Compose for Deployment](adr/0007-use-docker-compose-for-deployment.md)