Skip to content

Architecture Overview

The Freeze Design webshop is a custom apparel e-commerce platform with an integrated product designer.

Design Principles

  1. API-First - All functionality exposed via REST API
  2. Component-Based - Reusable React components
  3. Type-Safe - TypeScript throughout the frontend
  4. 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

  1. The browser renders a storefront or admin route from the Next.js App Router.
  2. Frontend API clients send session-aware requests to Django under /api/ or to django-allauth under /_allauth/.
  3. View sets and service modules validate the request, apply business rules, and read or write Django models in PostgreSQL.
  4. Redis supplies cache/session data and coordinates asynchronous Celery work where a request should not do the work inline.
  5. 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.