Skip to main content
โšก Calmops

Architectural Decision Records (ADRs): A Complete Guide

Introduction

Every software project makes hundreds of architectural decisions: what framework to use, how to structure the database, which cloud services to adopt, how to handle authentication. Over time, these decisions compound, and without documentation, teams lose track of the reasoning behind them.

Architectural Decision Records (ADRs) provide a simple yet powerful way to capture these decisions. This guide covers everything you need to implement ADRs in your project.


What are Architectural Decision Records?

Definition

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              ARCHITECTURAL DECISION RECORDS (ADRs)               โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   An ADR is a document that captures an important architectural โ”‚
โ”‚   decision made along with its context and consequences.        โ”‚
โ”‚                                                                  โ”‚
โ”‚   Origin: Michael Nygard's 2011 blog post                      โ”‚
โ”‚   "Documenting Architecture Decisions"                           โ”‚
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                                                         โ”‚   โ”‚
โ”‚   โ”‚  ADR = A document that captures:                       โ”‚   โ”‚
โ”‚   โ”‚                                                         โ”‚   โ”‚
โ”‚   โ”‚  โ€ข WHAT: The decision made                            โ”‚   โ”‚
โ”‚   โ”‚  โ€ข WHY: The context and reasons                       โ”‚   โ”‚
โ”‚   โ”‚  โ€ข ALTERNATIVES: What else was considered             โ”‚   โ”‚
โ”‚   โ”‚  โ€ข CONSEQUENCES: The impact of this decision          โ”‚   โ”‚
โ”‚   โ”‚  โ€ข STATUS: Proposed, Accepted, Deprecated, etc.        โ”‚   โ”‚
โ”‚   โ”‚                                                         โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why ADRs Matter

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 WHY USE ADRs?                                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   Problem: Without ADRs                                          โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ โ€ข "Why did we choose PostgreSQL?"                       โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "Who made this decision and why?"                     โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "What were the alternatives?"                        โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "Is this decision still valid?"                      โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "When we switched from MongoDB, what happened?"      โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "Why does this architecture look like this?"          โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ”‚   Solution: With ADRs                                           โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ โ€ข "See ADR-023: Use PostgreSQL as Primary Database"    โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "ADR-023 documents the team decision, date, and      โ”‚   โ”‚
โ”‚   โ”‚   rationale from our 2024-03-15 meeting"               โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "ADR-023 also lists alternatives considered"        โ”‚   โ”‚
โ”‚   โ”‚ โ€ข "ADR-042 marks ADR-023 as deprecated"               โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ”‚   Benefits:                                                     โ”‚
โ”‚   โœ“ Preserves institutional knowledge                          โ”‚
โ”‚   โœ“ Enables better onboarding                                  โ”‚
โ”‚   โœ“ Supports decision review and reversal                      โ”‚
โ”‚   โœ“ Creates audit trail for compliance                         โ”‚
โ”‚   โœ“ Facilitates design discussions                             โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ADR Structure

The Standard ADR Template

# ADR-XXX: [Title]

## Status
[Proposed | Accepted | Deprecated | Superseded | Rejected]

## Context
[Describe the issue motivating this decision]

## Decision
[Describe what was decided]

## Consequences
[Describe resulting context, both positive and negative]

## Alternatives Considered
- [Option 1]: [Brief description]
- [Option 2]: [Brief description]

## Related ADRs
- [ADR-XXX]: [Description]

## Notes
[Any additional notes, links, or references]

Enhanced Template

# ADR-047: Use Next.js for Frontend Framework

## Status
**Accepted** (2024-03-15)

## Date
2024-03-15

## Decision Makers
- @sarah-lee (Tech Lead)
- @mike-chen (Senior Engineer)
- @jordan-patel (Engineering Manager)

## Context
We need to select a frontend framework for our new customer-facing web application. 
The current application uses vanilla JavaScript, which has led to:
- Slow development velocity
- Difficult code maintenance
- Poor developer experience
- Inconsistent code patterns across the codebase

