Architecture Overview¶
The Freeze Design webshop is a custom apparel e-commerce platform with an integrated product designer.
Design Principles¶
- API-First - All functionality exposed via REST API
- Component-Based - Reusable React components
- Type-Safe - TypeScript throughout the frontend
- Scalable - Stateless backend with async task processing
System Components¶
Frontend (Next.js)¶
The frontend is a Next.js 16.2.12 application using React 19.2.8 and the App Router.
Key Features:
- Server-side rendering for SEO
- Fabric.js canvas for product designer
- React Context for client state (auth, cart, team orders, theme)
- TanStack Query for API data
Backend (Django REST Framework)¶
Django 6.0.7 + Django REST Framework 3.17.1 provide the REST API and admin interface.
Key Features:
- RESTful API design
- django-allauth headless authentication
- Celery for async tasks (backups, WebP image generation, monitoring)
- PostgreSQL 15 with MPTT for categories
Data Flow¶
sequenceDiagram
participant U as User
participant F as Frontend
participant A as API
participant D as Database
participant M as Mollie
U->>F: Browse Products
F->>A: GET /api/products/
A->>D: Query Products
D-->>A: Product List
A-->>F: JSON Response
F-->>U: Render Page
U->>F: Submit Order
F->>A: POST /api/orders/checkout/
A->>D: Create Order
A->>M: Create Payment
M-->>A: Checkout URL
A-->>F: Redirect to Mollie
U->>M: Complete Payment
M->>A: Webhook (payment status)
A->>D: Update Order Status
A->>A: Send Confirmation via Resend
Security Architecture¶
- HTTPS enforced (Let's Encrypt with automated renewal)
- CSRF protection for mutations
- Rate limiting (DRF anon/user throttles, stricter scoped throttle on checkout)
- Content Security Policy headers (django-csp)
- Input validation at API level
- MFA support for admin accounts (django-allauth MFA), login lockout via django-axes
Deployment Architecture¶
There is currently a single deployed environment: staging at
https://staging.freezedesign.nl. A production VPS (Hetzner CX43) has been
provisioned and hardened, but nothing has been deployed to it yet.
See Deployment Guide for setup details.
Production is planned, not live
Production will be a single domain, freezedesign.nl, serving both
frontend and API under /api — no separate api. subdomain, matching
the staging model. Ahead of the DNS cutover it will be built and tested
on prod.freezedesign.nl. Until cutover, staging is the only real
environment and the production deploy workflow is disabled.
System Overview¶
Freeze Design is a layered web application. A Next.js storefront and staff interface call a Django REST API; Django persists commerce data in PostgreSQL, uses Redis for caching and Celery coordination, and delegates payment, email, object-storage, analytics, and error-reporting concerns to configured external services. Browser requests enter through Nginx in deployed environments and return HTML, JSON, media, or generated PDF documents.
Component Diagram¶
flowchart LR
user[Customer or staff browser] --> nginx[Nginx]
nginx --> frontend[Next.js frontend]
frontend --> api[Django REST API]
api --> postgres[(PostgreSQL)]
api --> redis[(Redis)]
api --> celery[Celery workers and beat]
celery --> redis
api --> mollie[Mollie]
api --> resend[Resend]
api --> spaces[Object storage]
Data Flow¶
- The browser renders a storefront or admin route from the Next.js App Router.
- Frontend API clients send session-aware requests to Django under
/api/or to django-allauth under/_allauth/. - View sets and service modules validate the request, apply business rules, and read or write Django models in PostgreSQL.
- Redis supplies cache/session data and coordinates asynchronous Celery work where a request should not do the work inline.
- The API returns serialized JSON or a file response; the frontend updates TanStack Query, React Context, or local Zustand state and rerenders.
Key Abstractions¶
| Area | Location | Responsibility |
|---|---|---|
| Django URL composition | backend/config/urls.py |
Mounts routers, authentication, health, payment, invoice, schema, and admin endpoints. |
| Django settings | backend/config/settings.py |
Loads environment-specific application, security, storage, cache, Celery, and monitoring configuration. |
| Commerce services | backend/apps/*/services.py |
Encapsulate order, payment, invoice, quote, pricing, user, and related business workflows. |
| API serializers and views | backend/apps/*/serializers.py, backend/apps/*/views.py |
Define external request/response contracts and endpoint behavior. |
| Frontend API layer | frontend/lib/api/ |
Centralizes browser-to-backend requests for storefront and admin features. |
| Query hooks | frontend/hooks/api/ |
Wrap API operations in TanStack Query caching and mutations. |
| Product designer | frontend/components/ProductDesigner/ |
Manages Fabric.js canvas editing, print zones, previews, and cart/design integration. |
Directory Structure Rationale¶
backend/ Django project, domain apps, migrations, tests, and operational commands
frontend/ Next.js routes, UI components, API clients, state, and browser tests
docs/docs/ MkDocs source grouped by architecture, guides, API, QA, and runbooks
scripts/ Setup, release, backup, deployment, health, and maintenance automation
loadtests/ k6 scenarios and recorded baseline results
nginx/ Reverse-proxy configuration for staging and production
.github/workflows/ CI, documentation, security, backup, and deployment automation
Backend domain boundaries follow Django apps, while frontend boundaries separate routes from reusable components, remote-data hooks, and client state. Operational assets remain at repository level because they coordinate both runtimes.