scaffold-ca-python 0.3.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (414) hide show
  1. scaffold_ca_python-0.5.0/.release-please-manifest.json +3 -0
  2. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/CHANGELOG.md +14 -0
  3. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/PKG-INFO +2 -2
  4. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/README.md +1 -1
  5. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/checklists/requirements.md +36 -0
  6. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/contracts/dm.md +22 -0
  7. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/contracts/guc.md +38 -0
  8. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/data-model.md +36 -0
  9. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/plan.md +109 -0
  10. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/quickstart.md +66 -0
  11. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/research.md +59 -0
  12. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/spec.md +170 -0
  13. scaffold_ca_python-0.5.0/specs/026-usecase-naming-standardization/tasks.md +215 -0
  14. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/checklists/requirements.md +36 -0
  15. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/contracts/generated-routes.md +83 -0
  16. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/data-model.md +31 -0
  17. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/plan.md +106 -0
  18. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/quickstart.md +65 -0
  19. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/research.md +63 -0
  20. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/spec.md +147 -0
  21. scaffold_ca_python-0.5.0/specs/027-mcp-health-check/tasks.md +220 -0
  22. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_use_case.py +23 -13
  23. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/module_locator.py +19 -2
  24. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/name_utils.py +8 -0
  25. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/entry_points/ep_mcp.py +13 -0
  26. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/simple/delete_module_factory.py +1 -1
  27. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/simple/use_case_factory.py +4 -4
  28. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/app.py.jinja2 +2 -1
  29. scaffold_ca_python-0.5.0/src/scaffold_ca_python/templates/entry_point/mcp/routes.py.jinja2 +25 -0
  30. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/test_app.py.jinja2 +17 -0
  31. scaffold_ca_python-0.5.0/src/scaffold_ca_python/templates/entry_point/mcp/test_routes.py.jinja2 +25 -0
  32. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/use_case/test_use_case.py.jinja2 +1 -1
  33. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_delete_module.py +68 -0
  34. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_generate_entry_point.py +35 -0
  35. scaffold_ca_python-0.5.0/tests/commands/test_generate_use_case.py +245 -0
  36. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_performance.py +3 -3
  37. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_workflow.py +1 -1
  38. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_module_locator.py +47 -0
  39. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_name_utils.py +25 -0
  40. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/entry_points/test_ep_mcp.py +30 -0
  41. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/fixtures/dry_run_baseline.json +2 -0
  42. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/simple/test_use_case_factory.py +4 -4
  43. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_entry_point_templates.py +79 -0
  44. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_use_case_templates.py +11 -0
  45. scaffold_ca_python-0.3.0/.release-please-manifest.json +0 -3
  46. scaffold_ca_python-0.3.0/tests/commands/test_generate_use_case.py +0 -132
  47. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-analyze/SKILL.md +0 -0
  48. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-checklist/SKILL.md +0 -0
  49. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-clarify/SKILL.md +0 -0
  50. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-constitution/SKILL.md +0 -0
  51. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-converge/SKILL.md +0 -0
  52. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-implement/SKILL.md +0 -0
  53. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-plan/SKILL.md +0 -0
  54. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-specify/SKILL.md +0 -0
  55. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-tasks/SKILL.md +0 -0
  56. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.claude/skills/speckit-taskstoissues/SKILL.md +0 -0
  57. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-analyze/SKILL.md +0 -0
  58. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-checklist/SKILL.md +0 -0
  59. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-clarify/SKILL.md +0 -0
  60. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-constitution/SKILL.md +0 -0
  61. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-converge/SKILL.md +0 -0
  62. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-implement/SKILL.md +0 -0
  63. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-plan/SKILL.md +0 -0
  64. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-specify/SKILL.md +0 -0
  65. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-tasks/SKILL.md +0 -0
  66. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.cursor/skills/speckit-taskstoissues/SKILL.md +0 -0
  67. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/copilot-instructions.md +0 -0
  68. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/issue_template.md +0 -0
  69. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/pull_request_template.md +0 -0
  70. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-analyze/SKILL.md +0 -0
  71. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-checklist/SKILL.md +0 -0
  72. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-clarify/SKILL.md +0 -0
  73. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-constitution/SKILL.md +0 -0
  74. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-converge/SKILL.md +0 -0
  75. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-implement/SKILL.md +0 -0
  76. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-plan/SKILL.md +0 -0
  77. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-specify/SKILL.md +0 -0
  78. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-tasks/SKILL.md +0 -0
  79. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/skills/speckit-taskstoissues/SKILL.md +0 -0
  80. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/workflows/build.yml +0 -0
  81. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/workflows/dependency-review.yml +0 -0
  82. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/workflows/publish.yml +0 -0
  83. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/workflows/release-please.yml +0 -0
  84. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/workflows/scorecards-analysis.yml +0 -0
  85. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.github/workflows/secret-scanner.yml +0 -0
  86. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.gitignore +0 -0
  87. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.pre-commit-config.yaml +0 -0
  88. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.python-version +0 -0
  89. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/.gitignore +0 -0
  90. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/init-options.json +0 -0
  91. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/integration.json +0 -0
  92. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/integrations/claude.manifest.json +0 -0
  93. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/integrations/copilot.manifest.json +0 -0
  94. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/integrations/cursor-agent.manifest.json +0 -0
  95. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/integrations/speckit.manifest.json +0 -0
  96. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/memory/constitution.md +0 -0
  97. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/check-prerequisites.sh +0 -0
  98. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/common.sh +0 -0
  99. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/create-new-feature.sh +0 -0
  100. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/resolve-template.sh +0 -0
  101. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/setup-plan.sh +0 -0
  102. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/setup-tasks.sh +0 -0
  103. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/scripts/bash/update-agent-context.sh +0 -0
  104. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/templates/agent-file-template.md +0 -0
  105. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/templates/checklist-template.md +0 -0
  106. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/templates/constitution-template.md +0 -0
  107. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/templates/plan-template.md +0 -0
  108. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/templates/spec-template.md +0 -0
  109. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/.specify/templates/tasks-template.md +0 -0
  110. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/LICENSE +0 -0
  111. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/SECURITY.md +0 -0
  112. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/pyproject.toml +0 -0
  113. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/release-please-config.json +0 -0
  114. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/checklists/requirements.md +0 -0
  115. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/ca.md +0 -0
  116. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/dm.md +0 -0
  117. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/gda.md +0 -0
  118. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/gep.md +0 -0
  119. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/gh.md +0 -0
  120. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/gm.md +0 -0
  121. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/gpipe.md +0 -0
  122. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/guc.md +0 -0
  123. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/up.md +0 -0
  124. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/contracts/vs.md +0 -0
  125. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/data-model.md +0 -0
  126. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/plan.md +0 -0
  127. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/quickstart.md +0 -0
  128. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/research.md +0 -0
  129. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/spec.md +0 -0
  130. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/004-scaffold-ca-python-cli/tasks.md +0 -0
  131. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/006-ca-scaffold-enhancements/checklists/requirements.md +0 -0
  132. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/006-ca-scaffold-enhancements/plan.md +0 -0
  133. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/006-ca-scaffold-enhancements/spec.md +0 -0
  134. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/006-ca-scaffold-enhancements/tasks.md +0 -0
  135. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/checklists/requirements.md +0 -0
  136. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/contracts/clean-architecture.md +0 -0
  137. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/contracts/gda.md +0 -0
  138. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/contracts/gep.md +0 -0
  139. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/contracts/gpipe.md +0 -0
  140. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/data-model.md +0 -0
  141. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/plan.md +0 -0
  142. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/quickstart.md +0 -0
  143. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/research.md +0 -0
  144. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/spec.md +0 -0
  145. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/007-cli-usability-enhancements/tasks.md +0 -0
  146. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/checklists/requirements.md +0 -0
  147. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/contracts/gep.md +0 -0
  148. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/data-model.md +0 -0
  149. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/plan.md +0 -0
  150. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/quickstart.md +0 -0
  151. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/research.md +0 -0
  152. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/spec.md +0 -0
  153. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/008-fastapi-entrypoint-baseline/tasks.md +0 -0
  154. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/checklists/requirements.md +0 -0
  155. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/contracts/gep-restapi.md +0 -0
  156. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/data-model.md +0 -0
  157. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/plan.md +0 -0
  158. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/quickstart.md +0 -0
  159. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/research.md +0 -0
  160. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/spec.md +0 -0
  161. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/009-app-factory-split/tasks.md +0 -0
  162. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/011-fix-restapi-cleanup/data-model.md +0 -0
  163. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/011-fix-restapi-cleanup/plan.md +0 -0
  164. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/011-fix-restapi-cleanup/quickstart.md +0 -0
  165. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/011-fix-restapi-cleanup/research.md +0 -0
  166. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/011-fix-restapi-cleanup/spec.md +0 -0
  167. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/011-fix-restapi-cleanup/tasks.md +0 -0
  168. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/checklists/requirements.md +0 -0
  169. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/data-model.md +0 -0
  170. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/plan.md +0 -0
  171. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/quickstart.md +0 -0
  172. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/research.md +0 -0
  173. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/spec.md +0 -0
  174. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/012-fix-restapi-test-templates/tasks.md +0 -0
  175. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/checklists/requirements.md +0 -0
  176. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/data-model.md +0 -0
  177. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/plan.md +0 -0
  178. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/quickstart.md +0 -0
  179. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/research.md +0 -0
  180. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/spec.md +0 -0
  181. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/014-tests-in-src/tasks.md +0 -0
  182. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/checklists/requirements.md +0 -0
  183. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/data-model.md +0 -0
  184. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/plan.md +0 -0
  185. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/quickstart.md +0 -0
  186. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/research.md +0 -0
  187. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/spec.md +0 -0
  188. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/015-factory-builder-refactor/tasks.md +0 -0
  189. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/016-dedup-command-aliases/checklists/requirements.md +0 -0
  190. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/016-dedup-command-aliases/data-model.md +0 -0
  191. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/016-dedup-command-aliases/plan.md +0 -0
  192. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/016-dedup-command-aliases/research.md +0 -0
  193. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/016-dedup-command-aliases/spec.md +0 -0
  194. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/016-dedup-command-aliases/tasks.md +0 -0
  195. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/checklists/requirements.md +0 -0
  196. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/contracts/name-validation.md +0 -0
  197. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/data-model.md +0 -0
  198. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/plan.md +0 -0
  199. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/research.md +0 -0
  200. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/spec.md +0 -0
  201. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/017-pep8-naming-validation/tasks.md +0 -0
  202. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/019-mcp-entry-point-restructure/contracts/gep-mcp.md +0 -0
  203. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/019-mcp-entry-point-restructure/data-model.md +0 -0
  204. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/019-mcp-entry-point-restructure/plan.md +0 -0
  205. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/019-mcp-entry-point-restructure/research.md +0 -0
  206. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/019-mcp-entry-point-restructure/spec.md +0 -0
  207. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/019-mcp-entry-point-restructure/tasks.md +0 -0
  208. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/checklists/requirements.md +0 -0
  209. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/contracts/readme-outline.md +0 -0
  210. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/data-model.md +0 -0
  211. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/plan.md +0 -0
  212. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/quickstart.md +0 -0
  213. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/research.md +0 -0
  214. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/spec.md +0 -0
  215. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/020-pypi-publish-readme/tasks.md +0 -0
  216. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/checklists/requirements.md +0 -0
  217. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/contracts/gep-add-tool.md +0 -0
  218. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/data-model.md +0 -0
  219. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/plan.md +0 -0
  220. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/quickstart.md +0 -0
  221. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/research.md +0 -0
  222. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/spec.md +0 -0
  223. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/021-mcp-add-tool/tasks.md +0 -0
  224. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/checklists/requirements.md +0 -0
  225. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/contracts/cli-behavior.md +0 -0
  226. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/contracts/factory-extension.md +0 -0
  227. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/data-model.md +0 -0
  228. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/plan.md +0 -0
  229. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/quickstart.md +0 -0
  230. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/research.md +0 -0
  231. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/spec.md +0 -0
  232. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/022-solid-code-cleanup/tasks.md +0 -0
  233. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/023-error-hints/spec.md +0 -0
  234. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/024-typed-template-contexts/spec.md +0 -0
  235. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/checklists/requirements.md +0 -0
  236. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/contracts/dm.md +0 -0
  237. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/contracts/gm.md +0 -0
  238. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/data-model.md +0 -0
  239. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/plan.md +0 -0
  240. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/quickstart.md +0 -0
  241. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/research.md +0 -0
  242. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/spec.md +0 -0
  243. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/specs/025-model-gateway-generation/tasks.md +0 -0
  244. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/__init__.py +0 -0
  245. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/cli.py +0 -0
  246. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/__init__.py +0 -0
  247. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/_entry_point_rules.py +0 -0
  248. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/_shared.py +0 -0
  249. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/add_mcp_tool.py +0 -0
  250. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/delete_module.py +0 -0
  251. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_driven_adapter.py +0 -0
  252. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_entry_point.py +0 -0
  253. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_helper.py +0 -0
  254. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_model.py +0 -0
  255. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_pipeline.py +0 -0
  256. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/generate_project.py +0 -0
  257. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/update_project.py +0 -0
  258. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/commands/validate_structure.py +0 -0
  259. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/__init__.py +0 -0
  260. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/file_writer.py +0 -0
  261. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/mcp_tool_spec.py +0 -0
  262. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/module_builder.py +0 -0
  263. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/openapi_routes.py +0 -0
  264. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/project_detector.py +0 -0
  265. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/pyproject_writer.py +0 -0
  266. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/structure_validator.py +0 -0
  267. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/core/template_renderer.py +0 -0
  268. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/__init__.py +0 -0
  269. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/driven_adapters/__init__.py +0 -0
  270. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/driven_adapters/base.py +0 -0
  271. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/driven_adapters/da_generic.py +0 -0
  272. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/driven_adapters/da_rest_consumer.py +0 -0
  273. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/driven_adapters/da_secrets.py +0 -0
  274. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/entry_points/__init__.py +0 -0
  275. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/entry_points/base.py +0 -0
  276. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/entry_points/ep_agent.py +0 -0
  277. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/entry_points/ep_generic.py +0 -0
  278. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/entry_points/ep_restapi.py +0 -0
  279. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/pipelines/__init__.py +0 -0
  280. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/pipelines/pipeline_factory.py +0 -0
  281. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/simple/__init__.py +0 -0
  282. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/simple/helper_factory.py +0 -0
  283. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/factory/simple/model_factory.py +0 -0
  284. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/models/__init__.py +0 -0
  285. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/models/context.py +0 -0
  286. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/models/file_operation.py +0 -0
  287. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/models/layer.py +0 -0
  288. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/models/options.py +0 -0
  289. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/models/violation.py +0 -0
  290. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/__init__.py +0 -0
  291. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/generic/__init__.py.jinja2 +0 -0
  292. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/generic/adapter.py.jinja2 +0 -0
  293. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/generic/test_adapter.py.jinja2 +0 -0
  294. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/rest_consumer/__init__.py.jinja2 +0 -0
  295. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/rest_consumer/rest_consumer.py.jinja2 +0 -0
  296. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/rest_consumer/test_rest_consumer.py.jinja2 +0 -0
  297. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/secrets/__init__.py.jinja2 +0 -0
  298. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/secrets/secrets_adapter.py.jinja2 +0 -0
  299. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/driven_adapter/secrets/test_secrets_adapter.py.jinja2 +0 -0
  300. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/agent/__init__.py.jinja2 +0 -0
  301. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/agent/agent.py.jinja2 +0 -0
  302. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/agent/card.py.jinja2 +0 -0
  303. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/agent/entrypoint_main.py.jinja2 +0 -0
  304. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/agent/test_agent.py.jinja2 +0 -0
  305. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/generic/__init__.py.jinja2 +0 -0
  306. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/generic/entrypoint_main.py.jinja2 +0 -0
  307. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/generic/handler.py.jinja2 +0 -0
  308. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/generic/test_handler.py.jinja2 +0 -0
  309. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/__init__.py.jinja2 +0 -0
  310. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/prompts.py.jinja2 +0 -0
  311. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/resources.py.jinja2 +0 -0
  312. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/server.py.jinja2 +0 -0
  313. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/test_prompts.py.jinja2 +0 -0
  314. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/test_resources.py.jinja2 +0 -0
  315. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/test_tool_stub.py.jinja2 +0 -0
  316. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/test_tools.py.jinja2 +0 -0
  317. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/tool_stub.py.jinja2 +0 -0
  318. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/mcp/tools.py.jinja2 +0 -0
  319. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/__init__.py.jinja2 +0 -0
  320. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/app.py.jinja2 +0 -0
  321. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/exception_handler.py.jinja2 +0 -0
  322. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/health.py.jinja2 +0 -0
  323. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/rest_controller.py.jinja2 +0 -0
  324. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/server.py.jinja2 +0 -0
  325. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/test_app.py.jinja2 +0 -0
  326. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/test_exception_handler.py.jinja2 +0 -0
  327. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/test_rest_controller.py.jinja2 +0 -0
  328. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/entry_point/restapi/test_server.py.jinja2 +0 -0
  329. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/helper/__init__.py.jinja2 +0 -0
  330. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/helper/helper.py.jinja2 +0 -0
  331. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/helper/test_helper.py.jinja2 +0 -0
  332. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/model/__init__.py.jinja2 +0 -0
  333. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/model/gateway.py.jinja2 +0 -0
  334. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/model/gateways_init.py.jinja2 +0 -0
  335. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/model/model.py.jinja2 +0 -0
  336. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/model/test_gateway.py.jinja2 +0 -0
  337. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/model/test_model.py.jinja2 +0 -0
  338. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/pipeline/azure/azure_pipelines.yml.jinja2 +0 -0
  339. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/pipeline/github/ci.yml.jinja2 +0 -0
  340. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/README.jinja2 +0 -0
  341. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/application/config/__init__.py.jinja2 +0 -0
  342. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/application/config/config.py.jinja2 +0 -0
  343. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/application/config/container.py.jinja2 +0 -0
  344. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/application/config/driven_adapters_container.py.jinja2 +0 -0
  345. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/application/config/resource_container.py.jinja2 +0 -0
  346. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/application/config/usecases_container.py.jinja2 +0 -0
  347. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/dockerfile.jinja2 +0 -0
  348. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/dockerignore.jinja2 +0 -0
  349. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/empty.jinja2 +0 -0
  350. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/gitignore.jinja2 +0 -0
  351. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/layer_init.jinja2 +0 -0
  352. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/main.py.jinja2 +0 -0
  353. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/mypy_ini.jinja2 +0 -0
  354. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/package_init.py.jinja2 +0 -0
  355. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/pyproject_toml.jinja2 +0 -0
  356. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/project/python_version.jinja2 +0 -0
  357. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/src/scaffold_ca_python/templates/use_case/use_case.py.jinja2 +0 -0
  358. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/__init__.py +0 -0
  359. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/__init__.py +0 -0
  360. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_behavior_contract.py +0 -0
  361. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_cli.py +0 -0
  362. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_dry_run_checksum.py +0 -0
  363. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_generate_driven_adapter.py +0 -0
  364. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_generate_helper.py +0 -0
  365. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_generate_model.py +0 -0
  366. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_generate_pipeline.py +0 -0
  367. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_generate_project.py +0 -0
  368. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_shared.py +0 -0
  369. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_update_project.py +0 -0
  370. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/commands/test_validate_structure.py +0 -0
  371. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/conftest.py +0 -0
  372. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/__init__.py +0 -0
  373. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_file_writer.py +0 -0
  374. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_mcp_tool_spec.py +0 -0
  375. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_openapi_routes.py +0 -0
  376. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_project_context.py +0 -0
  377. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_project_detector.py +0 -0
  378. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_pyproject_writer.py +0 -0
  379. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_structure_validator.py +0 -0
  380. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/core/test_template_renderer.py +0 -0
  381. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/__init__.py +0 -0
  382. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/driven_adapters/__init__.py +0 -0
  383. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/driven_adapters/test_da_generic.py +0 -0
  384. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/driven_adapters/test_da_rest_consumer.py +0 -0
  385. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/driven_adapters/test_da_secrets.py +0 -0
  386. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/entry_points/__init__.py +0 -0
  387. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/entry_points/test_ep_agent.py +0 -0
  388. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/entry_points/test_ep_generic.py +0 -0
  389. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/entry_points/test_ep_restapi.py +0 -0
  390. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/simple/__init__.py +0 -0
  391. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/simple/test_delete_module_factory.py +0 -0
  392. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/simple/test_helper_factory.py +0 -0
  393. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/simple/test_model_factory.py +0 -0
  394. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/test_dry_run_parity.py +0 -0
  395. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/test_extensibility.py +0 -0
  396. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/test_module_builder.py +0 -0
  397. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/factory/test_registry.py +0 -0
  398. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/models/__init__.py +0 -0
  399. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/models/test_context.py +0 -0
  400. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/models/test_file_operation.py +0 -0
  401. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/models/test_layer.py +0 -0
  402. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/models/test_options.py +0 -0
  403. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/models/test_violation.py +0 -0
  404. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/__init__.py +0 -0
  405. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_di_config_templates.py +0 -0
  406. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_docker_templates.py +0 -0
  407. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_driven_adapter_templates.py +0 -0
  408. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_entrypoint_main_templates.py +0 -0
  409. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_helper_templates.py +0 -0
  410. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_model_templates.py +0 -0
  411. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_pipeline_templates.py +0 -0
  412. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/templates/test_project_templates.py +0 -0
  413. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/tests/test_source_hygiene.py +0 -0
  414. {scaffold_ca_python-0.3.0 → scaffold_ca_python-0.5.0}/uv.lock +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.5.0"