Requirements:
- SSR/SSG capabilities for SEO
- Fast initial page load
- Strong TypeScript support
- Good ecosystem and community

## Decision
We will use **Next.js** (React-based framework) for our new frontend.

## Consequences

### Positive
- Excellent performance with SSR and automatic code splitting
- Large ecosystem of components and libraries
- Strong TypeScript support out of the box
- Built-in routing and API capabilities
- Great developer experience with fast refresh
- Good documentation and community support

### Negative
- Learning curve for teams unfamiliar with React
- Larger bundle sizes compared to vanilla JS
- Server-side rendering adds complexity
- Some configuration needed for advanced use cases

## Alternatives Considered

### Option 1: Remix
- **Pros**: Better nested routing, simpler mental model
- **Cons**: Smaller ecosystem, newer project (less mature)
- **Why not**: Less hiring pool, fewer third-party integrations

### Option 2: Vue.js with Nuxt
- **Pros**: Easier learning curve, good documentation
- **Cons**: Smaller ecosystem than React
- **Why not**: Team has less Vue experience

### Option 3: Svelte/SvelteKit
- **Pros**: Smaller bundles, simpler syntax
- **Cons**: Smaller ecosystem, less enterprise adoption
- **Why not**: Riskier for long-term support

## Implementation Notes
- Use App Router (Next.js 13+)
- Implement CSS Modules or Tailwind for styling
- Set up automated testing with Jest and React Testing Library

## Related ADRs
- [ADR-012]: Use TypeScript for all new projects
- [ADR-023]: Use PostgreSQL as Primary Database
- [ADR-045]: Adopt component library for UI

