Skip to content

πŸ—οΈ Mario's Pizzeria: Technical ArchitectureΒΆ

System Design Document > Architecture: Clean Architecture + CQRS + Event Sourcing Technology Stack: FastAPI, Python, MongoDB, OAuth 2.0 Status: Production Ready

πŸ“‹ Source Code: View Complete Implementation


πŸ’‘ Pattern in Action: This document demonstrates Clean Architecture layer separation with the Repository Pattern for data access abstraction and Event-Driven Architecture for scalability.


πŸ“‹ Architecture OverviewΒΆ

Mario's Pizzeria implements a modern, scalable architecture following clean architecture principles with CQRS (Command Query Responsibility Segregation) and event-driven patterns. This design ensures maintainability, testability, and scalability for a growing restaurant business.

Key Architectural Decisions:

⚠️ Architecture Principle: Dependencies point INWARD only (API β†’ Application β†’ Domain ← Integration). The domain layer has ZERO dependencies on outer layers! See Clean Architecture for why this matters.


πŸ›οΈ Clean Architecture LayersΒΆ

Mario's Pizzeria demonstrates the four-layer clean architecture:

graph TB
    %% API Layer
    subgraph APILayer["🌐 API Layer"]
        OrdersController["πŸ“‹ OrdersController<br/>FastAPI<br/>Order management endpoints"]
        MenuController["πŸ• MenuController<br/>FastAPI<br/>Menu browsing endpoints"]
        KitchenController["πŸ‘¨β€πŸ³ KitchenController<br/>FastAPI<br/>Kitchen status endpoints"]
        DTOs["πŸ“„ DTOs<br/>Pydantic<br/>Request/Response models"]
    end

    %% Application Layer
    subgraph AppLayer["πŸ’Ό Application Layer"]
        Mediator["🎯 Mediator<br/>CQRS<br/>Command/Query dispatcher"]
        PlaceOrderHandler["πŸ“ PlaceOrderHandler<br/>Command Handler<br/>Order placement logic"]
        GetMenuHandler["πŸ“– GetMenuHandler<br/>Query Handler<br/>Menu retrieval logic"]
        KitchenHandlers["⚑ KitchenHandlers<br/>Event Handlers<br/>Kitchen workflow"]
    end

    %% Domain Layer
    subgraph DomainLayer["πŸ›οΈ Domain Layer"]
        OrderEntity["πŸ“‹ Order<br/>AggregateRoot<br/>Order business logic"]
        PizzaEntity["πŸ• Pizza<br/>AggregateRoot<br/>Pizza with pricing"]
        CustomerEntity["πŸ‘€ Customer<br/>AggregateRoot<br/>Customer information"]
        KitchenEntity["🏠 Kitchen<br/>Entity<br/>Kitchen capacity"]
        DomainEvents["⚑ Domain Events<br/>Events<br/>OrderPlaced, OrderReady"]
    end

    %% Integration Layer
    subgraph IntegrationLayer["πŸ”Œ Integration Layer"]
        OrderRepo["πŸ’Ύ OrderRepository<br/>File/Mongo<br/>Order persistence"]
        PaymentService["πŸ’³ PaymentService<br/>External API<br/>Payment processing"]
        SMSService["πŸ“± SMSService<br/>External API<br/>Customer notifications"]
    end

    %% API to Application connections
    OrdersController -->|Sends commands/queries| Mediator
    MenuController -->|Sends queries| Mediator
    KitchenController -->|Sends queries| Mediator

    %% Application Layer connections
    Mediator -->|Routes PlaceOrderCommand| PlaceOrderHandler
    Mediator -->|Routes GetMenuQuery| GetMenuHandler
    Mediator -->|Routes events| KitchenHandlers

    %% Application to Domain connections
    PlaceOrderHandler -->|Creates/manipulates| OrderEntity
    GetMenuHandler -->|Reads menu data| PizzaEntity

    %% Application to Integration connections
    PlaceOrderHandler -->|Persists orders| OrderRepo
    PlaceOrderHandler -->|Processes payments| PaymentService
    KitchenHandlers -->|Sends notifications| SMSService

    %% Styling
    classDef apiLayer fill:#E3F2FD,stroke:#1976D2,stroke-width:2px
    classDef appLayer fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px
    classDef domainLayer fill:#E8F5E8,stroke:#388E3C,stroke-width:2px
    classDef integrationLayer fill:#FFF3E0,stroke:#F57C00,stroke-width:2px

    class OrdersController,MenuController,KitchenController,DTOs apiLayer
    class Mediator,PlaceOrderHandler,GetMenuHandler,KitchenHandlers appLayer
    class OrderEntity,PizzaEntity,CustomerEntity,KitchenEntity,DomainEvents domainLayer
    class OrderRepo,PaymentService,SMSService integrationLayer

πŸ—„οΈ Data Storage StrategyΒΆ

Mario's Pizzeria demonstrates multiple persistence approaches to support different deployment scenarios:

File-Based Storage (Development)ΒΆ

Perfect for development and testing environments with simple JSON persistence:

pizzeria_data/
β”œβ”€β”€ orders/
β”‚   β”œβ”€β”€ 2024-09-22/           # Orders by date
β”‚   β”‚   β”œβ”€β”€ order_001.json
β”‚   β”‚   β”œβ”€β”€ order_002.json
β”‚   β”‚   └── order_003.json
β”‚   └── index.json            # Order index
β”œβ”€β”€ menu/
β”‚   └── pizzas.json           # Available pizzas
β”œβ”€β”€ kitchen/
β”‚   └── status.json           # Kitchen state
└── customers/
    └── customers.json        # Customer history

