Architecture
Devux follows clean architecture principles with domain-driven organization. Each endpoint is self-contained with its own layers, making the codebase predictable and maintainable.
Layers
┌─────────────────────────────────────┐
│ Controller │ ← Receives HTTP request
├─────────────────────────────────────┤
│ Validator │ ← Validates input with Zod
├─────────────────────────────────────┤
│ Use-Case │ ← Business logic
├─────────────────────────────────────┤
│ Repos / Services │ ← Data access & shared logic
├─────────────────────────────────────┤
│ Presenter │ ← Formats response
└─────────────────────────────────────┘Each layer has a single responsibility:
| Layer | Responsibility |
|---|---|
| Controller | Receives request, coordinates flow, returns response |
| Validator | Validates request payload against Zod schema |
| Use-Case | Executes business logic, orchestrates repos/services |
| Repos | Database operations with input/output validation |
| Services | Shared business logic across endpoints |
| Presenter | Transforms use-case output to API response format |
Project Structure
apps/backend/src/
├── domains/
│ └── customers/
│ ├── endpoints/
│ │ └── create-customer/
│ │ ├── repos/ # Endpoint-specific repos
│ │ ├── tests/
│ │ ├── create-customer.use-case.ts
│ │ ├── create-customer.responses.ts
│ │ └── create-customer.route.config.ts
│ ├── repos/ # Domain repos (shared)
│ └── services/ # Domain services (shared)
├── app-services/ # Cross-domain services
├── infrastructure/
│ └── core/ # Framework core
└── __internals__/ # Generated DI setup (don't edit)
├── domains/
├── app-services/
└── registries/
packages/shared/src/shared-app/
└── domains/
└── customers/
├── customers.error-codes.ts
├── customers.constants.ts
└── zod-schemas/
├── customers.base.zod.schema.ts
└── create-customer/
└── create-customer.zod.schema.tsComponent Types
Per-Endpoint Components
Each endpoint gets its own set of components, generated by the CLI:
- Use-Case – The core business logic
- Controller – HTTP handling (auto-generated, rarely modified)
- Validator – Input validation (auto-generated)
- Presenter – Response formatting (auto-generated)
- Endpoint Repos – Database operations specific to this endpoint
Shared Components
Reusable across multiple endpoints:
- Domain Repos – Database operations shared within a domain
- Domain Services – Business logic shared within a domain (can have their own repos)
- App Services – Utilities shared across all domains (global or request-scoped)
Data Flow
Request → Controller → Validator → Use-Case → Presenter → Response
↓
┌─────────────────┼─────────────────┐
↓ ↓ ↓
Endpoint Repos Domain Repos Domain Services
↓ ↓ ↓
Database Database Domain Repos
↓
Database- Controller receives the HTTP request
- Validator validates the payload against the Zod schema
- Use-Case executes business logic, calling repos and services
- Presenter formats the response
- Controller returns the HTTP response
Domain Organization
Domains group related functionality. A typical e-commerce app might have:
domains/
├── customers/ # Customer management
├── products/ # Product catalog
├── orders/ # Order processing
└── payments/ # Payment handlingEach domain is independent - endpoints in customers don't directly access products repos. Cross-domain communication happens through domain services or at the use-case level.
Why This Structure?
Predictability – Every endpoint follows the same pattern. Once you understand one, you understand all.
Testability – Each component can be tested in isolation. Use-cases don't know about HTTP. Repos don't know about business rules.
Maintainability – Changes are localized. Modifying a customer endpoint doesn't affect order endpoints.
Scalability – Add new domains without touching existing code. The CLI generates consistent structure every time.