# Schema Architecture
> **Purpose**: This document is the consolidated overview of the DDD layers that the Backbone Framework generates from your schema files. It replaces the previous DOMAIN.md, APPLICATION.md, INFRASTRUCTURE.md, and PRESENTATION.md.
>
> **Important**: You do **not** author the layers described here directly. They are output of the code generator. Read this only when you need to understand what the framework will produce — for day-to-day schema authoring, see [RULE_FORMAT_MODELS.md](./RULE_FORMAT_MODELS.md), [RULE_FORMAT_HOOKS.md](./RULE_FORMAT_HOOKS.md), and [RULE_FORMAT_WORKFLOWS.md](./RULE_FORMAT_WORKFLOWS.md).
## Table of Contents
1. [Bounded Context Model](#bounded-context-model)
2. [Layer Overview](#layer-overview)
3. [Domain Layer](#domain-layer)
4. [Application Layer](#application-layer)
5. [Infrastructure Layer](#infrastructure-layer)
6. [Presentation Layer](#presentation-layer)
7. [Data Flow](#data-flow)
8. [Generated File Layout](#generated-file-layout)
9. [Phase 1–10 Simplification Highlights](#phase-110-simplification-highlights)
---
## Bounded Context Model
Each module under `libs/modules/{module}/` is a **bounded context** in the DDD sense. It owns its complete domain — entities, value objects, repository traits, services, use cases, and presentation layer. Modules communicate exclusively through:
1. **Public exports** via `pub use` from the module's `lib.rs`.
2. **Domain events** consumed via the `event-subscription` generator.
3. **Anti-corruption-layer (ACL) adapters** generated by the `integration` target.
There is **no shared central domain**. The `corpus.Organization` and `bersihir.Organization` are different types that happen to share a name.
### Module Boundaries
```
libs/modules/
├── bersihir/ ← Laundry marketplace bounded context (~80 entities)
├── sapiens/ ← Identity, auth, RBAC bounded context (~50 entities)
├── bucket/ ← File storage bounded context
└── corpus/ ← Organization/CRM bounded context
```
A module imports types from another only via `external_imports` in its `index.model.yaml` — see [INTEGRATION.md](./INTEGRATION.md).
---
## Layer Overview
The generator emits four layers per module, following Clean Architecture dependency direction (outer depends on inner, never reverse):
```
┌─────────────────────────────────────────────────────────┐
│ Presentation ← HTTP, gRPC, GraphQL, OpenAPI, DTOs │
├─────────────────────────────────────────────────────────┤
│ Application ← Use cases, services, event handlers │
├─────────────────────────────────────────────────────────┤
│ Domain ← Entities, VOs, repo traits, events │
├─────────────────────────────────────────────────────────┤
│ Infrastructure ← Repository impls, projections, ES │
└─────────────────────────────────────────────────────────┘
↑ ↑
│ │
backbone-core backbone-orm
(generic traits) (DB primitives)
```
---
## Domain Layer
Generated from `*.model.yaml` and `*.hook.yaml`. Pure business logic with no external dependencies.
| `src/domain/entities/` | `rust` | Entity structs, constructors, mutation methods, state machine guards |
| `src/domain/value_objects/` | `value-object` | Typed IDs (`OrderId`, `Email`), wrapper VOs with `From<&str>` |
| `src/domain/repository/` | `repository-trait` | Repository trait definitions (port interfaces) |
| `src/domain/events/` | `events` | Domain event types — one per business event |
| `src/domain/state_machine/` | `state-machine` | State enums, transition tables, `StateMachineBehavior` impls |
| `src/domain/validator/` | `validator` | Field validators, entity-level rules, cross-field checks |
| `src/domain/specification/` | `specification` | Specification pattern types for filtering / matching |
| `src/domain/service/` | `domain-service` | Domain services (stateless, depend only on repo traits) |
**Phase 8 note**: `StateMachineBehavior` and `TransitionMeta` traits are owned by `backbone-core`. Entity files import these — they no longer redefine them per-entity.
---
## Application Layer
Generated from `*.model.yaml` (use cases) and `*.hook.yaml` (rules → service guards).
| `src/application/service/` | `service` | Application services. Each service wraps a `GenericCrudService<E>` and adds custom methods. |
| `src/application/usecase/` | `usecase` | Use case structs (`CreateOrder`, `ApproveOrder`) — one per documented use case |
| `src/application/cqrs/` | `cqrs` | **Opt-in**. Command/query handlers when `cqrs: true` |
| `src/application/workflow/` | `flow` | Saga / workflow orchestrators generated from `*.workflow.yaml` |
**Phase 3 note**: Per-entity adapter structs were eliminated. Generated services delegate to `GenericCrudService<E>` from `backbone-core` and only emit code for custom methods. The legacy `usecase/` directory tree (174 directories) was removed in commit `fe91e4a4b`.
---
## Infrastructure Layer
| `src/infrastructure/repository/` | `repository` | Concrete repository implementations using `GenericCrudRepository<E>` |
| `src/infrastructure/projection/` | `projection` | **Opt-in**. CQRS read-model projections |
| `src/infrastructure/event_store/` | `event-store` | Event store for event-sourced aggregates |
| `migrations/` | `sql` | PostgreSQL migration files |
| `migrations/seeds/` | `seeder` | Seed data SQL with custom-block markers |
**Phase 4 note**: Repository implementations are tiny — usually just a struct that holds a `Pool` and delegates everything to `GenericCrudRepository`. Custom queries live in a separate `_custom.rs` file.
---
## Presentation Layer
| `src/presentation/http/handlers/` | `handler` | Axum HTTP handlers — one per CRUD endpoint plus state transitions |
| `src/presentation/http/routes_composer.rs` | `routes-composer` | Single function that registers every entity's `http_routes()` |
| `src/presentation/http/handlers/mod.rs` | `handlers-module` | Top-level handler module with custom-code marker |
| `src/presentation/grpc/` | `grpc` | Tonic gRPC services |
| `src/presentation/graphql/` | `graphql` | GraphQL schema + resolvers (recently added) |
| `src/presentation/dto/` | `dto` | Request / response / patch DTOs imported by handlers |
| `docs/openapi/` | `openapi` | OpenAPI 3 YAML specs (one per entity if `--split` used) |
| `src/presentation/versioning.rs` | `versioning` | API versioning helpers |
**Phase 9 note**: Each entity exposes a single `http_routes()` function instead of registering per-action routes individually. The `routes_composer.rs` calls these in one place. Custom routes live in `src/presentation/http/custom_routes.rs` — see [GENERATION.md → Custom Code Preservation](./GENERATION.md#custom-code-preservation).
---
## Data Flow
```
HTTP Request
↓
[middleware: auth, ratelimit, logging]
↓
Handler (presentation/http/handlers)
├── Deserialize request → DTO
├── Authorize via Auth/Policy engine
└── Call Application Service
↓
Application Service (application/service)
├── Validate via Domain Validators
├── Run business rules from Hook
└── Call Repository Trait (domain/repository)
↓
Repository Impl (infrastructure/repository)
└── GenericCrudRepository → SQL
↓
PostgreSQL
```
Triggers (`after_create`, `after_update`, etc.) fire from the service layer after a successful repository call. Workflows are dispatched by event subscriptions when a domain event is emitted.
---
## Generated File Layout
```
libs/modules/{module}/
├── Cargo.toml
├── migrations/ ← sql + seeder
│ ├── 0001_initial.sql
│ └── seeds/
│ └── 0001_*_seed.sql
├── proto/ ← proto
├── src/
│ ├── lib.rs ← module
│ ├── app_state.rs ← app-state
│ ├── config.rs ← config
│ ├── domain/
│ │ ├── entities/ ← rust
│ │ ├── value_objects/ ← value-object
│ │ ├── repository/ ← repository-trait
│ │ ├── events/ ← events
│ │ ├── state_machine/ ← state-machine
│ │ ├── validator/ ← validator
│ │ ├── specification/ ← specification
│ │ └── service/ ← domain-service
│ ├── application/
│ │ ├── service/ ← service
│ │ ├── usecase/ ← usecase
│ │ ├── cqrs/ ← cqrs (opt-in)
│ │ └── workflow/ ← flow
│ ├── infrastructure/
│ │ ├── repository/ ← repository
│ │ ├── projection/ ← projection (opt-in)
│ │ ├── event_store/ ← event-store
│ │ └── integration/ ← integration
│ ├── presentation/
│ │ ├── http/
│ │ │ ├── handlers/ ← handler + handlers-module
│ │ │ ├── routes_composer.rs ← routes-composer
│ │ │ └── custom_routes.rs ← handwritten
│ │ ├── grpc/ ← grpc
│ │ ├── graphql/ ← graphql
│ │ └── dto/ ← dto
│ ├── authorization/ ← auth
│ ├── triggers/ ← trigger
│ └── exports.rs ← export
└── tests/ ← integration-test
```
---
## Phase 1–10 Simplification Highlights
The generator was substantially refactored across ten phases. The summary below explains what was removed and what replaced it. Read this if you're looking at older docs or older generated code that no longer matches reality.
| 1 | Trait aliases | Less per-entity boilerplate; generators emit code that uses `backbone-core` aliases |
| 2 | State machine enforcement | Illegal transitions are unrepresentable at the type level |
| 3 | Service simplification | Per-entity `CrudService` adapter structs eliminated; services delegate to `GenericCrudService<E>` |
| 4 | Repository generics | `GenericCrudRepository<E>` pattern; entity-specific repos are tiny |
| 5 | Workflow + trigger composition | No per-entity workflow / trigger adapters |
| 6 | Pagination types in core | `DomainPaginationParams` / `DomainPaginatedResult` extracted |
| 7 | Child entity collapse | Parent-child entities share a single CRUD stack |
| 8 | `StateMachineBehavior` in core | Entity code imports from `backbone-core` instead of redefining |
| 9 | `http_routes()` composition | All entity routes register through one composer function |
| 10 | Sub-workflow decomposition | Monolithic workflows replaced by event-chained sub-workflows |
For the full per-phase generator change list, see [GENERATION.md → Recent Generator Changes](./GENERATION.md#recent-generator-changes-phases-1-10).