Some checks failed
CI / Check / Test (push) Failing after 1m24s
Hex arch + DDD, tree-sitter parsing, Mermaid/ASCII output. Supports Rust + Python. 92 tests. CI, diff, --check for staleness detection.
52 lines
2.3 KiB
Markdown
52 lines
2.3 KiB
Markdown
# 0001 — Hexagonal Architecture with DDD
|
|
|
|
**Status:** Accepted
|
|
**Date:** 2026-06-16
|
|
|
|
## Context
|
|
|
|
Archlens is a language-agnostic architecture diagram generator. It needs to support multiple input languages (Rust, C#, Python), multiple output formats (Mermaid, ASCII, future: D2, interactive web), and multiple IO strategies (file, stdout). The tool must be extensible without modifying core logic.
|
|
|
|
## Decision
|
|
|
|
Use hexagonal architecture (ports and adapters) with DDD structuring. Workspace layout:
|
|
|
|
```
|
|
crates/
|
|
domain/ — zero external deps (no tracing, no rayon, nothing)
|
|
application/ — depends on domain only + rayon, tracing (pragmatic utility exceptions)
|
|
adapters/
|
|
tree-sitter/ — SourceAnalyzer (internal modules per language)
|
|
walkdir/ — FileDiscovery
|
|
mermaid/ — DiagramRenderer
|
|
ascii/ — DiagramRenderer
|
|
file-writer/ — OutputWriter
|
|
stdout-writer/ — OutputWriter
|
|
toml-config/ — ConfigLoader
|
|
presentation/ — CLI (clap), composition root, tracing-subscriber setup
|
|
```
|
|
|
|
**Dependency rules:**
|
|
- Domain depends on nothing
|
|
- Application depends on domain
|
|
- Adapters depend on domain (not application)
|
|
- Presentation depends on application + adapters (composition root)
|
|
|
|
**Use cases** are generic over port traits (static dispatch), not trait objects.
|
|
|
|
**Pragmatic exceptions:** `rayon` and `tracing` in application crate. These are general-purpose utilities, not external system adapters. Documented explicitly to avoid precedent creep.
|
|
|
|
## Alternatives Considered
|
|
|
|
- **Trait objects for DI:** Simpler type signatures but runtime dispatch overhead and less compile-time safety. Rejected — generics align better with Rust idioms and zero-cost goals.
|
|
- **DI container (shaku):** Unnecessary ceremony for Rust. Manual wiring in presentation is explicit and sufficient.
|
|
- **Domain with tracing dependency:** Rejected to keep domain fully pure. Application wraps domain calls in spans.
|
|
|
|
## Consequences
|
|
|
|
- Adding a new language = new module in tree-sitter adapter (or new adapter crate)
|
|
- Adding a new output format = new adapter crate implementing DiagramRenderer
|
|
- Adding a new output destination = new adapter crate implementing OutputWriter
|
|
- Use case type signatures carry multiple generic parameters (accepted tradeoff)
|
|
- Domain crate is testable with zero setup — no mocks for infrastructure needed
|