docs: define repository pattern boundary
This commit is contained in:
@@ -97,6 +97,28 @@ Domain code should not depend on delivery mechanisms, databases, network
|
|||||||
clients, or framework-specific runtime concerns unless the project intentionally
|
clients, or framework-specific runtime concerns unless the project intentionally
|
||||||
uses an architecture where that trade-off is accepted and recorded.
|
uses an architecture where that trade-off is accepted and recorded.
|
||||||
|
|
||||||
|
## Persistence Boundary
|
||||||
|
|
||||||
|
The default persistence boundary is the repository pattern.
|
||||||
|
|
||||||
|
Use repositories to express domain-specific persistence operations without
|
||||||
|
leaking database, ORM, file-system, or external storage details into application
|
||||||
|
or domain logic.
|
||||||
|
|
||||||
|
Default rules:
|
||||||
|
|
||||||
|
- Application or domain-facing code depends on repository interfaces.
|
||||||
|
- Infrastructure implements repository interfaces.
|
||||||
|
- Repositories are named around domain concepts, not database tables.
|
||||||
|
- Repositories expose intention-revealing operations, not generic CRUD by
|
||||||
|
default.
|
||||||
|
- Transaction boundaries are explicit at the application service, unit of work,
|
||||||
|
or framework boundary selected by the project.
|
||||||
|
|
||||||
|
If a project intentionally avoids repositories because the framework or
|
||||||
|
architecture provides a better persistence boundary, record that decision in
|
||||||
|
[DECISIONS.md](DECISIONS.md).
|
||||||
|
|
||||||
## Request Flow
|
## Request Flow
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
|||||||
+8
-2
@@ -125,9 +125,15 @@ Project-specific DTO rules:
|
|||||||
|
|
||||||
## Repository Rules
|
## Repository Rules
|
||||||
|
|
||||||
Repositories, gateways, or data access abstractions should express persistence
|
Use the repository pattern as the default persistence boundary.
|
||||||
intent without hiding important consistency behavior.
|
|
||||||
|
|
||||||
|
Repositories, gateways, or data access abstractions should express domain
|
||||||
|
persistence intent without hiding important consistency behavior.
|
||||||
|
|
||||||
|
- Define repository interfaces at the application or domain boundary.
|
||||||
|
- Implement repositories in infrastructure or persistence-specific modules.
|
||||||
|
- Prefer specific repositories such as `OrderRepository` or
|
||||||
|
`SupportRequestRepository`.
|
||||||
- Keep query methods specific enough to reveal purpose.
|
- Keep query methods specific enough to reveal purpose.
|
||||||
- Avoid generic repositories when they obscure domain behavior.
|
- Avoid generic repositories when they obscure domain behavior.
|
||||||
- Document transaction boundaries.
|
- Document transaction boundaries.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ For project constraints, see [PROJECT.md](PROJECT.md).
|
|||||||
| ADR-001 | Example: Start with a modular monolith | Example | 2026-06-28 |
|
| ADR-001 | Example: Start with a modular monolith | Example | 2026-06-28 |
|
||||||
| ADR-002 | Example: Keep project documentation in the repository | Example | 2026-06-28 |
|
| ADR-002 | Example: Keep project documentation in the repository | Example | 2026-06-28 |
|
||||||
| ADR-003 | Example: Require explicit validation evidence before merge | Example | 2026-06-28 |
|
| ADR-003 | Example: Require explicit validation evidence before merge | Example | 2026-06-28 |
|
||||||
|
| ADR-004 | Example: Use repository pattern for persistence boundaries | Example | 2026-06-28 |
|
||||||
|
|
||||||
## ADR-000: ADR Template
|
## ADR-000: ADR Template
|
||||||
|
|
||||||
@@ -245,3 +246,62 @@ manual checks, or reasons validation could not be run.
|
|||||||
- PR templates should include validation.
|
- PR templates should include validation.
|
||||||
- Reviewers can block merges when risk is high and evidence is missing.
|
- Reviewers can block merges when risk is high and evidence is missing.
|
||||||
- Failed or skipped validation must be explained.
|
- Failed or skipped validation must be explained.
|
||||||
|
|
||||||
|
## ADR-004: Example: Use Repository Pattern For Persistence Boundaries
|
||||||
|
|
||||||
|
### Title
|
||||||
|
|
||||||
|
Use repository pattern for persistence boundaries.
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
### Date
|
||||||
|
|
||||||
|
2026-06-28
|
||||||
|
|
||||||
|
### Context
|
||||||
|
|
||||||
|
The project needs domain and application logic to remain independent from the
|
||||||
|
database engine, ORM, and storage implementation details.
|
||||||
|
|
||||||
|
### Problem
|
||||||
|
|
||||||
|
Without an explicit persistence boundary, database concerns can leak into
|
||||||
|
business logic and make testing, refactoring, and future storage changes harder.
|
||||||
|
|
||||||
|
### Alternatives
|
||||||
|
|
||||||
|
| Alternative | Summary |
|
||||||
|
| --- | --- |
|
||||||
|
| Direct ORM access everywhere | Fast initially, but couples business logic to persistence details. |
|
||||||
|
| Generic repository | Reduces ORM exposure, but often becomes a thin CRUD wrapper. |
|
||||||
|
| Domain-specific repository pattern | Keeps persistence behind intention-revealing interfaces. |
|
||||||
|
|
||||||
|
### Pros
|
||||||
|
|
||||||
|
- Keeps application and domain logic focused on use cases and rules.
|
||||||
|
- Makes persistence behavior easier to test and replace.
|
||||||
|
- Creates a clear place for query intent and transaction expectations.
|
||||||
|
- Reduces accidental coupling to ORM-specific APIs.
|
||||||
|
|
||||||
|
### Cons
|
||||||
|
|
||||||
|
- Adds interfaces and implementation classes.
|
||||||
|
- Poorly designed repositories can hide important query or transaction costs.
|
||||||
|
- Generic repositories can obscure domain behavior if used mechanically.
|
||||||
|
|
||||||
|
### Decision
|
||||||
|
|
||||||
|
Use domain-specific repositories as the default persistence boundary.
|
||||||
|
|
||||||
|
### Consequences
|
||||||
|
|
||||||
|
- Repository interfaces should live at the application or domain boundary.
|
||||||
|
- Repository implementations should live in infrastructure or persistence
|
||||||
|
modules.
|
||||||
|
- Generic CRUD repositories should be avoided unless the project records a clear
|
||||||
|
reason.
|
||||||
|
- Transaction boundaries must be documented where writes span multiple
|
||||||
|
repositories.
|
||||||
|
|||||||
@@ -78,6 +78,19 @@ atlas-desk/
|
|||||||
- Domain rules do not depend on HTTP, Vue, or database APIs.
|
- Domain rules do not depend on HTTP, Vue, or database APIs.
|
||||||
- Infrastructure implementations depend inward on application contracts.
|
- Infrastructure implementations depend inward on application contracts.
|
||||||
|
|
||||||
|
## Persistence Boundary
|
||||||
|
|
||||||
|
Atlas Desk uses the repository pattern for persistence boundaries.
|
||||||
|
|
||||||
|
- Repository interfaces live in the owning backend module.
|
||||||
|
- Repository implementations live in the module's infrastructure or persistence
|
||||||
|
folder.
|
||||||
|
- Repositories are domain-specific, such as `RequestRepository` and
|
||||||
|
`UserRepository`.
|
||||||
|
- Application services coordinate transactions for workflows that write multiple
|
||||||
|
records, such as assignment plus audit event creation.
|
||||||
|
- Generic CRUD repositories are not used because they hide workflow intent.
|
||||||
|
|
||||||
## Request Flow
|
## Request Flow
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
|||||||
@@ -57,6 +57,10 @@
|
|||||||
|
|
||||||
## Repository Rules
|
## Repository Rules
|
||||||
|
|
||||||
|
- Use the repository pattern for persistence boundaries.
|
||||||
|
- Keep repository interfaces in the owning backend module.
|
||||||
|
- Keep repository implementations near persistence infrastructure.
|
||||||
|
- Use specific repositories such as `RequestRepository` and `UserRepository`.
|
||||||
- Keep queries explicit, such as `FindOpenRequestsForQueue`.
|
- Keep queries explicit, such as `FindOpenRequestsForQueue`.
|
||||||
- Do not add generic repository abstractions over the database context.
|
- Do not add generic repository abstractions over the database context.
|
||||||
- Write operations that can be retried must be idempotent or transactionally protected.
|
- Write operations that can be retried must be idempotent or transactionally protected.
|
||||||
|
|||||||
@@ -148,3 +148,55 @@ Enforce authorization in backend policies for all sensitive actions.
|
|||||||
- Frontend checks remain usability hints only.
|
- Frontend checks remain usability hints only.
|
||||||
- Authorization tests are required for each protected workflow.
|
- Authorization tests are required for each protected workflow.
|
||||||
- Policy changes must be reviewed as security-sensitive changes.
|
- Policy changes must be reviewed as security-sensitive changes.
|
||||||
|
|
||||||
|
## ADR-004: Use Repository Pattern For Persistence Boundaries
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
### Date
|
||||||
|
|
||||||
|
2026-06-28
|
||||||
|
|
||||||
|
### Context
|
||||||
|
|
||||||
|
Atlas Desk uses PostgreSQL and Entity Framework Core, but request workflow rules
|
||||||
|
should not depend directly on ORM APIs or database-specific query details.
|
||||||
|
|
||||||
|
### Problem
|
||||||
|
|
||||||
|
Direct persistence access from application services would make workflow logic
|
||||||
|
harder to test and increase coupling to storage implementation details.
|
||||||
|
|
||||||
|
### Alternatives
|
||||||
|
|
||||||
|
| Alternative | Summary |
|
||||||
|
| --- | --- |
|
||||||
|
| Direct database context access | Simple, but spreads persistence concerns through application logic. |
|
||||||
|
| Generic repository | Hides the ORM, but exposes low-value CRUD abstractions. |
|
||||||
|
| Domain-specific repositories | Keeps persistence behind workflow-focused interfaces. |
|
||||||
|
|
||||||
|
### Pros
|
||||||
|
|
||||||
|
- Keeps workflow services focused on use cases.
|
||||||
|
- Makes request assignment and audit behavior easier to test.
|
||||||
|
- Provides intention-revealing query methods.
|
||||||
|
- Allows persistence implementation changes without rewriting domain logic.
|
||||||
|
|
||||||
|
### Cons
|
||||||
|
|
||||||
|
- Adds interface and implementation classes.
|
||||||
|
- Requires discipline to avoid generic CRUD repositories.
|
||||||
|
- Complex queries still need explicit performance review.
|
||||||
|
|
||||||
|
### Decision
|
||||||
|
|
||||||
|
Use domain-specific repositories for persistence boundaries.
|
||||||
|
|
||||||
|
### Consequences
|
||||||
|
|
||||||
|
- `RequestRepository` owns request persistence operations.
|
||||||
|
- `UserRepository` owns user lookup persistence operations.
|
||||||
|
- Reporting uses explicit read queries instead of mutating request data.
|
||||||
|
- Transaction boundaries remain visible in application services.
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ flowchart LR
|
|||||||
- {{DEPENDENCY_RULE_2}}
|
- {{DEPENDENCY_RULE_2}}
|
||||||
- {{DEPENDENCY_RULE_3}}
|
- {{DEPENDENCY_RULE_3}}
|
||||||
|
|
||||||
|
## Persistence Boundary
|
||||||
|
|
||||||
|
- Pattern: Repository pattern
|
||||||
|
- Repository interfaces: {{REPOSITORY_INTERFACE_LOCATION}}
|
||||||
|
- Repository implementations: {{REPOSITORY_IMPLEMENTATION_LOCATION}}
|
||||||
|
- Transaction boundary: {{TRANSACTION_BOUNDARY}}
|
||||||
|
- Repository rules: {{REPOSITORY_RULES}}
|
||||||
|
|
||||||
## Request Flow
|
## Request Flow
|
||||||
|
|
||||||
{{REQUEST_FLOW}}
|
{{REQUEST_FLOW}}
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
|
|
||||||
## Repository Rules
|
## Repository Rules
|
||||||
|
|
||||||
|
- Use the repository pattern for persistence boundaries.
|
||||||
|
- Repository interfaces live in {{REPOSITORY_INTERFACE_LOCATION}}.
|
||||||
|
- Repository implementations live in {{REPOSITORY_IMPLEMENTATION_LOCATION}}.
|
||||||
|
- Repositories should be domain-specific, not generic CRUD wrappers by default.
|
||||||
- {{REPOSITORY_RULE}}
|
- {{REPOSITORY_RULE}}
|
||||||
|
|
||||||
## Service Rules
|
## Service Rules
|
||||||
|
|||||||
Reference in New Issue
Block a user