Skip to content

Architecture Overview

codex-services is the business logic layer of the Codex ecosystem. It provides pure-Python, framework-agnostic engines for booking, scheduling, and calendar workflows — no ORM, no HTTP, no side effects. Drop into any Python project or wire into codex-bot / codex-django.


Ecosystem Position

```mermaid graph TD core["codex-core\n(BaseDTO, PII masking, BaseCommonSettings)"] services["codex-services\n(booking engine, calendar, slot calculator)"] bot["codex-bot\n(aiogram Telegram infrastructure)"] django["codex-django\n(Django integration layer)"]

core --> services
services --> bot
services --> django

```

codex-services depends only on codex-core (and optionally holidays). It has no knowledge of HTTP, databases, or message brokers.


Modules

Module Import path Purpose
Booking Engine codex_services.booking.slot_master Recursive chain-finder for multi-service bookings with scoring and waitlist
Slot Calculator codex_services.booking._shared Low-level datetime arithmetic — windows, gaps, busy interval merging
Calendar Engine codex_services.calendar Calendar grid generator for UI rendering with holiday awareness

Core Design Invariants

Immutable Data Model

All DTOs inherit BaseDTO from codex-core, which enforces frozen=True via Pydantic ConfigDict. Objects are never mutated after creation. To derive a modified copy:

updated = original.model_copy(update={"score": 9.5})

GDPR-Safe Logging

Every DTO's __repr__ exposes only IDs and timestamps — never names, notes, phone numbers, or other PII.

<SingleServiceSolution svc=haircut res=master_1 start=10:00>

This is intentional and documented in the source. Safe to log at DEBUG level.

Protocol-Driven Provider Interfaces

The engine never touches a database directly. External data is injected via runtime-checkable Protocol interfaces defined in booking._shared.interfaces:

Protocol Responsibility
AvailabilityProvider Build MasterAvailability objects from ORM/cache
ScheduleProvider Query working hours and break intervals
BusySlotsProvider Fetch already-booked time intervals

Implement these in your Django/SQLAlchemy layer and pass the results to the engine. The engine itself never imports your ORM models.

Stateless Engines

ChainFinder, BookingScorer, and CalendarEngine carry no request-scoped state. Instantiate once, reuse across requests without locks or resets.