-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Problem
Current State:
This project has made several significant architectural decisions (SQLite over other databases, Repository + Service pattern, AutoMapper, FluentValidation, in-memory caching, token-efficient documentation strategy, stadium-themed versioning), but the rationale, context, and trade-offs behind these decisions are not formally documented.
Pain Points:
-
Learning Barrier: As a learning PoC emphasizing "clarity and best practices," new developers or learners cannot easily understand WHY certain architectural choices were made, only WHAT was implemented.
-
Lost Context: Over time, the motivation behind decisions becomes unclear. Future contributors may:
- Blindly accept outdated decisions that should be revisited
- Reverse decisions without understanding their consequences
- Repeat past mistakes by not knowing what was already considered and rejected
-
Onboarding Friction: New contributors must reverse-engineer decisions from code, commit history, or incomplete documentation rather than reading clear rationale.
-
Decision Reversals: When requirements change (e.g., moving from SQLite to PostgreSQL for production), there's no record of:
- What alternatives were considered
- What trade-offs were made
- What circumstances would warrant revisiting the decision
-
Missing Knowledge Transfer: The project's focus on AI-assisted development and token-efficient documentation would benefit from structured decision records that both humans and AI agents can reference.
Proposed Solution
Implement Architecture Decision Records (ADRs) using Michael Nygard's template to document all architecturally significant decisions in a lightweight, maintainable format.
Key Benefits:
- Educational Value: Learners understand not just implementation patterns, but decision-making reasoning
- Knowledge Preservation: Decisions remain accessible as team composition changes
- Context for AI Agents: Structured ADRs provide high-value context for GitHub Copilot and other AI assistants
- Decision Traceability: Clear audit trail of what was decided, when, and why
- Change Confidence: Future changes informed by understanding original constraints and trade-offs
- Best Practice Demonstration: Shows professional decision documentation for a learning resource
Timing: This is particularly valuable now because:
- Issue [FEATURE] Restructure project to adopt a Clean Architecture-inspired structure #266 (Clean Architecture migration) is planned for v2.0.0 - ADRs will document why we're changing
- Issue [FEATURE] Add PostgreSQL support with unified migration-based initialization #249 (PostgreSQL support) will require architectural documentation
- Multiple other architectural issues ([FEATURE] Adopt JWT Authentication via Client Credentials Flow for protected API routes #105, Handle concurrency conflicts with EF Core using application-managed tokens #65) are in the pipeline
- Establishing ADR practice before major refactoring ensures we capture the "before" state and rationale for changes
Suggested Approach
1. Repository Structure
Create an adr/ directory at the project root to store all ADRs:
Dotnet.Samples.AspNetCore.WebApi/
├── adr/
│ ├── README.md # ADR index and navigation
│ ├── 0001-use-architecture-decision-records.md
│ ├── 0002-use-sqlite-for-data-storage.md
│ ├── 0003-adopt-traditional-layered-architecture.md # May be superseded by Issue #266
│ ├── 0004-use-automapper-for-dto-mapping.md
│ ├── 0005-use-fluentvalidation-over-data-annotations.md
│ ├── 0006-implement-in-memory-caching.md
│ ├── 0007-adopt-token-efficient-documentation-strategy.md
│ └── 0008-use-stadium-themed-semantic-versioning.md
├── README.md
├── AGENTS.md
└── ...
2. ADR Template (Michael Nygard Format)
# [NUMBER]. [TITLE]
Date: YYYY-MM-DD
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXXX]
## Context
What is the issue we're facing? What forces are at play (technical, political, social, project constraints)? Present facts neutrally without bias.
## Decision
We will [DECISION IN ACTIVE VOICE WITH FULL SENTENCES].
## Consequences
### Positive
- Consequence 1
- Consequence 2
### Negative
- Trade-off 1
- Limitation 1
### Neutral
- Other effect 13. Initial ADRs to Create
Retroactive ADRs (document existing decisions):
- 0001-use-architecture-decision-records.md: Meta-ADR explaining why we're using ADRs
- 0002-use-sqlite-for-data-storage.md: Why SQLite over PostgreSQL/SQL Server
- Context: PoC/learning project, simplicity, zero-config, file-based
- Trade-offs: Not production-ready, limited concurrency, no advanced features
- Note: Related to Issue [FEATURE] Add PostgreSQL support with unified migration-based initialization #249 (PostgreSQL planned for v2.0.0)
- 0003-adopt-traditional-layered-architecture.md: Why traditional layered architecture over Clean Architecture
- Context: Controllers → Services → Repositories → Data pattern, simplicity for small projects, immediate productivity
- Trade-offs: Domain entities mixed with DTOs, dependencies flow in multiple directions, tight coupling, limited flexibility
- Status: Under active reconsideration (see Issue [FEATURE] Restructure project to adopt a Clean Architecture-inspired structure #266)
- Note: This ADR will likely be superseded by a future ADR when Clean Architecture is adopted (Issue [FEATURE] Restructure project to adopt a Clean Architecture-inspired structure #266 proposes minimal folder-based Clean Architecture for v2.0.0)
- 0004-use-automapper-for-dto-mapping.md: Why AutoMapper vs manual mapping
- Context: Reduce boilerplate, convention-based mapping
- Trade-offs: Magic behavior, runtime performance cost, learning curve
- 0005-use-fluentvalidation-over-data-annotations.md: Why FluentValidation
- Context: Complex validation rules, separation of concerns, testability
- Trade-offs: Additional dependency, not built-in to ASP.NET Core
- 0006-implement-in-memory-caching.md: Why
IMemoryCachevs distributed cache- Context: Demo simplicity, single-instance deployment, fast access
- Trade-offs: Lost on restart, not suitable for multi-instance deployments
- 0007-adopt-token-efficient-documentation-strategy.md: Why split docs into auto-loaded + on-demand
- Context: Optimize AI agent token budget, balance context vs cost
- Trade-offs: Fragmented documentation, requires manual loading
- 0008-use-stadium-themed-semantic-versioning.md: Why football stadium names
- Context: Memorable releases, alphabetical progression, project theme
- Trade-offs: Non-standard, might confuse newcomers
4. Integration Points
Update CONTRIBUTING.md:
Add section on ADRs:
## Architecture Decision Records
When proposing changes that affect:
- Project structure or architecture
- Technology choices or dependencies
- Non-functional requirements (performance, security, scalability)
- Development workflows or processes
Please create an ADR in the `adr/` directory following the existing template. See `adr/README.md` for guidance.Update README.md:
Add ADR section to documentation:
## Architecture Decisions
See [Architecture Decision Records (ADRs)](adr/README.md) for documented decisions about this project's architecture, technology choices, and development practices.Update .github/copilot-instructions.md:
Add ADR context for AI agents:
## Architecture Decision Records (ADRs)
Load `#file:adr/README.md` when:
- User asks about architectural choices or "why we use X"
- Proposing changes to core architecture or dependencies
- Need historical context for past decisions5. Implementation Steps
- Create
adr/directory structure - Write
adr/README.mdwith index, navigation, and template - Create ADR 0001 (meta-ADR about using ADRs)
- Create retroactive ADRs 0002-0008 for existing decisions
- Update CONTRIBUTING.md, README.md, and Copilot instructions
- Add ADR creation to PR review checklist
- Document ADR workflow in AGENTS.md
Important: ADR 0003 (Traditional Layered Architecture) documents the current state with full awareness that Issue #266 proposes a future change to Clean Architecture. This demonstrates proper ADR usage:
- Capture the original decision with its context
- Mark it as "Under Reconsideration"
- When Clean Architecture is adopted, create a new ADR that supersedes 0003
- Keep 0003 in the repository for historical context
6. Tooling (Optional Future Enhancement)
Consider adopting adr-tools or similar:
adr new "Use PostgreSQL for production": Generate new ADR with boilerplateadr list: Show all ADRs with statusadr supersede 0002 "Use PostgreSQL": Link superseded decisions
For now, manual markdown files are sufficient given the project's simplicity.
Acceptance Criteria
- Analysis completed: ADRs would benefit this project
-
adr/directory created at project root -
adr/README.mdcreated with ADR index, template, and usage guide - ADR 0001 created: "Use Architecture Decision Records"
- Retroactive ADRs created for 7 existing key decisions (0002-0008)
- CONTRIBUTING.md updated with ADR guidance for contributors
- README.md updated to reference ADR documentation
-
.github/copilot-instructions.mdupdated to include ADR context loading guidance - AGENTS.md updated with ADR maintenance workflow
- All ADRs use consistent format (Michael Nygard template)
- ADRs are written in clear, full sentences (not bullet fragments)
- Each ADR is 1-2 pages maximum
- CI/CD pipeline continues to pass with new documentation
- Documentation changes committed following conventional commits format
References
ADR Resources
- Documenting Architecture Decisions - Michael Nygard (2011) - Original blog post introducing the ADR concept
- ADR GitHub Organization - Collection of ADR templates, tools, and best practices
- Michael Nygard ADR Template - Canonical template format
- Azure Well-Architected Framework - ADRs - Microsoft guidance on ADRs
- Sustainable Architectural Decisions - Zdun et al. - Academic foundation for ADR practices
Related Project Documentation
#file:AGENTS.md- Operational instructions mentioning decision context needs#file:.github/copilot-instructions.md- Current AI agent instruction strategy#file:CONTRIBUTING.md- Contribution guidelines to be extended with ADR process#file:CHANGELOG.md- Shows evolution of decisions over time (e.g., .NET 10 upgrade, token-efficiency strategy)#file:README.md- Project overview highlighting "clarity and best practices" focus
Related GitHub Issues
These open issues involve architectural decisions that would benefit from ADR documentation:
- Issue #266: Restructure to Clean Architecture - High Priority, v2.0.0 milestone - Proposes migrating from traditional layered architecture to Clean Architecture (minimal folder-based approach). When implemented, this will supersede ADR 0003.
- Issue #249: Add PostgreSQL support - High Priority, v2.0.0 milestone - When implemented, will require an ADR documenting why PostgreSQL was chosen and how it relates to ADR 0002 (SQLite decision).
- Issue #105: JWT Authentication - Low Priority, v2.1.0 milestone - Will require ADR documenting authentication approach choice.
- Issue #65: EF Core Concurrency Tokens - Low Priority, v2.1.0 milestone - Will require ADR for concurrency strategy.
Note: Implementing ADRs now will establish the practice before these major architectural changes, ensuring decision rationale is captured from the start.
Example ADR Repositories
- AWS Prescriptive Guidance - ADRs
- Spotify Engineering - ADRs - Real-world usage
Tooling
- adr-tools - Command-line tools for managing ADRs
- Log4brains - Architecture decision log with web UI
- ADR Manager VSCode Extension - IDE integration