Appearance
ADR-004: Solution Structure
Status: Accepted Date: 2026-02-07
Context
The project spans 4 development phases, involves multiple contributors, and has complex cross-cutting concerns (permissions, auditing). The team needed a solution structure that supports long-term maintainability without excessive boilerplate.
Decision
Modular monolith - Clean Architecture project boundaries with feature-based vertical slices as separate projects.
Rationale
This is a hybrid of Clean Architecture and Vertical Slices:
- Clean Architecture boundaries provide strict dependency rules (Domain has no dependencies, Infrastructure is swappable)
- Feature projects provide isolation so each domain area (Projects, Timelines, Characters, Factions, Collaboration) owns its entities, logic, endpoints, and tests
- Shared projects (Domain, Infrastructure, Common) provide the boilerplate foundation so features don't duplicate base classes, DbContext, auth, or utility code
Benefits for this project specifically:
- Different developers can own different feature projects without merge conflicts
- Phase 2 (Characters/Factions) means adding new projects, not modifying Phase 1 code
- Each feature is independently testable
- Complex features (like Relationships with its permission logic) stay contained
- Shared permission logic lives in Common, reusable across all features
Alternatives Considered
- Pure Clean Architecture - Domain, Application, Infrastructure, API as four projects. Feature code organized by folders within Application. Rejected because the team wanted stronger feature isolation than folders provide
- Pure Vertical Slices - Single project with feature folders. Fast to build but shared concerns (permissions, auditing) get duplicated or awkwardly placed. Rejected for long-term maintainability concerns with 4 phases of development
- Simple layered - Single project with Controllers/Services/Models folders. Rejected as likely to become messy by Phase 2-3 given the number of entities and complex permission logic
Structure
src/
├── Shared/
│ ├── KnowledgeBase.Domain/
│ ├── KnowledgeBase.Infrastructure/
│ └── KnowledgeBase.Common/
├── Features/
│ ├── KnowledgeBase.Projects/
│ ├── KnowledgeBase.Timelines/
│ ├── KnowledgeBase.Characters/
│ ├── KnowledgeBase.Factions/
│ └── KnowledgeBase.Collaboration/
└── KnowledgeBase.API/Consequences
- More projects in the solution means more project references to manage
- Feature projects reference shared projects but should minimize cross-feature references
- Need clear guidelines on what belongs in shared vs. feature-specific code
- DbContext configuration may need to discover entity configurations across multiple feature projects