Files
web/docs/adr/index.md
T

23 lines
1.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR Index — web
Module-level architecture decisions for `code.nochebuena.dev/einherjar/web`.
For framework-wide decisions see the
[Einherjar docs repository](https://code.nochebuena.dev/einherjar/docs).
No module-level ADRs for v1.0.0 — all design decisions were consistent with
existing framework principles (ADR-001 through ADR-003 from `core`, framework
ADRs 001004 from `docs`). No contested choices required a record.
Decisions worth noting (not ADR-worthy individually):
| Decision | Outcome | Rationale |
|---|---|---|
| `RateLimiterStore` as interface (not concrete) | Interface only; `InMemoryRateLimiterStore` as default | Allows `cache-valkey` to satisfy it via duck typing without cross-module import |
| Fail-open rate limiting | Request allowed on store error | Availability preferred over hard enforcement during infrastructure degradation |
| `last_seen` excluded | Not in v1.0.0 | Application-domain concern; not transport-level middleware |
| UUID v7 for request IDs | v7 with v4 fallback | Time-ordered IDs sort chronologically in logs; fallback ensures generation never fails |
| `observability.Checkable` not redefined | Imported from contracts | Starters implement contracts directly; no web import needed by db/cache starters |
| Background goroutine for in-memory eviction | `time.Ticker` goroutine | Avoids `worker` module dependency; in-memory store is self-contained |
| `mw.RequestIDFrom` resolver sees the request (v1.4.0) | New entry point takes `func(*http.Request) string`; `RequestID` becomes a request-ignoring wrapper over it | An inbound correlation id must be able to survive this boundary, but acceptability is per-service — a typed audit column rejects what an opaque log accepts. The framework provides plumbing only (context + header, once per request); the app owns policy (which header, validation, generation fallback). An empty resolver result attaches nothing rather than a silently-empty value |