Skip to content

refactor(app): collapse feature wiring into per-feature Module builders#143

Merged
allisson merged 1 commit into
mainfrom
improve-codebase
Jul 17, 2026
Merged

refactor(app): collapse feature wiring into per-feature Module builders#143
allisson merged 1 commit into
mainfrom
improve-codebase

Conversation

@allisson

Copy link
Copy Markdown
Owner

Summary

Deepens the composition root (internal/app). Each feature now owns one build<Feature>Module that assembles use case → handler → Route Module in one place, replacing the scattered field + accessor + init triple that every handler and repository carried.

  • Handlers are no longer Container fields — built as locals inside the feature builders.
  • Repositories are no longer Container fields — built inline inside each use case's init (single consumer, stateless over *sql.DB).
  • Use cases stay as memoized once[T] fields (both the HTTP path and the CLI consume them).
  • The per-route authorizer becomes a shared Authorizer() accessor, so builders fetch it without threading.
  • initHTTPServer drops from ~12 dependency fetches to three (db, tokenUseCase, metricsProvider) plus a four-builder loop.
  • buildAuthModule builds its optional token rate limiter last, so the error paths never start its background goroutine.

Net: drops 8 handler + 7 repository fields/accessors/inits; adds 4 builders + 1 authorizer accessor. −232 lines.

Docs: the internal/app/README.md dependency graph and "adding components" section are updated to the builder pattern (and a stale initErrors-map example that never matched once[T] is corrected).

Validation

  • go build ./... — clean
  • make test — 1250 tests pass (41 packages, race enabled)
  • go vet -tags integration ./test/integration/... — clean
  • make lint — 0 issues, govulncheck 0 vulnerabilities
  • make docs-lint — 0 errors

Notes

  • No behavior change — pure wiring refactor. di_test.go now asserts at the module seam; the audit-log signature integration test builds its own repository from the container DB.
  • Out of scope (deliberately deferred): renaming di_crypto.go (it wires keyring/KEK, not transit crypto).

🤖 Generated with Claude Code

Each feature now owns one build<Feature>Module that assembles use case ->
handler -> Route Module in a single place. Handler and repository once[T]
fields are removed from the Container: handlers are built as locals inside
the builders, and repositories are built inline inside each use case's init
(single consumer, stateless over *sql.DB). Use cases stay as memoized
once[T] fields because both the HTTP path and the CLI consume them.

The per-route authorizer becomes a shared Authorizer() accessor so every
builder fetches it without threading. initHTTPServer drops ~12 dependency
fetches down to three plus a four-builder loop. buildAuthModule builds its
optional token rate limiter last so the error paths never start its
background goroutine.

Drops 8 handler + 7 repository fields/accessors/inits; adds 4 builders and
one authorizer accessor. Net -232 lines. di_test rewritten to assert at the
module seam; the audit-log integration test builds its own repository from
the container DB. README dependency graph and "adding components" updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@allisson
allisson merged commit f04604c into main Jul 17, 2026
3 checks passed
@allisson
allisson deleted the improve-codebase branch July 17, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant