A microservice responsible for delivery management — assigning orders to couriers, tracking courier movement, and coordinating delivery lifecycle.
Built with Domain-Driven Design (DDD) tactical patterns and Clean Architecture to keep business logic isolated, testable, and framework-agnostic.
The Delivery service is part of a larger system and communicates with:
- Geo Service — provides geographic data (coordinates by address) via gRPC
- Basket Service — publishes events when a new basket/order is created (consumed via Kafka)
- Other consumers — Delivery publishes domain events (order assigned, order completed) to Kafka
The main goal of this project is applying DDD tactical patterns:
- Aggregates —
Courier,Orderwith enforced invariants - Entities — with identity and lifecycle
- Value Objects —
Location(immutable, equality by value) - Domain Events —
OrderAssigned,OrderCompleted - Domain Services — logic that spans multiple aggregates
- Repository pattern — persistence abstraction via ports
- Unit of Work — transactional consistency
The project follows layered Clean Architecture with strict dependency direction (outer → inner):
┌─────────────────────────────────────┐
│ Adapters (HTTP, Kafka, gRPC, DB) │
└──────────────────┬──────────────────┘
│ depends on
▼
┌─────────────────────────────────────┐
│ Application (Use Cases, Commands) │
└──────────────────┬──────────────────┘
│ depends on
▼
┌─────────────────────────────────────┐
│ Domain (Entities, Value Objects, │
│ Aggregates, Domain Events) │
└─────────────────────────────────────┘
| Layer | Technology |
|---|---|
| Language | Python ≥ 3.13 (strict type hints) |
| Web Framework | Litestar |
| DI Container | Dishka |
| Message Broker | Kafka via FastStream |
| Database | PostgreSQL (async, psycopg) |
| ORM | SQLAlchemy 2.0 |
| Migrations | Alembic |
| Scheduling | APScheduler |
| RPC | gRPC (geo service communication) |
| Serialization | Pydantic v2, Protobuf |
| Lint/Format | Ruff |
| Package Manager | uv |
| Testing | Polyfactory (test data factories) |
| Infrastructure | Docker, Docker Compose |
We treat contracts as borders between services. Code is generated from formal specifications — never hand-written:
REST API schemas are generated from contract.yaml using datamodel-codegen:
datamodel-codegen \
--input src/delivery_app/adapters/input/http/openapi/contract.yaml \
--input-file-type openapi \
--output src/delivery_app/adapters/input/http/openapi/schemas \
--module-split-mode single \
--all-exports-scope recursive \
--output-model-type pydantic_v2.BaseModel \
--target-python-version 3.13 \
--reuse-model \
--use-exact-imports \
--disable-future-imports \
--use-standard-collections \
--use-operation-id-as-name \
--field-constraints \
--snake-case-field \
--formatters ruff-check ruff-formatgRPC client stubs are generated from .proto definitions using grpc_tools:
cd src/delivery_app/adapters/output/grpc/geo
python -m grpc_tools.protoc \
--python_out=./pb \
--grpc_python_out=./pb \
--pyi_out=./pb \
--proto_path=./protos \
./protos/*src/
├── delivery_app/
│ ├── core/
│ │ ├── domain/ # Entities, Value Objects, Aggregates, Domain Events, Errors
│ │ ├── application/ # Use Cases (Commands/Queries), Application Services
│ │ └── ports/ # Interfaces (Repositories, UoW, External Services)
│ ├── adapters/
│ │ ├── input/
│ │ │ ├── http/ # Litestar controllers, OpenAPI contract & schemas
│ │ │ └── kafka/ # Kafka consumers (basket events)
│ │ └── output/
│ │ ├── postgres/ # SQLAlchemy repositories, UoW, Alembic migrations
│ │ ├── kafka/ # Kafka producers (integration events)
│ │ ├── grpc/ # gRPC client (geo service)
│ │ └── scheduler/ # APScheduler jobs (assign orders, move couriers, outbox)
│ └── di/ # Dishka DI container providers
├── config/ # App settings (12-factor, env-based)
└── main.py # Application entrypoint
docker compose up -d # Start PostgreSQL
uv run alembic upgrade head # Apply migrations
uv run python src/main.py # Start the serviceuv run pytestTests are organized by layer:
tests/unit/core/domain/— pure domain logictests/unit/core/application/— use cases with fakes/mockstests/integration/— adapters with real infrastructure