Files
trakqr/docs/architecture.md

2.9 KiB

TrakQR Architecture Guidelines

Core Principles

1. Modular Monolith

The application is structured as a modular monolith where each feature/domain is self-contained but runs in a single deployable unit.

This provides:

  • Clear boundaries between features
  • Easy refactoring to microservices if needed later
  • Simplified deployment and operations

2. Vertical Slice Architecture

Code is organized by feature (vertical slices), not by technical layer (horizontal).

Each feature contains everything it needs:

  • Endpoint definitions
  • Request/Response models
  • Business logic
  • Validators
/Features
  /Auth
    /Endpoints
      SmallEndpoint.cs (contains Request, Response, Validator and Endpoint)
    /Register
      Endpoint.cs
      Request.cs
      Response.cs
      Validator.cs
    /Login
      ...
  /Links
    /Create
      ...
    /List
      ...
  /QRCodes
    ...

3. Minimal API with FastEndpoints

We use FastEndpoints instead of traditional MVC Controllers because:

  • Better performance (no reflection-based model binding)
  • Cleaner, more focused endpoint classes
  • Built-in validation with FluentValidation
  • Request/Response DTOs are co-located with endpoints
  • Easier testing

4. No Traditional Controllers

DO NOT use [ApiController] or ControllerBase. All HTTP endpoints must be FastEndpoints.

Module Structure

Each feature module should be fully self-contained. All code related to a feature lives within that feature's folder:

/Features/{Module}/
  - {Module}Responses.cs   # Shared response DTOs for this module
  - {Module}Settings.cs    # Configuration classes for this module
  /{Operation}/
    - Endpoint.cs          # The FastEndpoint class
    - Request.cs           # Input DTO
    - Validator.cs         # FluentValidation rules

Example - Auth module:

/Features/Auth/
  - AuthResponses.cs       # AuthResponse, UserInfo, MessageResponse
  - JwtSettings.cs         # JWT configuration
  /Register/
    - Endpoint.cs
    - Request.cs
    - Validator.cs
  /Login/
    - Endpoint.cs
    - Request.cs
    - Validator.cs

For simple operations, business logic lives directly in the Endpoint class. For complex logic, add a Handler.cs or Service.cs within the same feature folder.

Shared Infrastructure

Only truly cross-cutting infrastructure goes outside Features:

  • /Data - DbContext, migrations (shared database access)
  • /Models - EF Core entities (shared domain model)

Dependency Injection

  • Use constructor injection
  • Register services in Program.cs or feature-specific extension methods
  • Prefer scoped services for request-specific work

Validation

  • Use FluentValidation via FastEndpoints' built-in support
  • Validate at the endpoint level, not in services
  • Return 400 Bad Request with structured error responses

Authentication

  • JWT Bearer tokens for API authentication
  • Claims-based authorization
  • User ID extracted from JWT sub claim