ποΈ 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:
- Clean Architecture: Clear separation of concerns across four distinct layers
- CQRS Pattern: Separate models for read and write operations
- Event-Driven Design: Asynchronous processing and loose coupling
- Repository Pattern: Abstracted data access with multiple storage options
- Dependency Injection: Testable and maintainable service management
β οΈ 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 |
Menu OperationsΒΆ
| 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)
π Related DocumentationΒΆ
Case Study DocumentsΒΆ
- Business Analysis - Requirements and stakeholder analysis
- Domain Design - Business logic and data models
- Implementation Guide - Development patterns and APIs
- Testing & Deployment - Quality assurance and operations
Framework Patterns UsedΒΆ
- Clean Architecture - Four-layer separation with dependency rules
- CQRS Pattern - Separate read and write models for scalability
- Event-Driven Architecture - Async workflows and loose coupling
- Repository Pattern - Multiple storage implementations (File, MongoDB)
- Dependency Injection - Service lifetimes and testability
- Pipeline Behaviors - Logging, validation, error handling
π‘ 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.
- Testing & Deployment - Quality assurance and operations
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.