## References
- [Next.js Documentation](https://nextjs.org/docs)
- [Remix vs Next.js Comparison](https://remix.run/blog/remix-vs-next)
- [React Server Components](https://react.dev/blog/2023/03/16/introducing-rsc)

## History
- 2024-03-15: Accepted (Team vote: 5-0)
- 2024-03-10: Draft created

ADR Workflow

Decision Process

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   ADR WORKFLOW                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                               โ”‚
โ”‚   โ”‚   Issue     โ”‚                                               โ”‚
โ”‚   โ”‚ Identified  โ”‚                                               โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                               โ”‚
โ”‚          โ”‚                                                      โ”‚
โ”‚          โ–ผ                                                      โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
โ”‚   โ”‚  Research   โ”‚ โ”€โ”€โ”€โ–บ โ”‚  Propose    โ”‚                        โ”‚
โ”‚   โ”‚ Alternativesโ”‚      โ”‚  Options    โ”‚                        โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
โ”‚          โ”‚                     โ”‚                                 โ”‚
โ”‚          โ”‚            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                       โ”‚
โ”‚          โ”‚            โ”‚               โ”‚                       โ”‚
โ”‚          โ”‚            โ–ผ               โ–ผ                        โ”‚
โ”‚          โ”‚      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”‚
โ”‚          โ”‚      โ”‚ Discuss โ”‚    โ”‚   Review    โ”‚               โ”‚
โ”‚          โ”‚      โ”‚ Options โ”‚    โ”‚    ADR      โ”‚               โ”‚
โ”‚          โ”‚      โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ”‚
โ”‚          โ”‚           โ”‚                โ”‚                        โ”‚
โ”‚          โ”‚           โ–ผ                โ”‚                        โ”‚
โ”‚          โ”‚      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚                        โ”‚
โ”‚          โ”‚      โ”‚  Team   โ”‚           โ”‚                        โ”‚
โ”‚          โ”‚      โ”‚  Vote   โ”‚           โ”‚                        โ”‚
โ”‚          โ”‚      โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜           โ”‚                        โ”‚
โ”‚          โ”‚           โ”‚                โ”‚                        โ”‚
โ”‚          โ”‚           โ–ผ                โ–ผ                        โ”‚
โ”‚          โ”‚      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚          โ”‚      โ”‚  Accept / Reject /      โ”‚                   โ”‚
โ”‚          โ””โ”€โ”€โ”€โ”€โ–บ โ”‚  Request Changes       โ”‚                   โ”‚
โ”‚                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                             โ”‚                                   โ”‚
โ”‚                             โ–ผ                                   โ”‚
โ”‚                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚                 โ”‚   Merge to Main/Archive โ”‚                   โ”‚
โ”‚                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ADR Lifecycle

"""ADR lifecycle management."""

from enum import Enum
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, List

class ADRStatus(Enum):
    """Possible ADR statuses."""
    PROPOSED = "Proposed"
    ACCEPTED = "Accepted"
    REJECTED = "Rejected"
    SUPERSEDED = "Superseded"
    DEPRECATED = "Deprecated"

@dataclass
class ADR:
    """An Architectural Decision Record."""
    
    number: int
    title: str
    status: ADRStatus
    date: datetime
    decision_makers: List[str]
    context: str
    decision: str
    consequences_positive: List[str] = field(default_factory=list)
    consequences_negative: List[str] = field(default_factory=list)
    alternatives: List[dict] = field(default_factory=list)
    related_adrs: List[int] = field(default_factory=list)
    notes: str = ""
    
    def mark_superseded(self, new_adrs: List[int]):
        """Mark this ADR as superseded by new ones."""
        self.status = ADRStatus.SUPERSEDED
        for adr_num in new_adrs:
            self.related_adrs.append(adr_num)
    
    def mark_deprecated(self, reason: str):
        """Mark this ADR as deprecated."""
        self.status = ADRStatus.DEPRECATED
        self.notes += f"\n\nDeprecated: {reason}"


class ADRLog:
    """Manage a collection of ADRs."""
    
    def __init__(self):
        self.adrs: List[ADR] = []
        self.next_number = 1
    
    def create_proposed(self, title: str, context: str, decision: str) -> ADR:
        """Create a new proposed ADR."""
        adr = ADR(
            number=self.next_number,
            title=title,
            status=ADRStatus.PROPOSED,
            date=datetime.now(),
            decision_makers=[],
            context=context,
            decision=decision
        )
        self.next_number += 1
        self.adrs.append(adr)
        return adr
    
    def accept(self, adr_number: int, decision_makers: List[str]) -> ADR:
        """Accept an ADR."""
        adr = self._get(adr_number)
        adr.status = ADRStatus.ACCEPTED
        adr.decision_makers = decision_makers
        return adr
    
    def supersede(self, old_number: int, new_number: int) -> ADR:
        """Mark an ADR as superseded."""
        old_adr = self._get(old_number)
        old_adr.mark_superseded([new_number])
        
        new_adr = self._get(new_number)
        new_adr.related_adrs.append(old_number)
        
        return new_adr
    
    def _get(self, number: int) -> ADR:
        """Get ADR by number."""
        for adr in self.adrs:
            if adr.number == number:
                return adr
        raise ValueError(f"ADR-{number} not found")
    
    def get_active(self) -> List[ADR]:
        """Get all active (non-superseded) ADRs."""
        return [adr for adr in self.adrs 
                if adr.status not in [ADRStatus.SUPERSEDED, ADRStatus.REJECTED]]

ADR Tools

ADR Management Tools

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    ADR TOOLS & INTEGRATIONS                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   Markdown-based (Recommended)                                   โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚   โ”‚ โ€ข adr-log (CLI tool for managing ADRs)                  โ”‚ โ”‚
โ”‚   โ”‚ โ€ข adr-tools (Michael Nygard's original)                  โ”‚ โ”‚
โ”‚   โ”‚ โ€ข Git-backed (store in repo, version controlled)         โ”‚ โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                                                                  โ”‚
โ”‚   Platform Integration                                           โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚   โ”‚ โ€ข GitHub: Store ADRs in repo, use issues for discussion โ”‚ โ”‚
โ”‚   โ”‚ โ€ข Notion: Use database for structured ADRs              โ”‚ โ”‚
โ”‚   โ”‚ โ€ข Confluence: Enterprise ADR management                  โ”‚ โ”‚
โ”‚   โ”‚ โ€ข Azure DevOps: Use Wiki for documentation              โ”‚ โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                                                                  โ”‚
โ”‚   Specialized Tools                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚   โ”‚ โ€ข ADR Manager (VS Code extension)                        โ”‚ โ”‚
โ”‚   โ”‚ โ€ข Goodpage (modern ADR tool)                             โ”‚ โ”‚
โ”‚   โ”‚ โ€ข Architecture Decision Records in GitHub Projects       โ”‚ โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

CLI Tool Setup

# Install adr-log
npm install -g adr-log

# Initialize ADRs directory
adr init doc/architecture/adr

# Create new ADR
adr new "Use PostgreSQL for main database"

# List all ADRs
adr list

# Show specific ADR
adr show 23

# Generate index
adr generate toc > README.md

Directory Structure

doc/
โ””โ”€โ”€ architecture/
    โ””โ”€โ”€ adr/
        โ”œโ”€โ”€ 0001-use-markdown-records.md
        โ”œโ”€โ”€ 0002-choose-auth0-for-authentication.md
        โ”œโ”€โ”€ 0003-use-postgresql-database.md
        โ”œโ”€โ”€ ...
        โ””โ”€โ”€ index.md (auto-generated)

# index.md format:
# # Architecture Decision Records
# 
# | Number | Title | Status |
# |--------|-------|--------|
# | ADR-0001 | Use Markdown Records | Accepted |
# | ADR-0002 | Choose Auth0 | Accepted |
# | ADR-0003 | Use PostgreSQL | Accepted |

Categorizing Decisions

Common ADR Categories

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    ADR CATEGORIES                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ PLATFORM & INFRASTRUCTURE                                โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Cloud provider selection (AWS, GCP, Azure)            โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Container orchestration (Kubernetes, ECS)             โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Database selection and architecture                   โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Caching strategy (Redis, Memcached)                   โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ APPLICATION ARCHITECTURE                                โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Microservices vs Monolith                             โ”‚   โ”‚
โ”‚   โ”‚ โ€ข API design (REST, GraphQL, gRPC)                     โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Event-driven architecture                             โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Layered vs Hexagonal architecture                     โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ DEVELOPMENT PRACTICES                                   โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Programming language selection                         โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Framework choices                                     โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Testing strategy                                      โ”‚   โ”‚
โ”‚   โ”‚ โ€ข CI/CD pipeline design                                 โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ SECURITY & COMPLIANCE                                   โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Authentication provider                               โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Authorization patterns                                โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Encryption approach                                   โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Compliance requirements                               โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ DATA & INTEGRATION                                       โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Data storage patterns                                 โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Integration approaches                                 โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Message queue selection                               โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Search infrastructure                                 โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ADR Numbering System

"""ADR numbering conventions."""

ADR_NUMBERING = """
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 ADR NUMBERING SYSTEM                              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   Option 1: Sequential (Simple)                                 โ”‚
โ”‚   โ”œโ”€โ”€ ADR-001: First decision                                  โ”‚
โ”‚   โ”œโ”€โ”€ ADR-002: Second decision                                 โ”‚
โ”‚   โ””โ”€โ”€ ADR-003: Third decision                                  โ”‚
โ”‚                                                                  โ”‚
โ”‚   Option 2: Functional Areas (Recommended for Large Projects)  โ”‚
โ”‚   โ”œโ”€โ”€ ADR-1XX: Infrastructure                                   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ ADR-100: Database choice                            โ”‚
โ”‚   โ”‚   โ””โ”€โ”€ ADR-101: Cloud provider                             โ”‚
โ”‚   โ”œโ”€โ”€ ADR-2XX: Application Architecture                        โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ ADR-200: API strategy                               โ”‚
โ”‚   โ”‚   โ””โ”€โ”€ ADR-201: Authentication                             โ”‚
โ”‚   โ”œโ”€โ”€ ADR-3XX: Development Practices                           โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ ADR-300: Language choice                           โ”‚
โ”‚   โ”‚   โ””โ”€โ”€ ADR-301: Testing framework                          โ”‚
โ”‚   โ””โ”€โ”€ ADR-4XX: Operations                                      โ”‚
โ”‚       โ”œโ”€โ”€ ADR-400: CI/CD pipeline                              โ”‚
โ”‚       โ””โ”€โ”€ ADR-401: Monitoring                                  โ”‚
โ”‚                                                                  โ”‚
โ”‚   Option 3: Year-Based (Good for Long Projects)                โ”‚
โ”‚   โ”œโ”€โ”€ ADR-2024-001: Decision from 2024                        โ”‚
โ”‚   โ”œโ”€โ”€ ADR-2024-002: Decision from 2024                        โ”‚
โ”‚   โ””โ”€โ”€ ADR-2025-001: Decision from 2025                        โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
"""

Real-World Examples

Example 1: Database Selection

# ADR-023: Use PostgreSQL as Primary Database

## Status
Accepted (2024-02-15)

## Context
We need to select a primary database for our new microservices architecture. 
Our requirements include:
- ACID compliance for financial transactions
- Complex query capabilities (reporting)
- Horizontal scaling for growth
- Strong JSON support for flexible schemas
- Reasonable cost for startup budget

Current system uses MongoDB but we've experienced:
- Transaction limitations
- Complex aggregations are slow
- Difficulty with reporting queries

## Decision
We will use **PostgreSQL** as our primary database for all new services.

## Consequences

### Positive
- Strong ACID compliance
- Excellent JSON support (JSONB type)
- Rich ecosystem and tooling
- Good horizontal scaling options (Citus, Patroni)
- Strong community and documentation
- Cost-effective (fully managed on AWS RDS)

### Negative
- Requires more schema planning than MongoDB
- Horizontal scaling is more complex
- Learning curve for team members

## Alternatives Considered

### Amazon Aurora
- **Pros**: Managed, highly available, MySQL/PostgreSQL compatible
- **Cons**: More expensive, vendor lock-in
- **Why not**: Budget constraints for startup

### MongoDB
- **Pros**: Flexible schema, easy to start
- **Cons**: Limited transactions, poor reporting
- **Why not**: Current pain points with existing system

### CockroachDB
- **Pros**: Distributed, geo-partitioning
- **Cons**: Newer, less mature
- **Why not**: PostgreSQL covers our current needs

## Implementation
- Use AWS RDS for managed PostgreSQL
- Implement database migrations with Alembic
- Set up read replicas for reporting queries

## Related ADRs
- [ADR-015]: Use AWS as Cloud Provider

## References
- [PostgreSQL vs MongoDB Comparison](https://www.enterprisedb.com/postgres-comparison)
- [AWS RDS Pricing](https://aws.amazon.com/rds/pricing/)

Example 2: Authentication

# ADR-032: Use Auth0 for Authentication

## Status
Accepted (2024-04-20)

## Context
We need to implement authentication across our web and mobile applications.
Requirements:
- Support multiple auth methods (email/password, social, MFA)
- Secure token management
- Compliance (SOC2, GDPR ready)
- Easy integration with React and mobile apps

## Decision
We will use **Auth0** as our authentication provider.

## Consequences

### Positive
- Quick integration with standard protocols (OAuth 2.0, OIDC)
- Built-in MFA and social login
- Universal login experience
- Good documentation and SDKs
- SOC2 Type II certified
- Reduces development time significantly

### Negative
- Subscription cost at scale
- Dependency on third-party service
- Customization limitations in Universal Login
- Adds latency to auth flow

## Alternatives Considered

### AWS Cognito
- **Pros**: Native AWS integration, lower cost at scale
- **Cons**: Steeper learning curve, less polished UI
- **Why not**: Auth0 provides better developer experience

### Firebase Auth
- **Pros**: Free tier, Google backing
- **Cons**: Less enterprise-focused
- **Why not**: Need enterprise features for future

### Self-hosted (Keycloak)
- **Pros**: Full control, no vendor lock-in
- **Cons**: Operational overhead, ongoing maintenance
- **Why not**: Team prefers managed solution for MVP

## Implementation Notes
- Use React SDK for web
- Use Auth0 SDKs for iOS/Android
- Implement token refresh with silent auth
- Set up role-based access control (RBAC)

## Related ADRs
- [ADR-023]: Use PostgreSQL as Primary Database
- [ADR-040]: Implement RBAC for Authorization

Best Practices

When to Write an ADR

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 WHEN TO WRITE AN ADR                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚   WRITE ADR when:                                               โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚   โ”‚ โœ“ Affects multiple services or teams                     โ”‚ โ”‚
โ”‚   โ”‚ โœ“ Has significant cost implications                       โ”‚ โ”‚
โ”‚   โ”‚ โœ“ Is difficult to reverse (locks in architecture)        โ”‚ โ”‚
โ”‚   โ”‚ โœ“ Impacts system reliability or security                 โ”‚ โ”‚
โ”‚   โ”‚ โœ“ Team needs consensus to proceed                        โ”‚ โ”‚
โ”‚   โ”‚ โœ“ Would benefit from documenting context for future      โ”‚ โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                                                                  โ”‚
โ”‚   DON'T NEED ADR for:                                           โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚   โ”‚ โœ— Localized decisions affecting single service            โ”‚ โ”‚
โ”‚   โ”‚ โœ— Implementation details that can be easily changed      โ”‚ โ”‚
โ”‚   โ”‚ โœ— Routine library updates                                โ”‚ โ”‚
โ”‚   โ”‚ โœ— Code style and formatting (use linters instead)       โ”‚ โ”‚
โ”‚   โ”‚ โœ— Trivial decisions with obvious solutions               โ”‚ โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                                                                  โ”‚
โ”‚   AS A RULE:                                                    โ”‚
โ”‚   If you spend more than 1 hour debating it, document it       โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ADR Maintenance

"""ADR maintenance workflow."""

class ADRMaintenance:
    """Guidelines for maintaining ADRs over time."""
    
    @staticmethod
    def should_review(adr_date: datetime, review_interval_days: int = 365) -> bool:
        """Check if ADR should be reviewed."""
        age = (datetime.now() - adr_date).days
        return age >= review_interval_days
    
    @staticmethod
    def review_checklist(adr: ADR) -> dict:
        """Checklist for ADR review."""
        return {
            'is_still_valid': True,  # Has the context changed?
            'has_new_alternatives': False,  # New technologies?
            'has_unintended_consequences': [],  # Any negative impacts?
            'needs_update': False,
            'should_deprecate': False,
            'notes': ''
        }
    
    @staticmethod
    def create_review_adrs(active_adrs: list) -> list:
        """Create review tickets for stale ADRs."""
        review_needed = []
        
        for adr in active_adrs:
            if ADRMaintenance.should_review(adr.date):
                review_needed.append({
                    'adr_number': adr.number,
                    'title': adr.title,
                    'age_days': (datetime.now() - adr.date).days,
                    'status': adr.status.value
                })
        
        return review_needed

Conclusion

Architectural Decision Records are essential for sustainable software development. Key takeaways:

  1. Document decisions while context is fresh - Later you’ll forget why
  2. Keep ADRs focused and concise - One decision per ADR
  3. Include alternatives considered - This is often the most valuable part
  4. Review and update ADRs periodically - Technology changes, so should decisions
  5. Make ADRs accessible - Store in the repo, link from READMEs

ADRs are not bureaucracyโ€”they’re an investment in your team’s future ability to make better decisions.


External Resources

Original Reference

Tools

Comments