fix(cli): hexagonal archetype actually wires its ports + strict-clean variants (v26.06.16)#42
Merged
Merged
Conversation
… variants + bump v26.06.16 Surfaced by an audit while validating implement-hexagonal-adapter (skill clean: DI resolves a Protocol/ABC outbound port to its adapter — the keystone capability; zero/multiple-impl raise clear NoSuchBeanError/NoUniqueBeanError). The 'hexagonal' archetype defined inbound (use-case) + outbound (repository) ports that NOTHING implemented -> resolve(port) raised NoSuchBeanError, the ports were dead code, and TodoService's 'Implements the inbound ports' docstring was false (the scanner binds ports by MRO, so an adapter must inherit the port). - application service now implements the 4 inbound use-case ports; in-memory adapter implements the outbound repository port -> both resolve; genuinely hexagonal. - async use-case boundary across all variants (in-memory/relational/document). - data-relational/data-document variants: find_by_id() T|None was dereferenced without a check (mypy error + latent AttributeError) -> now raise ResourceNotFoundException (404). All 3 variants pass mypy --strict. - DTO id: str everywhere (was int in the relational variant vs domain str). Verified: in-memory boots + full CRUD + 404/422; ports resolve via get_bean; all 3 variants mypy --strict clean. Regression: tests/cli/test_scaffold_hexagonal_ports.py. Gates: mypy --strict (607), ruff + format, full suite 3682 passed.
cfdf4c4 to
1c39132
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An audit while validating the
implement-hexagonal-adapterskill (which validated clean — DI resolves a Protocol/ABC outbound port to its adapter, the keystone capability for the pattern, and zero/multiple-implementation cases raise clearNoSuchBeanError/NoUniqueBeanError) found that thehexagonalarchetype itself wasn't actually hexagonal.Fixed
resolve(TodoRepositoryPort)raisedNoSuchBeanError, andTodoService's docstring "Implements the inbound ports" was false (pyfly's scanner binds ports by MRO, so an adapter must inherit the port). Now the application service implements the four inbound use-case ports and the in-memory adapter implements the outbound repository port — both resolve, and it's genuinely hexagonal. The use-case boundary is async across all variants for consistency (pyfly is async-first; the in-memory variant was sync, which is why it couldn't share the ports with the async data variants).mypy --strictfailures + latent not-found bug. The data-relational / data-document variants dereferencedfind_by_id()'sT | Nonewithout a check (amypyerror and anAttributeErroron a missing id); they now raiseResourceNotFoundException(→ 404).TodoResponseDTO.idwasintin the relational variant while the domainTodo.idis alwaysstr; nowstreverywhere.Verification
get_bean(TodoRepositoryPort) → InMemoryTodoRepository,get_bean(CreateTodoUseCase) → TodoService; roundtrip via ports works.mypy --strict(18 files each).tests/cli/test_scaffold_hexagonal_ports.py.Gates
mypy --strict(607) ✓ ·ruff+ruff format✓ · full suite 3682 passed, 1 skipped.Bumps
v26.06.15 → v26.06.16, CHANGELOG,uv.lockunchanged (no dep change).