Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 54 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
# Reservation Core — Barber Shop Booking System

Barber shop booking backend focused on **layered architecture**, **explicit domain**, and **guaranteed integrity via relational database**.
Backend system for barber shop booking, focused on **layered architecture**, **explicit domain modeling**, and **database-enforced integrity**.

The project prioritizes clear business rules, domain isolation, and the conscious use of SQL-first in Node.js.
The project prioritizes clear business rules, domain isolation, and SQL-first design for Node.js applications.

---

## Overview

A reservation system between users and barbers, with schedule conflict detection performed **at the database level** through constraints.
Reservation system connecting users and barbers, with schedule conflicts **prevented at the database level** via constraints.

The application does not perform redundant pre-validations for concurrency; conflicts are treated as integrity failures and correctly propagated to the application layer.
No redundant application-level pre-validation for concurrency is performed; conflicts are treated as integrity violations and propagated to the domain/application layer.

Core principles:
- Invariants protected in the domain and the database
- Unidirectional dependencies between layers
- Documented architectural decisions

* Invariants enforced in both domain and database layers
* Unidirectional dependencies between layers
* Documented architectural decisions

---

## Tech Stack

- Node.js + TypeScript
- NestJS (application composition and boundary)
- PostgreSQL
- Drizzle ORM (used only in infrastructure)
- pnpm
- Jest (configured; tests still evolving)
* Node.js + TypeScript
* NestJS (application composition and boundary)
* PostgreSQL
* Drizzle ORM (infrastructure layer only)
* pnpm
* Jest (fully configured for integration and unit testing)

**Migrations:** Pure SQL (SQL-first), manually written for explicit control over schema and constraints.
**Migrations:** SQL-first, manually written for explicit control over schema and constraints.

---

Expand All @@ -38,83 +39,77 @@ Layered architecture with unidirectional dependencies:

```
src/
├── domain # Entities, VOs, errors, and contracts
├── domain # Entities, value objects, errors, and contracts
├── application # Use cases and orchestration
└── infrastructure # Database, ORM, and adapters
└── infrastructure # Database adapters, ORM, and external integrations
```

Rules:
- `domain` does not depend on any other layer
- `application` depends only on `domain`
- `infrastructure` implements contracts defined above
- Dependency rules are **enforced via ESLint**
Dependency rules:

* `domain` is fully isolated, no external dependencies
* `application` depends only on `domain`
* `infrastructure` implements contracts defined in `domain` or `application`
* ESLint enforces architecture rules

Details and trade-offs documented in: [`docs/adr`](./docs/adr)
Full architectural decisions are documented in [`docs/adr`](./docs/adr).

---

## Domain Model

- **User**
The system's identity root.
Email and password hash are validated in the domain via Value Objects.
* **User**
Identity root. Email and password hash are validated via Value Objects.

- **Barber**
A specialization of `User`, sharing the same identifier.
Has its own table (`barbers`) for role-specific data.
* **Barber**
Specialization of `User` sharing the same identifier. Stores role-specific data in `barbers` table.

- **Client**
Not an explicit entity in the domain.
Usage concept: any `User` who creates a reservation.
* **Client**
Any `User` who creates a reservation. Not an explicit entity in the domain.

---

## Use Cases

Source of truth document: [`docs/use-cases.md`](./docs/use-cases.md)
Detailed source of truth: [`docs/use-cases.md`](./docs/use-cases.md)

Defined cases:
- Create user
- Create barber
- Create reservation
- Cancel reservation
- List barber schedule
- List client reservations
Implemented and in-progress use cases:

Not all have infrastructure implemented at the moment.
* Create user
* Create barber
* Create reservation
* Cancel reservation
* List barber schedule
* List client reservations

---

## Database and Integrity

- PostgreSQL as the source of truth
- Constraints for:
- relational integrity
- prevention of overlapping schedules
- Reservation conflicts:
- detected by the database
- translated into application errors
- This approach reduces race conditions and simplifies application logic
* PostgreSQL as source of truth
* Constraints enforce:

---
* Relational integrity
* Prevention of overlapping reservations
* Reservation conflicts are detected at the database level and translated to domain errors
* This approach minimizes race conditions and simplifies application logic

## Current Status
---

Project under development, focusing on structure and architectural correctness:
## Testing Strategy

- ✅ Domain modeled (`User`, `Barber`, `Reservation`)
- ✅ Main use cases defined
- ✅ Reservation conflict constraint implemented
- ⚠️ `User` and `Barber` infrastructure not yet implemented
- ⚠️ Reservation cancellation under definition (state not yet persisted)
- ⚠️ Tests still in early stages
* **Unit tests** validate domain logic and value objects
* **Integration tests** enforce invariants under real concurrent conditions
* Transactional repositories and concurrency barrier utilities simulate race conditions
* PostgreSQL `EXCLUDE USING gist` constraints enforce real concurrency protection
* Testing workflow and conventions documented in [`docs/testing.md`](./docs/testing.md)

---

## Documentation

- ADRs (decisions and trade-offs): [`docs/adr`](./docs/adr)
- Detailed use cases: [`docs/use-cases.md`](./docs/use-cases.md)
* ADRs (architectural decisions): [`docs/adr`](./docs/adr)
* Detailed use cases: [`docs/use-cases.md`](./docs/use-cases.md)
* Testing conventions and concurrency model: [`docs/testing.md`](./docs/testing.md)

---

Expand Down
Loading