3
+ }
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.0](https://github.com/bancolombia/scaffold-clean-architecture-py/compare/v0.4.0...v0.5.0) (2026-10-27)
4
+
5
+
6
+ ### Features
7
+
8
+ * **mcp:** generate health check route for MCP entry points ([70a2645](https://github.com/bancolombia/scaffold-clean-architecture-py/commit/70a2645e63957d211761e7535edc675685031d57))
9
+
10
+ ## [0.4.0](https://github.com/bancolombia/scaffold-clean-architecture-py/compare/v0.3.0...v0.4.0) (2026-10-26)
11
+
12
+
13
+ ### Features
14
+
15
+ * **usecase:** standardize generated use-case module names ([74a19b2](https://github.com/bancolombia/scaffold-clean-architecture-py/commit/74a19b20a448aff780e6439b2814541480ba1111))
16
+
3
17
  ## [0.3.0](https://github.com/bancolombia/scaffold-clean-architecture-py/compare/v0.2.1...v0.3.0) (2026-10-26)
4
18
 
5
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: scaffold-ca-python
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: Scaffolder to generate Clean Architecture apps
5
5
  Project-URL: Homepage, https://github.com/bancolombia/scaffold-clean-architecture-py
6
6
  Project-URL: Repository, https://github.com/bancolombia/scaffold-clean-architecture-py
@@ -128,7 +128,7 @@ scaffold gm --name order --dry-run
128
128
 
129
129
  ### scaffold guc
130
130
 
131
- Scaffold a use case in `domain/usecase/`.
131
+ Scaffold a use case in `domain/usecase/`. The module is always named `<name>_usecase.py` and the class `<Name>UseCase`. Writing `_usecase` in `--name` is optional and the suffix is never duplicated: `create_order`, `create_order_usecase` and `create_order_use_case` all create `create_order_usecase.py` with `CreateOrderUseCase`.
132
132
 
133
133
  ```bash
134
134
  scaffold guc --name create_order
@@ -97,7 +97,7 @@ scaffold gm --name order --dry-run
97
97
 
98
98
  ### scaffold guc
99
99
 
100
- Scaffold a use case in `domain/usecase/`.
100
+ Scaffold a use case in `domain/usecase/`. The module is always named `<name>_usecase.py` and the class `<Name>UseCase`. Writing `_usecase` in `--name` is optional and the suffix is never duplicated: `create_order`, `create_order_usecase` and `create_order_use_case` all create `create_order_usecase.py` with `CreateOrderUseCase`.
101
101
 
102
102
  ```bash
103
103
  scaffold guc --name create_order
@@ -0,0 +1,36 @@
1
+ # Specification Quality Checklist: Use Case Naming Standardization
2
+
3
+ **Purpose**: Validate specification completeness and quality before proceeding to planning
4
+ **Created**: 2026-10-26
5
+ **Feature**: [spec.md](../spec.md)
6
+
7
+ ## Content Quality
8
+
9
+ - [x] No implementation details (languages, frameworks, APIs)
10
+ - [x] Focused on user value and business needs
11
+ - [x] Written for non-technical stakeholders
12
+ - [x] All mandatory sections completed
13
+
14
+ ## Requirement Completeness
15
+
16
+ - [x] No [NEEDS CLARIFICATION] markers remain
17
+ - [x] Requirements are testable and unambiguous
18
+ - [x] Success criteria are measurable
19
+ - [x] Success criteria are technology-agnostic (no implementation details)
20
+ - [x] All acceptance scenarios are defined
21
+ - [x] Edge cases are identified
22
+ - [x] Scope is clearly bounded
23
+ - [x] Dependencies and assumptions identified
24
+
25
+ ## Feature Readiness
26
+
27
+ - [x] All functional requirements have clear acceptance criteria
28
+ - [x] User scenarios cover primary flows
29
+ - [x] Feature meets measurable outcomes defined in Success Criteria
30
+ - [x] No implementation details leak into specification
31
+
32
+ ## Notes
33
+
34
+ - The spec references CLI command names, file paths, and class names. For a code generator these are the user-facing output, not implementation details, so they are kept (same approach as `specs/025-model-gateway-generation/spec.md`).
35
+ - Scope decisions agreed with the user before writing: both `_usecase` and `_use_case` suffixes are recognized, the delete-module command is in scope, and the branch is created from `main`.
36
+ - Validation passed on the first iteration after aligning SC-003 with the repeated-suffix edge case.
@@ -0,0 +1,22 @@
1
+ # CLI Contract changes: `scaffold dm` / `scaffold delete-module`
2
+
3
+ Only the use case lookup changes. Flags, messages, and exit codes stay the same.
4
+
5
+ ## Use case candidates (in order)
6
+
7
+ | Layout | Source target | Test target |
8
+ |---|---|---|
9
+ | New | `src/<pkg>/domain/usecase/<base>_usecase.py` | `src/tests/domain/usecase/test_<base>_usecase.py` (if present) |
10
+ | Legacy | `src/<pkg>/domain/usecase/<name>.py` | `src/tests/domain/usecase/test_<name>.py` (if present) |
11
+
12
+ `<base>` is `--name` with trailing `_usecase` / `_use_case` suffixes removed. A candidate is listed once even if both rows resolve to the same file. The new row is skipped when `<base>` is empty.
13
+
14
+ ## Outcomes for use cases
15
+
16
+ | Situation | Exit | Effect |
17
+ |---|---|---|
18
+ | `dm --name book` or `dm --name book_usecase`, new file exists | 0 | preview lists `book_usecase.py` and its test; `--confirm` removes both |
19
+ | `dm --name book`, only legacy `book.py` exists | 0 | preview lists `book.py` and its test; `--confirm` removes both, as today |
20
+ | `dm --name book`, model package `domain/model/book/` and `book_usecase.py` both exist | 0 | preview lists the model package, its tests folder, `book_usecase.py`, and its test; `--confirm` removes all of them (existing cross-layer behavior) |
21
+ | `dm --name book`, both layouts exist | 0 | preview lists all 4 files; `--confirm` removes all 4 |
22
+ | no match | 1 | existing "No module named ..." error |
@@ -0,0 +1,38 @@
1
+ # CLI Contract changes: `scaffold guc` / `scaffold generate-use-case`
2
+
3
+ Flags, aliases, the no-argument help, name validation, and project-root errors stay the same. Only the generated names and two error cases change.
4
+
5
+ ## Outputs
6
+
7
+ | `--name` | Created files | Class |
8
+ |---|---|---|
9
+ | `create_order` | `src/<pkg>/domain/usecase/create_order_usecase.py`, `src/tests/domain/usecase/test_create_order_usecase.py` | `CreateOrderUseCase` |
10
+ | `create_order_usecase` | same as above | `CreateOrderUseCase` |
11
+ | `create_order_use_case` | same as above | `CreateOrderUseCase` |
12
+ | `create_order_usecase_usecase` | same as above | `CreateOrderUseCase` |
13
+ | `usecase_registry` | `usecase_registry_usecase.py`, `test_usecase_registry_usecase.py` | `UsecaseRegistryUseCase` |
14
+
15
+ The generated test imports `from <pkg>.domain.usecase.<base>_usecase import <Base>UseCase`.
16
+
17
+ ## Outcomes
18
+
19
+ | Situation | Exit | Output | Effect |
20
+ |---|---|---|---|
21
+ | Success | 0 | `✓ Use case <Base>UseCase created. Created 2 file(s).` | 2 files written |
22
+ | `--dry-run` | 0 | Tree titled `<base>_usecase (dry run)` listing the 2 paths | nothing written |
23
+ | `<base>_usecase.py` already exists (any spelling) | 1 | `Error: File 'src/<pkg>/domain/usecase/<base>_usecase.py' already exists.` plus the existing hint | nothing written |
24
+ | `src/tests/domain/usecase/test_<base>_usecase.py` already exists | 1 | `Error: File 'src/tests/domain/usecase/test_<base>_usecase.py' already exists.` plus the same hint | nothing written |
25
+ | Legacy `<base>.py` exists | 0 | normal success | `<base>_usecase.py` created, legacy file untouched, no warning |
26
+ | Name is only the suffix (`usecase`, `use_case`, `usecase_usecase`) | 1 | `Error: Use case name '<name>' is only the 'usecase' suffix.` / `Hint: Use a descriptive name such as 'create_order'.` | nothing written |
27
+
28
+ ## Help text
29
+
30
+ Epilog example becomes:
31
+
32
+ ```text
33
+ Example:
34
+
35
+ * scaffold guc --name create_order (creates domain/usecase/create_order_usecase.py)
36
+
37
+ * scaffold generate-use-case --name create_order
38
+ ```
@@ -0,0 +1,36 @@
1
+ # Data Model: Use Case Naming Standardization
2
+
3
+ No new runtime models. The feature derives three names from the user's `--name` value and reuses the existing `ModuleContext`.
4
+
5
+ ## Derived names
6
+
7
+ | Name | Rule | Example (`--name create_order_usecase`) |
8
+ |---|---|---|
9
+ | Raw name | `--name` as typed. Validated by `validate_module_name` (snake_case only). | `create_order_usecase` |
10
+ | Base name | `strip_usecase_suffix(raw)` (research R2). Must be non-empty. | `create_order` |
11
+ | Module name | `<base>_usecase` | `create_order_usecase` |
12
+ | Class name | `to_pascal_case(base) + "UseCase"` | `CreateOrderUseCase` |
13
+
14
+ ## ModuleContext usage
15
+
16
+ `ModuleContext(name=<base>, layer=Layer.DOMAIN_USECASE, project=...)`. It is unchanged, only the value passed as `name` differs.
17
+
18
+ | Field | Value | Used by |
19
+ |---|---|---|
20
+ | `name` | base name | factory path |
21
+ | `class_name` | `<Base>` | both templates (`{{ class_name }}UseCase`), success message |
22
+ | `module_name` | `<base>` | factory path (`<base>_usecase.py`), test import (`{{ module_name }}_usecase`), test function name |
23
+
24
+ ## Generated files
25
+
26
+ | File | Path |
27
+ |---|---|
28
+ | Use case module | `src/<pkg>/domain/usecase/<base>_usecase.py` |
29
+ | Test stub | `src/tests/domain/usecase/test_<base>_usecase.py` |
30
+
31
+ ## Validation rules
32
+
33
+ 1. The raw name must match snake_case (existing rule, existing message).
34
+ 2. The base name must be non-empty. Otherwise exit 1 with a hint (FR-008).
35
+ 3. `src/<pkg>/domain/usecase/<base>_usecase.py` must not exist. Otherwise exit 1 with a hint (FR-009). Legacy `<base>.py` is ignored (FR-009a).
36
+ 4. `src/tests/domain/usecase/test_<base>_usecase.py` must not exist. Otherwise exit 1 with a hint (FR-009b).
@@ -0,0 +1,109 @@
1
+ # Implementation Plan: Use Case Naming Standardization
2
+
3
+ **Branch**: `feature/usecase-naming-standardization` | **Date**: 2026-10-26 | **Spec**: [spec.md](spec.md)
4
+
5
+ **Input**: Feature specification from `/specs/026-usecase-naming-standardization/spec.md`
6
+
7
+ ## Summary
8
+
9
+ `scaffold guc --name <name>` always writes `domain/usecase/<base>_usecase.py` with `class <Base>UseCase`. `<base>` is `--name` with any trailing `_usecase` / `_use_case` suffixes removed, so the suffix never appears twice. A single helper, `strip_usecase_suffix`, in `name_utils` does the normalization. The command passes the base name into the existing `ModuleContext`. The factory and the test template append `_usecase`. Module lookup gains one candidate (`<base>_usecase.py`) ahead of the legacy `<name>.py`, so delete-module finds use cases by base name, by suffixed name, and in both layouts, with no change to the delete factory.
10
+
11
+ ## Technical Context
12
+
13
+ **Language/Version**: Python 3.13+
14
+
15
+ **Primary Dependencies**: Typer, Rich, Jinja2, Pydantic v2 (no new dependencies)
16
+
17
+ **Storage**: Files on disk via the existing `FileWriter`
18
+
19
+ **Testing**: pytest + pytest-cov (80% gate)
20
+
21
+ **Target Platform**: macOS / Linux developer machines (CLI)
22
+
23
+ **Project Type**: CLI code generator
24
+
25
+ **Performance Goals**: `guc` stays under the existing 3 s benchmark (`tests/commands/test_performance.py`)
26
+
27
+ **Constraints**: Generated code must pass the generated project's ruff, mypy strict, and pytest without edits. `ModuleContext` is shared by all generators and must not change behavior.
28
+
29
+ **Scale/Scope**: 1 changed template, 4 changed source modules, about 7 test files updated or extended, and a README section
30
+
31
+ ## Constitution Check
32
+
33
+ *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
34
+
35
+ | Principle | Status | Notes |
36
+ |---|---|---|
37
+ | I. Clean Architecture in generated projects | PASS | Files still land in `domain/usecase/`. `vs` classifies by the `("domain", "usecase")` prefix, so file names do not matter. |
38
+ | II. Template-driven generation | PASS | Both files still come from `templates/use_case/*.jinja2`. The changed test template gets a rendering test for the new import. Context is the existing Pydantic `ModuleContext`. |
39
+ | III. Command parity | PASS | `guc` / `generate-use-case` and `dm` / `delete-module` keep names, aliases, and `--dry-run`. |
40
+ | IV. Python-first idioms | PASS | `strip_usecase_suffix` is fully typed; ruff and mypy strict apply. |
41
+ | V. Test-first | PASS | Every step below starts with a failing test. The generated project still gets its test stub. |
42
+ | VI. Developer experience | PASS | The new suffix-only error uses `fail()` with a hint. The help epilog shows the generated file name. |
43
+ | VII. Branch naming | PASS | Work happens on `feature/usecase-naming-standardization`, already created from `main`. |
44
+
45
+ No violations, so Complexity Tracking is empty.
46
+
47
+ **Post-design re-check (after Phase 1)**: All gates still PASS. The design adds one pure function and one lookup candidate, with no new abstractions.
48
+
49
+ ## Project Structure
50
+
51
+ ### Documentation (this feature)
52
+
53
+ ```text
54
+ specs/026-usecase-naming-standardization/
55
+ ├── plan.md
56
+ ├── research.md
57
+ ├── data-model.md
58
+ ├── quickstart.md
59
+ ├── contracts/
60
+ │ ├── guc.md
61
+ │ └── dm.md
62
+ ├── checklists/requirements.md
63
+ └── tasks.md # created by /speckit-tasks
64
+ ```
65
+
66
+ ### Source Code (repository root)
67
+
68
+ ```text
69
+ src/scaffold_ca_python/
70
+ ├── core/
71
+ │ ├── name_utils.py # NEW fn: strip_usecase_suffix(name) -> str
72
+ │ └── module_locator.py # add <base>_usecase.py candidate before <name>.py, dedupe
73
+ ├── commands/
74
+ │ └── generate_use_case.py # normalize name, empty-base error, src + test conflict checks, dry-run title, epilog
75
+ ├── factory/simple/
76
+ │ ├── use_case_factory.py # write <base>_usecase.py / test_<base>_usecase.py
77
+ │ └── delete_module_factory.py # docstring only (lookup already shared)
78
+ └── templates/use_case/
79
+ ├── use_case.py.jinja2 # unchanged
80
+ └── test_use_case.py.jinja2 # CHANGED: import from ...usecase.{{ module_name }}_usecase
81
+
82
+ tests/
83
+ ├── core/test_name_utils.py # strip_usecase_suffix table (research R2)
84
+ ├── core/test_module_locator.py # base name, suffixed name, both layouts, dedupe
85
+ ├── templates/test_use_case_templates.py # new import path
86
+ ├── factory/simple/test_use_case_factory.py # new queued paths
87
+ ├── commands/test_generate_use_case.py # new paths, 3 spellings, repeated suffix, empty base, conflict, legacy ignored, dry-run
88
+ ├── commands/test_delete_module.py # delete by base / suffixed name, both layouts
89
+ ├── commands/test_workflow.py # new use case path
90
+ └── commands/test_performance.py # --name perf, cleanup perf_usecase.py / test_perf_usecase.py
91
+ ```
92
+
93
+ **Structure Decision**: Single-project CLI. Every change fits into existing modules. No new packages.
94
+
95
+ ## Implementation Order
96
+
97
+ 0. **Branch**: already on `feature/usecase-naming-standardization` (from `main`). Do not commit without asking the user.
98
+ 1. **Name helper (test-first)**: add the R2 table as parametrized tests in `test_name_utils.py`, then implement `strip_usecase_suffix`.
99
+ 2. **Template (test-first)**: assert the new import in `test_use_case_templates.py`, then change `test_use_case.py.jinja2`.
100
+ 3. **Factory (test-first)**: expect `create_order_usecase.py` / `test_create_order_usecase.py` in `test_use_case_factory.py`, then change `use_case_factory.py`.
101
+ 4. **Command (test-first)**: update and extend `test_generate_use_case.py` per [contracts/guc.md](contracts/guc.md), then normalize the name in `generate_use_case.py` (empty-base `fail()`, base-name `ModuleContext`, conflict path, dry-run title, epilog).
102
+ 5. **Lookup and delete (test-first)**: extend `test_module_locator.py` and `test_delete_module.py` per [contracts/dm.md](contracts/dm.md), then add the candidate in `module_locator.py` and update the `DeleteModuleFactory` docstring.
103
+ 6. **Remaining tests**: fix paths in `test_workflow.py` and the name and cleanup in `test_performance.py` (research R7).
104
+ 7. **Docs**: the README `scaffold guc` section notes the `<name>_usecase.py` output and that `_usecase` in `--name` is optional.
105
+ 8. **Validate**: run the [quickstart](quickstart.md), then `uv run ruff check`, `uv run ruff format --check`, `uv run mypy`, and `uv run pytest`.
106
+
107
+ ## Complexity Tracking
108
+
109
+ No constitution violations to justify.
@@ -0,0 +1,66 @@
1
+ # Quickstart: Use Case Naming Standardization
2
+
3
+ End-to-end checks for the [guc contract](contracts/guc.md) and the [dm contract](contracts/dm.md).
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ cd "$(mktemp -d)"
9
+ uv run --project /path/to/scaffold-clean-architecture-py scaffold ca --name demo-app
10
+ cd demo-app
11
+ alias scaffold='uv run --project /path/to/scaffold-clean-architecture-py scaffold'
12
+ ```
13
+
14
+ ## 1. Suffix is added and never duplicated
15
+
16
+ ```bash
17
+ scaffold guc --name paper
18
+ ls src/demo_app/domain/usecase/ # paper_usecase.py
19
+ ls src/tests/domain/usecase/ # test_paper_usecase.py
20
+ grep '^class' src/demo_app/domain/usecase/paper_usecase.py # class PaperUseCase:
21
+ ```
22
+
23
+ ```bash
24
+ scaffold guc --name create_order_usecase
25
+ grep '^class' src/demo_app/domain/usecase/create_order_usecase.py # class CreateOrderUseCase:
26
+ ```
27
+
28
+ Expected: no file name or class contains the suffix twice.
29
+
30
+ ## 2. Every spelling maps to the same module
31
+
32
+ ```bash
33
+ scaffold guc --name paper_use_case # exit 1: paper_usecase.py already exists
34
+ scaffold guc --name paper_usecase_usecase # exit 1: same file
35
+ scaffold guc --name usecase # exit 1: only the suffix, with hint
36
+ ```
37
+
38
+ ## 3. Dry-run matches the real run
39
+
40
+ ```bash
41
+ scaffold guc --name invoice_usecase --dry-run # lists invoice_usecase.py and test_invoice_usecase.py, writes nothing
42
+ ```
43
+
44
+ ## 4. Generated project stays green
45
+
46
+ ```bash
47
+ uv run ruff check . && uv run ruff format --check . && uv run mypy src && uv run pytest
48
+ ```
49
+
50
+ ## 5. Delete by base name, suffixed name, and both layouts
51
+
52
+ ```bash
53
+ scaffold dm --name paper # preview lists paper_usecase.py and its test
54
+ scaffold dm --name paper --confirm # both removed
55
+ scaffold dm --name create_order_usecase --confirm
56
+
57
+ touch src/demo_app/domain/usecase/invoice.py
58
+ scaffold guc --name invoice # succeeds, no warning; invoice.py untouched
59
+ scaffold dm --name invoice # preview lists invoice_usecase.py, its test, and invoice.py
60
+ ```
61
+
62
+ ## 6. CLI checks
63
+
64
+ ```bash
65
+ uv run ruff check && uv run ruff format --check && uv run mypy && uv run pytest
66
+ ```
@@ -0,0 +1,59 @@
1
+ # Research: Use Case Naming Standardization
2
+
3
+ ## R1. Where the name is normalized
4
+
5
+ - **Decision**: `generate_use_case.py` strips the suffix right after name validation and builds `ModuleContext(name=<base>, ...)`. All downstream names derive from the base name: `class_name` gives `<Base>` and `module_name` gives `<base>`. The factory and the test template append `_usecase`.
6
+ - **Rationale**: `ModuleContext` is shared by every generator, so changing its computed fields would affect models, adapters, and helpers (out of scope). Passing the base name keeps the existing `{{ class_name }}UseCase` template line correct and fixes the doubled suffix with no template logic.
7
+ - **Alternatives considered**:
8
+ - A use-case-specific context model with a `usecase_module` field. Rejected because it adds a type for one string concatenation.
9
+ - Stripping inside the Jinja template. Rejected because the file path is built in Python, not in the template, so the logic would be split across two places.
10
+
11
+ ## R2. Suffix-stripping rule
12
+
13
+ - **Decision**: Add `strip_usecase_suffix(name: str) -> str` to `core/name_utils.py`. It prefixes the name with `_`, removes `(?:_(?:usecase|use_case))+$`, and drops the leading `_`.
14
+ - **Rationale**: The leading `_` lets one regex handle both `book_usecase` and the suffix-only names `usecase` and `use_case` (which become empty), while `bookusecase` and `usecase_registry` stay untouched. The `+` removes repeated suffixes in any mix of spellings (clarification 2026-10-26).
15
+
16
+ | Input | Base |
17
+ |---|---|
18
+ | `book` | `book` |
19
+ | `book_usecase` / `book_use_case` | `book` |
20
+ | `paper_usecase_usecase` / `paper_use_case_usecase` | `paper` |
21
+ | `usecase_registry` | `usecase_registry` |
22
+ | `bookusecase` | `bookusecase` |
23
+ | `usecase` / `use_case` / `usecase_usecase` | empty |
24
+
25
+ - **Alternatives considered**: A `while name.endswith(...)` loop. It works but needs a separate case for the bare `usecase` / `use_case` names.
26
+
27
+ ## R3. Empty base name
28
+
29
+ - **Decision**: If the base is empty, call `fail()` with the message `Use case name '<name>' is only the 'usecase' suffix.` and the hint `Use a descriptive name such as 'create_order'.` This happens before the project-root lookup, right after `validate_name_or_exit`.
30
+ - **Rationale**: Reuses the existing `fail()` helper (exit 1 plus hint, Principle VI). Failing before any path is computed guarantees nothing is written.
31
+
32
+ ## R4. Template change
33
+
34
+ - **Decision**: Only `test_use_case.py.jinja2` changes. Its import becomes `from {{ project.python_package }}.domain.usecase.{{ module_name }}_usecase import {{ class_name }}UseCase`. `use_case.py.jinja2` is unchanged.
35
+ - **Rationale**: With the base name in context, the class line is already right. Only the module path in the import has to match the new file name.
36
+
37
+ ## R5. Lookup and deletion
38
+
39
+ - **Decision**: In `find_module_targets`, add a use case candidate `domain/usecase/<base>_usecase.py` (with `test_<base>_usecase.py`). It comes before the existing `domain/usecase/<snake>.py` candidate, which stays as the legacy lookup. If both candidates resolve to the same path (input already suffixed), it is added once. If the base is empty, the new candidate is skipped.
40
+ - **Rationale**: `DeleteModuleFactory` already iterates `find_module_targets`, so delete-module and its preview pick up the change with no edit there. Keeping the legacy candidate satisfies FR-014. Checking both candidates satisfies FR-014a, where both layouts are listed and removed.
41
+
42
+ | `dm --name` | Files checked |
43
+ |---|---|
44
+ | `book` | `book_usecase.py`, then `book.py` |
45
+ | `book_usecase` | `book_usecase.py` (once) |
46
+ | `book_use_case` | `book_usecase.py`, then `book_use_case.py` |
47
+
48
+ - **Alternatives considered**: Normalizing the name in `delete_module.py` before lookup. Rejected because the legacy `<name>.py` file (and models or helpers whose name ends in `_usecase`) would no longer be found.
49
+
50
+ ## R6. Conflict check
51
+
52
+ - **Decision**: `ensure_absent` checks both `src/<pkg>/domain/usecase/<base>_usecase.py` and `src/tests/domain/usecase/test_<base>_usecase.py`. Legacy `<base>.py` is not checked (clarification 2026-10-26, FR-009a).
53
+ - **Rationale**: All three spellings resolve to the same paths, so these checks cover FR-009. Checking the test file up front (FR-009b) avoids the `FileWriter` pre-flight raising an unhandled `FileExistsError` after parent folders were created. Feature 025 (research R4) found and fixed the same problem for models.
54
+
55
+ ## R7. Existing tests that encode the old names
56
+
57
+ - **Decision**: Update the paths in `tests/commands/test_generate_use_case.py`, `tests/factory/simple/test_use_case_factory.py`, `tests/commands/test_workflow.py`, and `tests/commands/test_performance.py`. In `test_performance.py`, also change `--name PerfCase` to `perf`, which generates `perf_usecase.py` with `class PerfUseCase`.
58
+ - **Rationale**: `PerfCase` has been rejected by snake_case validation since feature 017, so the benchmark measures an error path today. Fixing the name makes it time real generation, and the cleanup has to delete `perf_usecase.py` and `test_perf_usecase.py`. The base name `perf` follows the new convention (the suffix comes from the generator). `perf_case` would produce `perf_case_usecase.py`, mixing "case" and "use case".
59
+ - **Alternatives considered**: `--name perf_usecase`. It produces the same files, but the benchmark should time the plain generation path. Suffix stripping is already covered by the unit and command tests.
@@ -0,0 +1,170 @@
1
+ # Feature Specification: Use Case Naming Standardization
2
+
3
+ **Feature Branch**: `feature/usecase-naming-standardization`
4
+
5
+ **Created**: 2026-10-26
6
+
7
+ **Status**: Draft
8
+
9
+ **Input**: User description: "Standardize the naming of generated use cases in the `scaffold generate-use-case` (alias `guc`) command. The generated module must always end with `_usecase` (`<base>_usecase.py`) and the class must always be `<Base>UseCase`, whether or not the user includes the `usecase` word in `--name`, so the suffix is never duplicated."
10
+
11
+ ## Clarifications
12
+
13
+ ### Session 2026-10-26
14
+
15
+ - Q: If a legacy `domain/usecase/<name>.py` exists and the developer runs `scaffold guc --name <name>`, what should happen? → A: Ignore legacy files. Whatever `--name` the user sends (for example `paper`), the command always creates `<name>_usecase.py`, with no warning and no conflict. `book` in this spec is only an example name.
16
+ - Q: For a name that ends with the suffix more than once (for example `paper_usecase_usecase`), how many trailing suffixes are removed? → A: All of them, in any mix of `_usecase` and `_use_case`. The result is `paper_usecase.py` with the class `PaperUseCase`.
17
+ - Q: If both a legacy `<name>.py` and a new `<name>_usecase.py` exist, what does `scaffold dm --name <name>` delete? → A: Both files and their tests. The preview lists all of them before anything is removed.
18
+
19
+ ## User Scenarios & Testing *(mandatory)*
20
+
21
+ ### User Story 1 - Generated use case modules always carry the `_usecase` suffix (Priority: P1)
22
+
23
+ A developer working in a generated Clean Architecture project runs `scaffold guc --name book`. Today this creates `domain/usecase/book.py`, a file name that does not say it holds a use case. After this feature the command creates `domain/usecase/book_usecase.py` with the class `BookUseCase`, and the mirrored test `src/tests/domain/usecase/test_book_usecase.py`.
24
+
25
+ Resulting structure inside the generated project:
26
+
27
+ ```text
28
+ src/<package>/domain/usecase/
29
+ └── book_usecase.py # class BookUseCase
30
+ src/tests/domain/usecase/
31
+ └── test_book_usecase.py # imports BookUseCase from book_usecase
32
+ ```
33
+
34
+ **Why this priority**: This is the core of the feature. Every generated use case module becomes recognizable by name and follows one convention across all generated projects.
35
+
36
+ **Independent Test**: In a freshly scaffolded project, run `scaffold guc --name book` and verify the file names, the class name, and that the generated project's test suite passes.
37
+
38
+ **Acceptance Scenarios**:
39
+
40
+ 1. **Given** a valid project with no `book` use case, **When** the developer runs `scaffold guc --name book`, **Then** `domain/usecase/book_usecase.py` and `src/tests/domain/usecase/test_book_usecase.py` are created, and the command exits with code 0.
41
+ 2. **Given** the command above has run, **When** the developer opens `book_usecase.py`, **Then** it defines exactly one class named `BookUseCase`.
42
+ 3. **Given** the command above has run, **When** the developer opens `test_book_usecase.py`, **Then** it imports `BookUseCase` from the `book_usecase` module, and the generated project's lint, format, type-check, and test checks pass without manual edits.
43
+ 4. **Given** a valid project, **When** the developer runs `scaffold guc --name create_order`, **Then** the command creates `create_order_usecase.py` with the class `CreateOrderUseCase` and the test `test_create_order_usecase.py`.
44
+ 5. **Given** a valid project, **When** the developer runs `scaffold generate-use-case --name book` (the long form), **Then** the result is identical to running `scaffold guc --name book`.
45
+ 6. **Given** the command above has run, **Then** the success message reports the class name `BookUseCase` and the number of files created.
46
+
47
+ ---
48
+
49
+ ### User Story 2 - The suffix is never duplicated (Priority: P1)
50
+
51
+ A developer who already thinks of the module as a use case runs `scaffold guc --name book_usecase` or `scaffold guc --name book_use_case`. Today the class ends up as `BookUsecaseUseCase`. After this feature, the command recognizes the trailing suffix and produces exactly the same output as `scaffold guc --name book`.
52
+
53
+ **Why this priority**: The duplicated suffix is the reported bug. Producing the same result regardless of how the user writes the name removes it and makes the command predictable.
54
+
55
+ **Independent Test**: Run the command with `book`, `book_usecase`, and `book_use_case` in three fresh projects and verify that the three produce identical file names, class names, and file contents.
56
+
57
+ **Acceptance Scenarios**:
58
+
59
+ 1. **Given** a valid project, **When** the developer runs `scaffold guc --name book_usecase`, **Then** the command creates `book_usecase.py` with the class `BookUseCase` and the test `test_book_usecase.py`. No file or class contains the suffix twice.
60
+ 2. **Given** a valid project, **When** the developer runs `scaffold guc --name book_use_case`, **Then** the result is identical to scenario 1.
61
+ 3. **Given** a valid project, **When** the developer runs `scaffold guc --name create_order_usecase`, **Then** the command creates `create_order_usecase.py` with the class `CreateOrderUseCase`.
62
+ 4. **Given** a valid project, **When** the developer runs `scaffold guc --name usecase_registry`, **Then** only a trailing suffix is considered, so the command creates `usecase_registry_usecase.py` with the class `UsecaseRegistryUseCase`.
63
+
64
+ ---
65
+
66
+ ### User Story 3 - Preview and conflict detection use the normalized name (Priority: P2)
67
+
68
+ A developer previews generation with `--dry-run`, or runs the command again for a use case that already exists under a different spelling. Both the preview and the "already exists" check use the normalized module name, so the preview is accurate and existing work is never overwritten.
69
+
70
+ **Why this priority**: The constitution requires `--dry-run` on every command, and overwriting a hand-edited use case would destroy work. Both must agree with the new naming.
71
+
72
+ **Independent Test**: Run `scaffold guc --name book_usecase --dry-run` and verify the listed files, then generate `book` and try to generate `book_usecase` and verify the conflict.
73
+
74
+ **Acceptance Scenarios**:
75
+
76
+ 1. **Given** a valid project, **When** the developer runs `scaffold guc --name book --dry-run` or `scaffold guc --name book_usecase --dry-run`, **Then** the output lists `book_usecase.py` and `test_book_usecase.py`, and nothing is written to disk.
77
+ 2. **Given** a valid project, **When** the developer runs the same command without `--dry-run`, **Then** the files created match exactly the files listed by the dry-run.
78
+ 3. **Given** `domain/usecase/book_usecase.py` already exists, **When** the developer runs `scaffold guc --name book`, `--name book_usecase`, or `--name book_use_case`, **Then** the command exits with code 1, prints a clear message with a resolution hint, and writes no files.
79
+
80
+ ---
81
+
82
+ ### User Story 4 - Delete a use case by base name or suffixed name (Priority: P3)
83
+
84
+ A developer removes a use case with the delete-module command (`scaffold dm` / `scaffold delete-module`). The developer can refer to it either by its base name (`book`) or by its suffixed name (`book_usecase`), and the command finds `book_usecase.py` and its test. Use cases generated by earlier versions of the tool (`book.py`) can still be deleted by their original name.
85
+
86
+ **Why this priority**: Without this, deleting by the name used at generation time (`book`) would no longer find the use case. It is lower priority because deletion is used less often than generation.
87
+
88
+ **Independent Test**: Generate `book`, then run the delete-module command once with `--name book` and once with `--name book_usecase` in separate projects, and verify both remove the use case and its test. Repeat with a legacy `book.py` use case.
89
+
90
+ **Acceptance Scenarios**:
91
+
92
+ 1. **Given** a use case `book_usecase.py` with its test `test_book_usecase.py`, **When** the developer runs `scaffold dm --name book --confirm`, **Then** both files are removed.
93
+ 2. **Given** the same use case, **When** the developer runs `scaffold dm --name book_usecase --confirm`, **Then** both files are removed.
94
+ 3. **Given** the same use case, **When** the developer runs `scaffold dm --name book` with `--dry-run` or without `--confirm`, **Then** the preview lists `book_usecase.py` and `test_book_usecase.py`, and nothing is removed.
95
+ 4. **Given** a legacy use case `domain/usecase/book.py` with its test `test_book.py`, **When** the developer runs `scaffold dm --name book --confirm`, **Then** both files are removed, as they are today.
96
+ 5. **Given** both a legacy `book.py` and a new `book_usecase.py`, each with its test, **When** the developer runs `scaffold dm --name book` without `--confirm`, **Then** the preview lists all four files, and **When** the developer adds `--confirm`, **Then** all four files are removed.
97
+ 6. **Given** a model generated with `scaffold gm --name book` and a use case generated with `scaffold guc --name book`, **When** the developer runs `scaffold dm --name book` without `--confirm`, **Then** the preview lists the model package, its tests folder, `book_usecase.py`, and `test_book_usecase.py`, so the developer sees that both layers match before confirming. To remove only the use case's files, the developer deletes them by hand. A layer selector for delete-module is out of scope.
98
+
99
+ ---
100
+
101
+ ### Edge Cases
102
+
103
+ - **Name is only the suffix**: `scaffold guc --name usecase`, `--name use_case`, or a repetition such as `--name usecase_usecase` leaves no base name. The command exits with code 1, prints a clear message with a resolution hint (for example, suggesting a name such as `create_order`), and writes nothing.
104
+ - **Suffix not at the end**: the word `usecase` anywhere other than the end of the name (for example, `usecase_registry`) is kept as part of the base name.
105
+ - **Suffix glued to another word**: a name like `bookusecase` (no underscore) is not recognized as suffixed. It produces `bookusecase_usecase.py` with the class `BookusecaseUseCase`.
106
+ - **Repeated suffix**: all trailing suffixes are removed, in any mix of spellings. `paper_usecase_usecase` and `paper_use_case_usecase` both produce `paper_usecase.py` with the class `PaperUseCase`.
107
+ - **Invalid names**: names that are not valid snake_case module names, such as `Book`, `my-book`, or `1book`, exit with code 1 and the existing validation message. Nothing is written.
108
+ - **Outside a project**: running the command outside a Clean Architecture project root exits with code 1 and the existing message.
109
+ - **No arguments**: running `scaffold guc` with no arguments shows help and exits with code 0.
110
+ - **Legacy modules**: an existing legacy `domain/usecase/<name>.py` is ignored by generation. Running `scaffold guc --name <name>` creates `<name>_usecase.py` with no warning and no conflict, and the old file is left untouched.
111
+ - **Delete name matches other layers**: if the delete name also matches a model, adapter, entry point, or helper, the delete-module command lists every match, as it does today. Because a model and its use case usually share the base name (model `book`, use case `book_usecase.py`), `dm --name book` normally matches both. The preview shows every match before `--confirm` (US4 scenario 6).
112
+
113
+ ## Requirements *(mandatory)*
114
+
115
+ ### Functional Requirements
116
+
117
+ - **FR-001**: The generate-use-case command (`guc` / `generate-use-case`) MUST derive a base name from `--name` by repeatedly removing a trailing `_usecase` or `_use_case` suffix until none remains. If there is no such suffix, the base name is `--name` unchanged.
118
+ - **FR-002**: The command MUST create the use case module at `domain/usecase/<base>_usecase.py`.
119
+ - **FR-003**: The command MUST create the test stub at `src/tests/domain/usecase/test_<base>_usecase.py`.
120
+ - **FR-004**: The generated class MUST be named `<Base>UseCase`, where `<Base>` is the PascalCase form of the base name, and the `UseCase` suffix MUST appear exactly once.
121
+ - **FR-005**: The generated test stub MUST import `<Base>UseCase` from the `<base>_usecase` module.
122
+ - **FR-006**: The inputs `<base>`, `<base>_usecase`, and `<base>_use_case` MUST produce identical file paths, class names, and file contents.
123
+ - **FR-007**: Only a trailing suffix MUST be removed. The word `usecase` or `use_case` appearing elsewhere in the name MUST be preserved.
124
+ - **FR-008**: If removing the suffixes leaves an empty base name (for example `--name usecase`, `--name use_case`, or `--name usecase_usecase`), the command MUST exit with code 1, print a clear message with a resolution hint, and write no files.
125
+ - **FR-009**: The "already exists" check MUST use the normalized module path `domain/usecase/<base>_usecase.py`, so that any spelling of an existing use case is reported as a conflict (exit code 1, resolution hint, no files written).
126
+ - **FR-009a**: A legacy use case file `domain/usecase/<name>.py` MUST NOT be treated as a conflict and MUST NOT trigger a warning. Generation proceeds and leaves it untouched.
127
+ - **FR-009b**: The command MUST also exit with code 1, with a clear message and a resolution hint, and write no files, if `src/tests/domain/usecase/test_<base>_usecase.py` already exists.
128
+ - **FR-010**: `--dry-run` MUST list the normalized file paths and MUST write nothing.
129
+ - **FR-011**: The success message MUST report the normalized class name `<Base>UseCase` and the number of files created.
130
+ - **FR-012**: The command MUST keep its current snake_case name validation, project-root detection, and no-argument help behavior, including exit codes and messages.
131
+ - **FR-013**: The delete-module command (`dm` / `delete-module`) MUST find a use case generated with the new convention when given either the base name or the suffixed name (`_usecase` or `_use_case`), and remove both the module and its test.
132
+ - **FR-014**: The delete-module command MUST continue to find and remove legacy use cases (`domain/usecase/<name>.py` and `test_<name>.py`) by their original name.
133
+ - **FR-014a**: When both a legacy `domain/usecase/<base>.py` and a new `domain/usecase/<base>_usecase.py` exist, the delete-module command MUST list both modules and their tests in the preview and remove all of them on `--confirm`.
134
+ - **FR-015**: All generated files MUST keep coming from versioned templates, and every changed template MUST have rendering tests (Constitution Principle II).
135
+ - **FR-016**: The command's help text and the project README MUST show the `<base>_usecase.py` convention in their examples.
136
+
137
+ ### Key Entities
138
+
139
+ - **Use Case Base Name**: The `--name` value with every trailing `_usecase` or `_use_case` suffix removed. All file and class names derive from it.
140
+ - **Use Case Module**: The file `domain/usecase/<base>_usecase.py` that contains the use case class.
141
+ - **Use Case Class**: The class `<Base>UseCase` defined in the use case module.
142
+ - **Use Case Test Stub**: The file `src/tests/domain/usecase/test_<base>_usecase.py` that imports and exercises the use case class.
143
+
144
+ ## Success Criteria *(mandatory)*
145
+
146
+ ### Measurable Outcomes
147
+
148
+ - **SC-001**: 100% of use cases generated after this feature have a module file name ending in `_usecase.py` and a class name ending in exactly one `UseCase`.
149
+ - **SC-002**: For every base name tested, the three spellings (`<base>`, `<base>_usecase`, `<base>_use_case`) produce byte-identical output.
150
+ - **SC-003**: 0 generated class names contain the suffix twice, whatever the input (for example, `--name book_usecase` and `--name book_usecase_usecase` never produce `BookUsecaseUseCase`).
151
+ - **SC-004**: In 100% of freshly scaffolded projects, the generated project's lint, format, type-check, and test checks pass immediately after generating a use case, with no manual edits.
152
+ - **SC-005**: The files listed by `--dry-run` match the files actually created in 100% of runs.
153
+ - **SC-006**: Re-running the command for an existing use case under any of the three spellings never modifies an existing file.
154
+ - **SC-007**: The CLI's own test suite covers generation, suffix stripping for both spellings and repeated suffixes, the suffix-only error, dry-run, conflict detection (source and test file), legacy files being ignored by generation, and deletion by base name, suffixed name, legacy name, and with both layouts present, and stays at or above the 80% coverage gate.
155
+
156
+ ## Assumptions
157
+
158
+ - `_usecase` is the canonical module suffix. `_use_case` is accepted as input only and is always normalized to `_usecase` in file names.
159
+ - The class name suffix stays `UseCase` (capital U and C) as it is today. Only the module and test file names change.
160
+ - Suffix detection is case-sensitive and requires the underscore separator. This matches the existing snake_case-only validation, which already rejects uppercase input.
161
+ - The content of the generated use case and test templates is unchanged apart from the module name used in the test import.
162
+ - The `--name` help text keeps asking for a snake_case name. It does not need to tell users to include or omit the suffix, because both forms work.
163
+ - All work for this feature MUST happen on the branch `feature/usecase-naming-standardization`, created from `main`, following Constitution Principle VII.
164
+
165
+ ### Out of Scope
166
+
167
+ - Renaming or migrating use case files already generated in existing projects. Legacy `<name>.py` use cases are left as-is.
168
+ - Changing the naming of other generators (models, gateways, driven adapters, entry points, helpers).
169
+ - Automatically wiring the generated use case into the application's dependency container.
170
+ - A layer selector (for example `--layer`) for the delete-module command to target only the model or only the use case when both share a name.