fix: auth scheduler env vars, concurrency and browser stability
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
# Hexagonal Architecture (Ports & Adapters) – Reference Manual
|
||||
|
||||
## Overview
|
||||
|
||||
Hexagonal Architecture, also known as **Ports and Adapters**, is a software design pattern that isolates an application’s **core business logic** from external systems such as user interfaces, databases, frameworks, and third-party services.
|
||||
|
||||
The application is conceptually placed at the center (often drawn as a hexagon). All communication with the outside world happens through **ports** (abstract interfaces), which are implemented by **adapters**.
|
||||
|
||||
The key idea:
|
||||
> **The domain does not depend on technology. Technology depends on the domain.**
|
||||
|
||||
---
|
||||
|
||||
## Fundamental Principles
|
||||
|
||||
### 1. Business Logic First
|
||||
The core domain represents the real business rules and use cases. It must:
|
||||
- Be independent of UI, databases, frameworks, and delivery mechanisms
|
||||
- Express *what* the system does, not *how* it is delivered
|
||||
|
||||
### 2. Explicit Boundaries
|
||||
All interactions between the core and external systems cross explicit boundaries (ports). This prevents accidental coupling.
|
||||
|
||||
### 3. Dependency Inversion
|
||||
Dependencies always point **inward**, toward the core. External components depend on abstractions defined by the core.
|
||||
|
||||
---
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Domain (Core)
|
||||
The domain contains:
|
||||
- Business entities
|
||||
- Value objects
|
||||
- Use cases / application services
|
||||
- Domain rules and policies
|
||||
|
||||
It contains **no technical concerns** such as HTTP, databases, file systems, or frameworks.
|
||||
|
||||
---
|
||||
|
||||
### Port
|
||||
A **port** is an abstract interface defined by the core.
|
||||
|
||||
Ports describe:
|
||||
- What the application *needs* from the outside world (output ports)
|
||||
- What the application *offers* to the outside world (input ports)
|
||||
|
||||
Ports are defined in the language of the domain, not infrastructure.
|
||||
|
||||
Examples (conceptual):
|
||||
- “Store an order”
|
||||
- “Send a notification”
|
||||
- “Execute a checkout use case”
|
||||
|
||||
---
|
||||
|
||||
### Adapter
|
||||
An **adapter** is a concrete implementation of a port using a specific technology.
|
||||
|
||||
Adapters translate:
|
||||
- External representations → domain concepts
|
||||
- Domain requests → external system calls
|
||||
|
||||
Adapters are replaceable and exist at the system’s edge.
|
||||
|
||||
#### Adapter Types
|
||||
|
||||
**Primary (Driving) Adapters**
|
||||
- Initiate interaction with the core
|
||||
- Examples: Web UI, CLI, REST controller, automated tests
|
||||
|
||||
**Secondary (Driven) Adapters**
|
||||
- Are used by the core
|
||||
- Examples: Database repositories, message brokers, email services
|
||||
|
||||
---
|
||||
|
||||
## Dependency Rule
|
||||
|
||||
- The **core defines ports**
|
||||
- **Adapters implement ports**
|
||||
- The core knows nothing about adapters
|
||||
- Adapters depend on the core, never the reverse
|
||||
|
||||
This rule guarantees that business logic remains stable even when technologies change.
|
||||
|
||||
---
|
||||
|
||||
## Interaction Flow
|
||||
|
||||
1. A primary adapter receives input (e.g., user action)
|
||||
2. It calls an **input port**
|
||||
3. The core executes business logic
|
||||
4. The core calls **output ports** as needed
|
||||
5. Secondary adapters fulfill those ports using external systems
|
||||
|
||||
All I/O stays outside the core.
|
||||
|
||||
---
|
||||
|
||||
## Structuring a System
|
||||
|
||||
A conceptual structure:
|
||||
|
||||
- Core
|
||||
- Domain entities
|
||||
- Use cases
|
||||
- Port interfaces
|
||||
- Adapters
|
||||
- Input adapters (UI, API, tests)
|
||||
- Output adapters (DB, services, files)
|
||||
- Composition root
|
||||
- Wires ports to adapters at startup
|
||||
|
||||
This structure is conceptual, not tied to folders or modules.
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
Hexagonal architecture enables strong testing practices:
|
||||
|
||||
- Test core logic using fake or in-memory adapters
|
||||
- No need for databases or servers in unit tests
|
||||
- Integration tests focus on individual adapters
|
||||
|
||||
Testing becomes simpler because dependencies are explicit and replaceable.
|
||||
|
||||
---
|
||||
|
||||
## Benefits
|
||||
|
||||
- High testability
|
||||
- Clear separation of concerns
|
||||
- Technology independence
|
||||
- Easier maintenance and evolution
|
||||
- Multiple interfaces over the same core logic
|
||||
- Strong alignment with Domain-Driven Design
|
||||
|
||||
---
|
||||
|
||||
## Comparison to Layered Architecture
|
||||
|
||||
Layered Architecture:
|
||||
- Organizes code by technical layers
|
||||
- Often allows UI → DB coupling
|
||||
- Business logic can leak into infrastructure
|
||||
|
||||
Hexagonal Architecture:
|
||||
- Organizes around the domain
|
||||
- Enforces strict boundaries
|
||||
- Treats UI and DB as interchangeable details
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
Hexagonal architecture is well suited for:
|
||||
- Medium to large systems
|
||||
- Long-lived codebases
|
||||
- Complex business domains
|
||||
- Systems with multiple interfaces
|
||||
- Applications that must remain adaptable
|
||||
|
||||
It may be unnecessary for very small or trivial applications.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Hexagonal Architecture places the domain at the center and treats all external systems as replaceable plugins. By communicating exclusively through ports and adapters, it ensures long-term flexibility, maintainability, and testability.
|
||||
|
||||
This pattern is language-agnostic and focuses on **design principles**, not frameworks.
|
||||
|
||||
Reference in New Issue
Block a user