diff --git a/docs/library-decisions/2026-05-14-inversify.md b/docs/library-decisions/2026-05-14-inversify.md new file mode 100644 index 0000000..596bdd1 --- /dev/null +++ b/docs/library-decisions/2026-05-14-inversify.md @@ -0,0 +1,86 @@ +--- +package: inversify +version: "^6.2.0" +tier: feature +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: adr-002 +filter-results: + license: MIT + types: native + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view inversify license + - npm view inversify version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view inversify license` returns `MIT`. MIT is on the allowlist. + +## Filter: types + + + +inversify is authored in TypeScript and ships its own `.d.ts` declaration files. No separate `@types/inversify` package is needed. + +## Filter: maintenance + + + +Actively maintained; the 6.x line has seen recent releases addressing TypeScript compatibility improvements. Last release < 18 months, issue tracker shows ongoing engagement. + +## Filter: boundary-fit + + + +ADR-002 explicitly mandates InversifyJS as the DI framework for all feature packages. The ESLint boundary rules (ADR-010) do not restrict inversify to any specific path — feature packages are the declared consumers. + +## Filter: shadow-check + + + +inversify is the workspace-locked DI container per ADR-002. No parallel DI framework (tsyringe, awilix, etc.) is present or proposed. + +## Filter: eu-residency + + + +inversify is a pure runtime library with no network communication, telemetry, or data transmission. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against inversify at the time of this trace. + +## Filter: named-consumer + + + +All five feature packages — `@repo/auth`, `@repo/blog`, `@repo/media`, `@repo/marketing-pages`, `@repo/navigation` — depend on inversify for their per-feature DI containers (ADR-008). Concrete named consumers exist today. + +## Prompt: replaces + +Manual composition root patterns considered during initial architecture setup. InversifyJS replaces ad-hoc factory chaining that would not scale beyond three or four services per feature. No parallel approach is running. + +## Prompt: migration-cost-out + +Hard. InversifyJS container bindings, symbols, and decorator usage are scattered across every feature package's `di/` layer. Migrating out would require replacing all `@injectable()` / `@inject()` decorators, SYMBOLS definitions, and container bind calls across five feature packages simultaneously. The interface boundaries (ADR-002) reduce the surface, but the volume of changes is substantial. The per-feature container pattern (ADR-008) limits blast radius to one package at a time. + +## Prompt: alternatives-considered + +1. **tsyringe** (Microsoft) — lighter API but fewer lifecycle options and weaker TypeScript inference at the time of evaluation. +2. **Manual composition root** — zero dependency but does not scale past ~5 services without significant boilerplate and loses automatic dependency chain resolution. + +See ADR-002 for the full decision rationale. diff --git a/docs/library-decisions/2026-05-14-reflect-metadata.md b/docs/library-decisions/2026-05-14-reflect-metadata.md new file mode 100644 index 0000000..b31a79d --- /dev/null +++ b/docs/library-decisions/2026-05-14-reflect-metadata.md @@ -0,0 +1,84 @@ +--- +package: reflect-metadata +version: "^0.2.2" +tier: feature +decision: approved +date: 2026-05-14 +deciders: [Danijel Martinek] +adr: adr-002 +filter-results: + license: Apache-2.0 + types: native + maintenance: dormant + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass +verification-commands: + - npm view reflect-metadata license + - npm view reflect-metadata version + - pnpm audit --audit-level=moderate +accepted-cves: [] +--- + +## Filter: license + + + +`npm view reflect-metadata license` returns `Apache-2.0`. Apache-2.0 is on the allowlist. + +## Filter: types + + + +reflect-metadata ships its own `.d.ts` declaration files. Types are bundled with the package. + +## Filter: maintenance + + + +reflect-metadata implements the TC39 Metadata Reflection API proposal polyfill. The library is intentionally stable; new releases are rare because the spec is frozen pending TC39 progress. `dormant` is the accurate classification for a finished polyfill — this is not a concern for a library at this maturity level. + +## Filter: boundary-fit + + + +reflect-metadata is a required peer of InversifyJS (ADR-002). Feature packages importing inversify are expected to also import `reflect-metadata` once at the entry point of each feature's DI layer. No boundary rule restricts it. + +## Filter: shadow-check + + + +reflect-metadata is the only metadata polyfill in the workspace. It is explicitly paired with inversify per ADR-002 and has no competing alternative present. + +## Filter: eu-residency + + + +reflect-metadata is a pure runtime polyfill with no network communication, telemetry, or data transmission. EU residency does not apply. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` reports no advisories against reflect-metadata at the time of this trace. + +## Filter: named-consumer + + + +All five feature packages — `@repo/auth`, `@repo/blog`, `@repo/media`, `@repo/marketing-pages`, `@repo/navigation` — list reflect-metadata as a runtime dependency. It is imported at each feature's DI entry point to activate the metadata polyfill required by inversify decorators. + +## Prompt: replaces + +No prior metadata polyfill was in use. reflect-metadata is a direct requirement of InversifyJS's decorator-based binding — there is no alternative polyfill to retire. + +## Prompt: migration-cost-out + +Mechanical, but coupled to inversify removal. If InversifyJS is ever replaced with a DI approach that does not rely on the Reflect API (e.g., a factory-only approach), reflect-metadata can be removed by deleting one import per feature entry point. The removal is straightforward once the parent dependency (inversify) is gone. + +## Prompt: alternatives-considered + +1. **No polyfill / TC39 native** — The TC39 Metadata Reflection API is not yet at Stage 4; native support is not available in target runtimes. Not viable. +2. **`core-js` reflect subset** — Does not provide the complete `Reflect.metadata` API surface required by inversify. Not a functional alternative.