Skip to content

alisolphp/SeatLock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SeatLock

MIT License Code Coverage PHPStan PHP Version Symfony CI Pipeline Docker Code Style

SeatLock is a hexagonal backend service that provides a safe seat holding API for events.

It focuses on:

  • Strict business rules (max 5 seats per reservation, expiration windows, etc.)
  • No overselling via pessimistic locking and transaction retries
  • Idempotent HTTP APIs with Redis-backed storage
  • Clear observability and production-grade infrastructure

This repository is the single source of truth for both the code and the documentation.


1. Quick demo tour (5–10 minutes)

Get a feel for the project without reading all the docs.
Spin everything up:

make init
make up-warm

Then explore:

1.1 API documentation

Interactive OpenAPI / Swagger UI powered by Nelmio.

SeatLock API

Demonstrates listing seats, holding reservations, idempotency, and error handling.


1.2 Containers & observability

Dockerized stack with PostgreSQL, Redis, RabbitMQ, MinIO and full observability (Grafana, Prometheus, Loki, Tempo).

SeatLock Containers & Observability

Shows containers running and how metrics, logs and traces are wired together.


1.3 Load testing & concurrency safety

k6 script simulating concurrent users hitting the hold seats endpoint. Result: zero overselling, only 201 Created and 409 Conflict responses.

SeatLock k6 Load Testing

Verifies race condition prevention via row-level locks and retry logic.


1.4 Code quality gates

  • 200+ tests (Pest)
  • ~90%+ coverage
  • PHPStan level 8
  • Pint code style

All enforced locally and in CI.

SeatLock Tests & Quality

Runs the full test suite, coverage, static analysis and linting.


1.5 Transactional outbox pattern

Domain events are written to an outbox table and delivered asynchronously to RabbitMQ using Symfony Messenger.

SeatLock Transactional Outbox

Flow: HTTP request → DB transaction → outbox insert → worker relay → RabbitMQ.


2. Getting started

2.1 Prerequisites

  • Docker and Docker Compose
  • Make
  • PHP and Composer (only if you want to run the app without Docker)

2.2 Clone and install dependencies

git clone https://github.com/alisolphp/SeatLock seatlock
cd seatlock
make install

2.3 Run the stack

Start the application and its dependencies (PostgreSQL, Redis, RabbitMQ, MinIO, etc.):

make up

Stop everything:

make down

3. API and local exploration

Once the stack is up:

  • Base URL (dev): http://localhost:8080/

Example API endpoints (see API.md for full details):

  • GET /api/v1/events/{eventId}/seats – list available seats for an event
  • POST /api/v1/events/{eventId}/hold – hold up to 5 seats with idempotency

OpenAPI / Swagger (via Nelmio):

  • JSON: GET /api/doc.json
  • UI (if enabled): GET /api/doc

Use these together with API.md when integrating clients or doing manual testing.


4. Tests and quality checks

These commands are enforced locally and in CI. Run them before opening a PR.

4.1 Test suite

Run the full test suite:

make test

Optional human-friendly output:

make test-dox

4.2 Code coverage

Run tests with coverage (must stay at or above 90%):

make coverage

Coverage is validated in CI; if it drops below the threshold, the pipeline fails.

4.3 Static analysis

Run PHPStan at level 8:

make analyse

4.4 Coding style

Run Pint:

make lint

CI will fail if style checks do not pass.


5. Documentation map

You can understand the whole system by reading a small set of focused docs.

5.1 High-level orientation

File What you’ll find When to read it
ARCHITECTURE.md Why Symfony + Hexagonal, locking strategy, retry logic, idempotency, outbox, Redis keys Read first – full mental model
DOMAIN.md Entities, Value Objects, Enums, invariants, Domain Events payloads When working on business logic or events
API.md Full API spec, endpoints, request/response examples, error codes, idempotency rules When building or consuming the API
INFRASTRUCTURE.md Observability stack, logging, health checks, OpenTelemetry conventions When debugging infra or adding tracing/metrics
DIRECTORY_STRUCTURE.md Exact folder layout and what belongs where (strict Hexagonal) When adding or moving classes/files

5.2 Engineering process and lifecycle

File What you’ll find
CONTRIBUTING.md Conventional Commits, branching strategy, code review expectations
PHASE0_TASKS.md Phase 0 checklist and what “done” means for the initial milestone
TESTING.md Testing strategy, tools, and conventions
SECURITY.md Security model, headers, CORS, hardening guidelines
BACKUP_RECOVERY.md Backup and disaster recovery plan

5.3 Architecture Decision Records

docs/adr/
├── 001-framework-choice.md      # Symfony instead of Laravel
├── 002-locking-strategy.md      # Pessimistic locking + retry
└── 003-outbox-pattern.md        # Messenger + doctrine transport

Only “real” decisions live here; everything else is folded into the main docs.


6. Architecture in one minute

  1. HTTP client calls a controller.
  2. Controller delegates to an Application UseCase.
  3. The UseCase runs inside a TransactionManager that handles retries on transient errors.
  4. The UseCase talks to Domain Services and Repository interfaces (pure domain layer).
  5. The Infrastructure layer (Doctrine, Redis, Messenger, etc.) provides concrete adapters.
  6. Domain Events are persisted to an outbox table and relayed by a worker to RabbitMQ.

That’s the core flow. Everything else is detail.


7. Environments and configuration

Configuration is mostly driven by .env variables and Symfony config under config/:

  • Database, Redis, RabbitMQ, MinIO and other services are wired via Docker Compose.
  • CORS is configured via NelmioCorsBundle and environment-specific settings.
  • Logging and tracing follow the conventions documented in INFRASTRUCTURE.md.

For environment-specific behavior (dev, test, prod), see the config/packages and docker directories.


8. Architecture diagrams

For a deeper understanding, these diagrams live under docs/assets:

8.1 Sequence – hold seats flow

SeatLock Sequence Diagram

8.2 C4 container diagram

SeatLock C4 Container Diagram

8.3 ERD – events / seats / reservations

SeatLock ERD

8.4 Layered / hexagonal architecture

SeatLock Layered Architecture


9. Contributing

  • We follow Conventional Commits strictly. See docs/CONTRIBUTING.md for allowed types and examples.

  • Before pushing:

    • Ensure tests pass: make test, make coverage.
    • Ensure static analysis and style checks pass: make analyse, make lint.
  • Keep documentation changes small and focused. The goal is to keep everything:

    • Concise
    • Non-redundant
    • Developer-friendly

10. License

This project is licensed under the MIT License – see the LICENSE file for details.

About

SeatLock is a hexagonal backend service that provides a safe seat holding API for events.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages