Production-grade event-ticketing platform built on polyglot microservices, choreography saga, and cloud-native observability.
- Architecture
- Booking Saga
- Tech Stack
- Quick Start
- Documentation
- Architecture Decisions
- API Summary
- Screenshots
- Performance
- Contributing
- License
graph TB
subgraph "Client"
FE["Frontend\nReact 18 + Vite"]
end
subgraph "Gateway"
GW["API Gateway\nBun + Elysia :3000"]
end
subgraph "Java (JDK 21)"
US["User Service\nSpring Boot 3 :3001"]
BS["Booking Service\nSpring Boot 3 :3003"]
end
subgraph "Python 3.12"
ES["Event Service\nFastAPI :3002"]
PS["Payment Service\nFastAPI :3005"]
NS["Notification Service\nFastAPI :3006"]
end
subgraph "Bun"
IS["Inventory Service\nElysia :3004"]
end
subgraph "C++23"
SS["Search Service\nDrogon :3007"]
PRS["Pricing Service\nDrogon :3008"]
RS["Recommendation Service\nDrogon :3009"]
end
subgraph "Infrastructure"
KF[("Apache Kafka")]
PG[("PostgreSQL 16\n6 databases")]
MG[("MongoDB 7\n3 collections")]
RD[("Redis 7\nSeat locks")]
end
FE --> GW
GW --> US & ES & BS & IS & PS & NS & SS & PRS & RS
US --> PG
BS --> PG
IS --> PG & RD
SS --> PG
PRS --> PG
RS --> PG
ES --> MG
PS --> MG
NS --> MG
BS & IS & PS & NS & US & ES & SS & PRS & RS -.-> KF
KF -.-> IS & PS & NS & BS & SS & PRS & RS
| Service | Language | Framework | Database | Role |
|---|---|---|---|---|
| API Gateway | TypeScript / Bun | Elysia | — | Auth, routing, rate limiting |
| User Service | Java 21 | Spring Boot 3 | PostgreSQL | User registration, JWT auth |
| Event Service | Python 3.12 | FastAPI | MongoDB | Event/venue catalog |
| Booking Service | Java 21 | Spring Boot 3 | PostgreSQL | Saga orchestrator |
| Inventory Service | TypeScript / Bun | Elysia | PostgreSQL + Redis | Seat locking, availability |
| Payment Service | Python 3.12 | FastAPI | MongoDB | Payment processing |
| Notification Service | Python 3.12 | FastAPI | MongoDB | Email notifications |
| Search Service | C++23 | Drogon | PostgreSQL | Full-text search (CQRS) |
| Pricing Service | C++23 | Drogon | PostgreSQL | Dynamic pricing |
| Recommendation Service | C++23 | Drogon | PostgreSQL | Personalised recommendations |
| Frontend | TypeScript / Node | React 18 + Vite | — | SPA |
Three C++ services maintain their own read models via Kafka (CQRS pattern) and never query the Event Service directly. The Search Service builds an inverted index from event lifecycle events. The Pricing Service serves synchronous price quotes before booking creation. The Recommendation Service projects booking and search interactions into collaborative-filtering models.
Full architecture deep-dive: docs/architecture.md. Service details: docs/services/.
The booking lifecycle uses a choreography saga — no central orchestrator. Each service reacts to Kafka events and produces the next event.
sequenceDiagram
participant C as Client
participant GW as Gateway
participant PR as Pricing Service
participant BS as Booking Service
participant KF as Kafka
participant IS as Inventory Service
participant PS as Payment Service
participant NS as Notification Service
C->>GW: POST /api/bookings { seats, eventId }
GW->>PR: POST /api/pricing/quote (sync)
PR-->>GW: { totalPrice }
GW->>BS: Forward with price
BS->>BS: Save booking (PENDING)
BS->>KF: booking.initiated
BS-->>C: 202 Accepted { bookingId }
KF->>IS: booking.initiated
IS->>IS: Lock seats (Redis SETNX)
IS->>KF: seats.locked
KF->>BS: seats.locked
BS->>KF: payment.requested
KF->>PS: payment.requested
PS->>KF: payment.processed
alt Success
KF->>BS: payment.processed (SUCCESS)
BS->>KF: booking.confirmed + seats.confirm
KF->>IS: seats.confirm → RESERVED
KF->>NS: booking.confirmed → email
else Failure
KF->>BS: payment.processed (FAILED)
BS->>KF: booking.failed + seats.release
KF->>IS: seats.release → AVAILABLE
KF->>NS: booking.failed → email
end
C->>GW: GET /api/bookings/{id}
GW->>BS: Forward
BS-->>C: { status: "CONFIRMED" | "FAILED" }
Key points:
- Pricing is synchronous — the gateway calls Pricing Service before creating the booking.
- Everything after booking creation is asynchronous over Kafka.
- Compensation on failure:
seats.releasereturns locked seats to AVAILABLE.
Full event payloads: docs/event-catalog.md.
| Tool | Version | Install |
|---|---|---|
| Docker | 24.x | docker.com |
| Docker Compose | 2.x | Bundled with Docker |
| Make | any | brew install make |
# 1. Clone and setup
git clone https://github.com/your-org/ticketflow.git
cd ticketflow
make setup
# 2. Start full stack (Docker)
make dev
# 3. Seed sample data
make seed
# 4. Verify health
make health
# 5. Run end-to-end demo
make demoDemo credentials: test@ticketflow.dev / Test1234!
| Make target | Description |
|---|---|
make dev |
Build + start all services |
make dev-infra |
Start only Kafka, DBs, Redis |
make logs-booking |
Tail per-service logs |
make lint |
TypeScript + Python compile check |
make test |
Java unit tests |
make kafka-consume t=topic |
Consume from a topic |
make k8s-apply |
Deploy everything to Kubernetes |
Full development guide: docs/development.md. Configuration reference: docs/configuration.md.
| Document | Description |
|---|---|
| Architecture Deep-Dive | Design principles, communication patterns, scalability |
| API Reference | Full request/response schemas, error codes |
| Event Catalog | All Kafka topics, payloads, consumer groups |
| Deployment Guide | Docker Compose prod, Kubernetes, KEDA |
| Development Guide | Local setup, troubleshooting, gotchas |
| Observability Guide | Prometheus, Grafana, Jaeger, Loki, alerting |
| Configuration Reference | All environment variables and defaults |
| Service | Doc |
|---|---|
| Gateway | docs/services/gateway.md |
| User Service | docs/services/user-service.md |
| Event Service | docs/services/event-service.md |
| Booking Service | docs/services/booking-service.md |
| Inventory Service | docs/services/inventory-service.md |
| Payment Service | docs/services/payment-service.md |
| Notification Service | docs/services/notification-service.md |
| Search Service | docs/services/search-service.md |
| Pricing Service | docs/services/pricing-service.md |
| Recommendation Service | docs/services/recommendation-service.md |
| Decision | Rationale |
|---|---|
| Polyglot Architecture | Each runtime matches workload: Java for transactional, Python for document-centric, Bun for high-throughput edge, C++ for algorithmic |
| Kafka over RabbitMQ | Event log replay, consumer groups, KEDA integration, partition-based ordering, saga auditability |
| Async Saga Pattern | Choreography over orchestration — no central coordinator, bounded failure, independent deployability |
| Database per Service | Independent schemas, technology fit, fault isolation, no cross-service joins |
All requests through http://localhost:3000. Protected routes require Authorization: Bearer <token>.
| Service | Method | Path | Auth | Description |
|---|---|---|---|---|
| Gateway | GET | /health |
No | Health check |
| User | POST | /api/users/register |
No | Register |
| User | POST | /api/users/login |
No | JWT login |
| User | GET | /api/users/me |
Yes | Profile |
| Event | GET | /api/events |
No | List events |
| Event | POST | /api/events |
ADMIN | Create event |
| Inventory | GET | /api/inventory/events/:id/seats |
No | Seat map |
| Booking | POST | /api/bookings |
Yes | Initiate booking (202) |
| Booking | GET | /api/bookings/:id |
Yes | Poll status |
| Booking | POST | /api/bookings/:id/cancel |
Yes | Cancel |
| Payment | GET | /api/payments/:id |
Yes | Payment details |
| Search | GET | /api/search/events |
No | Full-text search |
| Pricing | POST | /api/pricing/quote |
No | Price quote |
| Recommendations | GET | /api/recommendations/user/:id |
No | Personalised |
Full specs: docs/api-reference.md.
| Tool | Preview |
|---|---|
| Frontend | ![]() |
| Kafka UI | ![]() |
| Grafana | ![]() |
| Jaeger | ![]() |
| Mailpit | ![]() |
| Search | ![]() |
| Recommendations | ![]() |
Screenshots are placeholders — run
make devand capture your own.
| Service | Endpoint | P50 | P95 | Throughput |
|---|---|---|---|---|
| Gateway | /api/events |
— | — | — |
| Search | /api/search/events |
— | — | — |
| Pricing | /api/pricing/quote |
— | — | — |
| Booking | POST /api/bookings (202) |
— | — | — |
Benchmarks are placeholders. Run
make devand measure with your own load-testing tool.
| Component | Technology | Purpose |
|---|---|---|
| Message Broker | Apache Kafka 7.7 | Async saga orchestration |
| Relational DB | PostgreSQL 16 | 6 databases (users, bookings, inventory, search, pricing, recommendations) |
| Document DB | MongoDB 7 | Events, payments, notifications |
| Cache / Lock | Redis 7 | Distributed seat locking (SETNX, 5min TTL) |
| Metrics | Prometheus | All services instrumented |
| Dashboards | Grafana | Pre-built dashboards |
| Tracing | Jaeger + OpenTelemetry | Distributed traces across all services |
| Logs | Loki + Promtail | Centralised log storage |
| Autoscaler | KEDA 2.14 | Scale on Kafka consumer lag |
- Fork, create a feature branch (
feat/your-feature). - Ensure
make lintandmake testpass. - Open a PR against
main.
Code style:
- Java: Google Java Style Guide
- Python: Black + isort
- TypeScript (Bun): ESLint + Prettier
- C++: CMake 3.25 + vcpkg, GTest
MIT License. See LICENSE for details.