Benefits: Zero configuration, version control friendly, fast local development

MongoDB Storage (Production)ΒΆ

Scalable document database for production workloads:

// Orders Collection
{
  "_id": "order_001",
  "customer_name": "Mario Rossi",
  "customer_phone": "+1-555-0123",
  "pizzas": [
    {
      "name": "Margherita",
      "size": "large",
      "toppings": ["extra cheese"],
      "price": 15.99
    }
  ],
  "total_amount": 15.99,
  "status": "ready",
  "order_time": "2025-09-25T10:30:00Z"
}

Benefits: Horizontal scaling, rich queries, built-in replication, ACID transactions

Event Sourcing (Advanced)ΒΆ

Complete audit trail and temporal queries using event streams:

Event Store:
β”œβ”€β”€ order_001_stream
β”‚   β”œβ”€β”€ OrderPlacedEvent
β”‚   β”œβ”€β”€ PaymentProcessedEvent
β”‚   β”œβ”€β”€ OrderConfirmedEvent
β”‚   β”œβ”€β”€ CookingStartedEvent
β”‚   └── OrderReadyEvent

Benefits: Complete audit trail, temporal queries, replay capability, debugging

🌐 API Endpoints¢

Complete RESTful API designed for different client types (web, mobile, POS systems):

Order ManagementΒΆ

Method Endpoint Description Auth Required
POST /orders Place new pizza order Customer
GET /orders List orders (with status filter) Staff
GET /orders/{id} Get specific order details Owner/Customer
PUT /orders/{id}/status Update order status Kitchen
DELETE /orders/{id} Cancel order Customer/Manager
Method Endpoint Description Auth Required
GET /menu/pizzas Get available pizzas Public
GET /menu/pizzas/{id} Get pizza details Public
GET /menu/toppings Get available toppings Public

Kitchen ManagementΒΆ

Method Endpoint Description Auth Required
GET /kitchen/status Get kitchen capacity status Staff
GET /kitchen/queue Get current cooking queue Kitchen
POST /kitchen/orders/{id}/start Start cooking order Kitchen
POST /kitchen/orders/{id}/complete Complete order Kitchen

πŸ” Security ArchitectureΒΆ

OAuth 2.0 ScopesΒΆ

Fine-grained access control using OAuth2 scopes:

SCOPES = {
    "orders:read": "Read order information",
    "orders:write": "Create and modify orders",
    "kitchen:read": "View kitchen status",
    "kitchen:manage": "Manage kitchen operations",
    "menu:read": "View menu items",
    "admin": "Full administrative access"
}

Role-Based Access ControlΒΆ

Role Scopes Permissions
Customer orders:write, menu:read Place orders, view menu
Kitchen Staff kitchen:manage, orders:read Manage cooking queue
Manager admin Full system access
Public menu:read Browse menu only

πŸš€ Scalability ConsiderationsΒΆ

Horizontal ScalingΒΆ

  • API Layer: Stateless controllers scale horizontally behind load balancer (see Clean Architecture)
  • Application Layer: Event handlers can be distributed across multiple instances (see Event-Driven Architecture)
  • Database Layer: MongoDB supports sharding and replica sets (see Repository Pattern)
  • External Services: Circuit breakers prevent cascade failures

πŸ’‘ Event-Driven Scalability: Kitchen event handlers can run on separate servers from order handlers, scaling independently based on load! Learn more: Event-Driven Architecture Benefits.

Performance OptimizationsΒΆ

  • Caching: Redis for frequently accessed menu items and customer data
  • Background Processing: Event-driven async handling for notifications and reporting
  • Database Indexing: Optimized queries for order status and customer lookups
  • CDN: Static assets (images, CSS) served from edge locations
  • Read Models: Separate CQRS read models optimized for queries

Monitoring & ObservabilityΒΆ

  • Health Checks: Endpoint monitoring for all critical services
  • Metrics: Custom business metrics (orders/hour, kitchen efficiency)
  • Logging: Structured logging with correlation IDs using Pipeline Behaviors
  • Tracing: Distributed tracing for request flows

πŸ’‘ Cross-Cutting Concerns: Logging, metrics, and tracing are implemented as Pipeline Behaviors that automatically wrap all command and query handlers!


πŸ”§ Infrastructure RequirementsΒΆ

Development EnvironmentΒΆ

  • Python: 3.9+ with FastAPI and Neuroglia framework
  • Storage: Local JSON files for rapid development (see Repository Pattern)
  • Authentication: Development OAuth server (Keycloak)

Production EnvironmentΒΆ

  • Compute: 2+ CPU cores, 4GB RAM minimum per instance
  • Database: MongoDB cluster with replica sets
  • Caching: Redis cluster for session and menu caching
  • Load Balancer: NGINX or cloud load balancer
  • Authentication: Production OAuth provider (Auth0, Keycloak)

Case Study DocumentsΒΆ

Framework Patterns UsedΒΆ

πŸ’‘ Architecture Learning: See how Mario's Pizzeria avoids common clean architecture mistakes like mixing layers and breaking dependency rules!


This technical architecture provides a scalable, maintainable foundation for Mario's Pizzeria using proven patterns from the Neuroglia framework.


This technical architecture ensures Mario's Pizzeria can scale from a single location to a multi-restaurant franchise while maintaining code quality and operational excellence.