Skip to content

Architecture

[!abstract] Summary Unicorn Trails is a full-stack application with a .NET backend, React frontend, PostgreSQL database, and Cloudflare R2 storage.

System Overview

graph TB
    subgraph Client["Frontend"]
        React[React SPA]
        SW[Service Worker]
    end

    subgraph Edge["Edge Layer"]
        CDN[Cloudflare CDN]
        Nginx[Nginx]
    end

    subgraph Server["Backend"]
        API[ASP.NET Core API]
        MediatR[MediatR Pipeline]
        EF[EF Core]
        Hangfire[Hangfire Jobs]
    end

    subgraph Storage["Data Layer"]
        PG[(PostgreSQL)]
        R2[(Cloudflare R2)]
        Cache[(Memory Cache)]
    end

    React --> CDN
    CDN --> Nginx
    Nginx --> API
    SW -.-> React
    API --> MediatR
    MediatR --> EF
    MediatR --> Cache
    EF --> PG
    Hangfire --> PG
    Hangfire --> R2
    API --> R2

Components

Component Technology Purpose
Frontend React, TypeScript, Vite User interface
Edge Nginx Static serving, CSP headers, SPA routing
Backend ASP.NET Core REST API
Database PostgreSQL Persistent storage
File Storage Cloudflare R2 Images and files
Background Jobs Hangfire Async processing
Caching Memory Cache Response caching
Email Resend Transactional emails
CAPTCHA Cloudflare Turnstile Bot protection
Error Tracking Sentry Error monitoring (optional)
Geocoding GeoCode API Reverse geocoding (optional)

Nginx

The frontend is served via Nginx which handles:

  • Static file serving (React build)
  • SPA routing (fallback to index.html)
  • Gzip compression
  • CSP headers (Content Security Policy)
  • Cache headers for assets

Backend Architecture

The backend follows a vertical slice architecture with CQRS pattern:

Application/Features/{Feature}/
├── Commands/     # Write operations
├── Queries/      # Read operations
├── Models/       # DTOs
└── Validators/   # Request validation

Request Flow

flowchart TB
    A[HTTP Request] --> B[Middleware Pipeline]
    B --> C[Controller]
    C --> D[MediatR]
    D --> E[Behaviors]
    E --> F[Handler]
    F --> G[EF Core]
    G --> H[Interceptors]
    H --> I[(Database)]

    B -.->|Security Headers| B1[SecurityHeadersMiddleware]
    B -.->|Correlation ID| B2[CorrelationIdMiddleware]
    B -.->|Error Handling| B3[GlobalExceptionHandler]

    E -.->|Validation| E1[ValidationBehavior]
    E -.->|Caching| E2[CachingBehavior]
    E -.->|Auth| E3[UserIdBehavior]

    H -.->|Audit| H1[AuditableInterceptor]
    H -.->|Soft Delete| H2[SoftDeleteInterceptor]

See CQRS Pattern for implementation details.

Frontend Architecture

The frontend uses:

  • TanStack Query — Server state management
  • Zustand — Client state management
  • React Hook Form — Form handling
  • MUI — Component library

Data Flow

flowchart TB
    subgraph Components
        A[Page Component]
        B[Form Component]
        C[List Component]
    end

    subgraph State
        D[TanStack Query]
        E[Zustand Store]
    end

    subgraph API
        F[API Client]
        G[Error Handler]
    end

    A --> D
    B --> E
    C --> D
    D --> F
    E --> F
    F --> G
    G -->|Success| D
    G -->|Error| H[Toast/Form Errors]