roadmap-cli 0.1.1__py3-none-any.whl

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 (521) hide show
  1. roadmap/__init__.py +27 -0
  2. roadmap/adapters/__init__.py +1 -0
  3. roadmap/adapters/base_paginated_adapter.py +117 -0
  4. roadmap/adapters/cli/__init__.py +249 -0
  5. roadmap/adapters/cli/analysis/__init__.py +5 -0
  6. roadmap/adapters/cli/analysis/commands.py +370 -0
  7. roadmap/adapters/cli/analysis/presenter.py +125 -0
  8. roadmap/adapters/cli/archive_operations.py +86 -0
  9. roadmap/adapters/cli/cli_command_helpers.py +109 -0
  10. roadmap/adapters/cli/cli_confirmations.py +74 -0
  11. roadmap/adapters/cli/cli_error_handlers.py +146 -0
  12. roadmap/adapters/cli/cli_validators.py +39 -0
  13. roadmap/adapters/cli/commands/sync_status.py +308 -0
  14. roadmap/adapters/cli/comment/__init__.py +5 -0
  15. roadmap/adapters/cli/comment/commands.py +106 -0
  16. roadmap/adapters/cli/config/__init__.py +5 -0
  17. roadmap/adapters/cli/config/commands.py +198 -0
  18. roadmap/adapters/cli/console_exports.py +10 -0
  19. roadmap/adapters/cli/core.py +26 -0
  20. roadmap/adapters/cli/crud/__init__.py +47 -0
  21. roadmap/adapters/cli/crud/base_archive.py +208 -0
  22. roadmap/adapters/cli/crud/base_create.py +154 -0
  23. roadmap/adapters/cli/crud/base_delete.py +155 -0
  24. roadmap/adapters/cli/crud/base_restore.py +283 -0
  25. roadmap/adapters/cli/crud/base_update.py +193 -0
  26. roadmap/adapters/cli/crud/crud_helpers.py +206 -0
  27. roadmap/adapters/cli/crud/crud_utils.py +152 -0
  28. roadmap/adapters/cli/crud/entity_builders.py +374 -0
  29. roadmap/adapters/cli/data/__init__.py +8 -0
  30. roadmap/adapters/cli/data/commands.py +149 -0
  31. roadmap/adapters/cli/decorators.py +208 -0
  32. roadmap/adapters/cli/dtos/__init__.py +155 -0
  33. roadmap/adapters/cli/exception_handler.py +105 -0
  34. roadmap/adapters/cli/git/__init__.py +8 -0
  35. roadmap/adapters/cli/git/commands.py +475 -0
  36. roadmap/adapters/cli/git/handlers/__init__.py +1 -0
  37. roadmap/adapters/cli/git/handlers/git_authentication_handler.py +124 -0
  38. roadmap/adapters/cli/git/handlers/git_branch_handler.py +238 -0
  39. roadmap/adapters/cli/git/handlers/git_connectivity_handler.py +122 -0
  40. roadmap/adapters/cli/git/handlers/git_hooks_handler.py +105 -0
  41. roadmap/adapters/cli/git/hooks_config.py +327 -0
  42. roadmap/adapters/cli/git/status_display.py +158 -0
  43. roadmap/adapters/cli/health/__init__.py +8 -0
  44. roadmap/adapters/cli/health/db_integrity.py +204 -0
  45. roadmap/adapters/cli/health/enhancer.py +227 -0
  46. roadmap/adapters/cli/health/fixer.py +295 -0
  47. roadmap/adapters/cli/health/fixers/__init__.py +10 -0
  48. roadmap/adapters/cli/health/fixers/corrupted_comments_fixer.py +231 -0
  49. roadmap/adapters/cli/health/fixers/data_integrity_fixer.py +137 -0
  50. roadmap/adapters/cli/health/fixers/duplicate_issues_fixer.py +138 -0
  51. roadmap/adapters/cli/health/fixers/folder_structure_fixer.py +114 -0
  52. roadmap/adapters/cli/health/fixers/label_normalization_fixer.py +162 -0
  53. roadmap/adapters/cli/health/fixers/milestone_name_normalization_fixer.py +181 -0
  54. roadmap/adapters/cli/health/fixers/milestone_naming_compliance_fixer.py +244 -0
  55. roadmap/adapters/cli/health/fixers/milestone_parse_error_fixer.py +162 -0
  56. roadmap/adapters/cli/health/fixers/milestone_validation_fixer.py +211 -0
  57. roadmap/adapters/cli/health/fixers/old_backups_fixer.py +135 -0
  58. roadmap/adapters/cli/health/fixers/orphaned_issues_fixer.py +252 -0
  59. roadmap/adapters/cli/health/formatter.py +250 -0
  60. roadmap/adapters/cli/health/formatters.py +427 -0
  61. roadmap/adapters/cli/health/scan.py +293 -0
  62. roadmap/adapters/cli/init/__init__.py +5 -0
  63. roadmap/adapters/cli/init/commands.py +587 -0
  64. roadmap/adapters/cli/init.py +9 -0
  65. roadmap/adapters/cli/issues/__init__.py +70 -0
  66. roadmap/adapters/cli/issues/archive.py +137 -0
  67. roadmap/adapters/cli/issues/archive_class.py +253 -0
  68. roadmap/adapters/cli/issues/block.py +39 -0
  69. roadmap/adapters/cli/issues/close.py +216 -0
  70. roadmap/adapters/cli/issues/comment.py +178 -0
  71. roadmap/adapters/cli/issues/create.py +162 -0
  72. roadmap/adapters/cli/issues/delete.py +31 -0
  73. roadmap/adapters/cli/issues/deps.py +161 -0
  74. roadmap/adapters/cli/issues/issue_status_helpers.py +111 -0
  75. roadmap/adapters/cli/issues/link.py +308 -0
  76. roadmap/adapters/cli/issues/list.py +402 -0
  77. roadmap/adapters/cli/issues/lookup.py +96 -0
  78. roadmap/adapters/cli/issues/progress.py +102 -0
  79. roadmap/adapters/cli/issues/restore.py +96 -0
  80. roadmap/adapters/cli/issues/restore_class.py +57 -0
  81. roadmap/adapters/cli/issues/start.py +165 -0
  82. roadmap/adapters/cli/issues/sync_status.py +374 -0
  83. roadmap/adapters/cli/issues/unblock.py +43 -0
  84. roadmap/adapters/cli/issues/unlink.py +104 -0
  85. roadmap/adapters/cli/issues/update.py +120 -0
  86. roadmap/adapters/cli/issues/view.py +36 -0
  87. roadmap/adapters/cli/layout.py +220 -0
  88. roadmap/adapters/cli/mappers.py +200 -0
  89. roadmap/adapters/cli/milestones/__init__.py +52 -0
  90. roadmap/adapters/cli/milestones/archive.py +125 -0
  91. roadmap/adapters/cli/milestones/archive_class.py +236 -0
  92. roadmap/adapters/cli/milestones/assign.py +62 -0
  93. roadmap/adapters/cli/milestones/close.py +177 -0
  94. roadmap/adapters/cli/milestones/create.py +131 -0
  95. roadmap/adapters/cli/milestones/delete.py +27 -0
  96. roadmap/adapters/cli/milestones/kanban.py +123 -0
  97. roadmap/adapters/cli/milestones/list.py +87 -0
  98. roadmap/adapters/cli/milestones/recalculate.py +79 -0
  99. roadmap/adapters/cli/milestones/restore.py +87 -0
  100. roadmap/adapters/cli/milestones/restore_class.py +99 -0
  101. roadmap/adapters/cli/milestones/update.py +61 -0
  102. roadmap/adapters/cli/milestones/view.py +142 -0
  103. roadmap/adapters/cli/output_manager.py +319 -0
  104. roadmap/adapters/cli/presentation/base_presenter.py +121 -0
  105. roadmap/adapters/cli/presentation/cleanup_presenter.py +235 -0
  106. roadmap/adapters/cli/presentation/core_initialization_presenter.py +277 -0
  107. roadmap/adapters/cli/presentation/crud_presenter.py +134 -0
  108. roadmap/adapters/cli/presentation/daily_summary_presenter.py +266 -0
  109. roadmap/adapters/cli/presentation/issue_presenter.py +258 -0
  110. roadmap/adapters/cli/presentation/milestone_list_presenter.py +135 -0
  111. roadmap/adapters/cli/presentation/milestone_presenter.py +297 -0
  112. roadmap/adapters/cli/presentation/project_presenter.py +233 -0
  113. roadmap/adapters/cli/presentation/project_status_presenter.py +186 -0
  114. roadmap/adapters/cli/presentation/table_builders.py +95 -0
  115. roadmap/adapters/cli/projects/__init__.py +42 -0
  116. roadmap/adapters/cli/projects/archive.py +127 -0
  117. roadmap/adapters/cli/projects/archive_class.py +96 -0
  118. roadmap/adapters/cli/projects/close.py +94 -0
  119. roadmap/adapters/cli/projects/create.py +50 -0
  120. roadmap/adapters/cli/projects/delete.py +27 -0
  121. roadmap/adapters/cli/projects/list.py +227 -0
  122. roadmap/adapters/cli/projects/restore.py +87 -0
  123. roadmap/adapters/cli/projects/restore_class.py +56 -0
  124. roadmap/adapters/cli/projects/update.py +57 -0
  125. roadmap/adapters/cli/projects/view.py +157 -0
  126. roadmap/adapters/cli/services/__init__.py +1 -0
  127. roadmap/adapters/cli/services/daily_summary_service.py +313 -0
  128. roadmap/adapters/cli/services/export_manager.py +268 -0
  129. roadmap/adapters/cli/services/milestone_list_service.py +266 -0
  130. roadmap/adapters/cli/services/project_initialization_service.py +29 -0
  131. roadmap/adapters/cli/services/project_status_service.py +462 -0
  132. roadmap/adapters/cli/services/sync_service.py +62 -0
  133. roadmap/adapters/cli/status.py +408 -0
  134. roadmap/adapters/cli/styling.py +21 -0
  135. roadmap/adapters/cli/sync.py +1117 -0
  136. roadmap/adapters/cli/sync_context.py +432 -0
  137. roadmap/adapters/cli/sync_handlers/__init__.py +77 -0
  138. roadmap/adapters/cli/sync_handlers/apply_ops.py +522 -0
  139. roadmap/adapters/cli/sync_handlers/baseline_ops.py +366 -0
  140. roadmap/adapters/cli/sync_handlers/conflict_ops.py +161 -0
  141. roadmap/adapters/cli/sync_handlers/dry_run_display.py +237 -0
  142. roadmap/adapters/cli/sync_handlers/interactive_resolver.py +396 -0
  143. roadmap/adapters/cli/sync_handlers/progress_tracker.py +128 -0
  144. roadmap/adapters/cli/sync_metrics_command.py +190 -0
  145. roadmap/adapters/cli/sync_presenter.py +58 -0
  146. roadmap/adapters/cli/sync_validation.py +295 -0
  147. roadmap/adapters/cli/today.py +52 -0
  148. roadmap/adapters/cli/utils/click_options.py +38 -0
  149. roadmap/adapters/git/__init__.py +1 -0
  150. roadmap/adapters/git/git.py +208 -0
  151. roadmap/adapters/git/git_branch_manager.py +400 -0
  152. roadmap/adapters/git/git_command_executor.py +56 -0
  153. roadmap/adapters/git/git_commit_analyzer.py +334 -0
  154. roadmap/adapters/git/git_hooks.py +22 -0
  155. roadmap/adapters/git/git_hooks_manager.py +455 -0
  156. roadmap/adapters/git/git_repository_info.py +65 -0
  157. roadmap/adapters/git/hook_installer.py +106 -0
  158. roadmap/adapters/git/hook_registry.py +97 -0
  159. roadmap/adapters/git/hook_script_generator.py +58 -0
  160. roadmap/adapters/git/sync_monitor.py +409 -0
  161. roadmap/adapters/git/workflow_automation.py +286 -0
  162. roadmap/adapters/github/__init__.py +1 -0
  163. roadmap/adapters/github/github.py +360 -0
  164. roadmap/adapters/github/handlers/__init__.py +17 -0
  165. roadmap/adapters/github/handlers/base.py +337 -0
  166. roadmap/adapters/github/handlers/collaborators.py +165 -0
  167. roadmap/adapters/github/handlers/comments.py +118 -0
  168. roadmap/adapters/github/handlers/issues.py +150 -0
  169. roadmap/adapters/github/handlers/labels.py +164 -0
  170. roadmap/adapters/github/handlers/milestones.py +104 -0
  171. roadmap/adapters/persistence/__init__.py +35 -0
  172. roadmap/adapters/persistence/conflict_resolver.py +190 -0
  173. roadmap/adapters/persistence/database_manager.py +492 -0
  174. roadmap/adapters/persistence/entity_sync_coordinators.py +672 -0
  175. roadmap/adapters/persistence/file_locking.py +348 -0
  176. roadmap/adapters/persistence/file_parser.py +92 -0
  177. roadmap/adapters/persistence/file_synchronizer.py +107 -0
  178. roadmap/adapters/persistence/focused_managers.py +140 -0
  179. roadmap/adapters/persistence/git_history.py +330 -0
  180. roadmap/adapters/persistence/parser/__init__.py +20 -0
  181. roadmap/adapters/persistence/parser/frontmatter.py +152 -0
  182. roadmap/adapters/persistence/parser/issue.py +245 -0
  183. roadmap/adapters/persistence/parser/milestone.py +146 -0
  184. roadmap/adapters/persistence/parser/project.py +106 -0
  185. roadmap/adapters/persistence/persistence.py +288 -0
  186. roadmap/adapters/persistence/repositories/__init__.py +15 -0
  187. roadmap/adapters/persistence/repositories/issue_repository.py +223 -0
  188. roadmap/adapters/persistence/repositories/milestone_repository.py +140 -0
  189. roadmap/adapters/persistence/repositories/project_repository.py +168 -0
  190. roadmap/adapters/persistence/repositories/remote_link_repository.py +355 -0
  191. roadmap/adapters/persistence/repositories/sync_state_repository.py +66 -0
  192. roadmap/adapters/persistence/storage/__init__.py +36 -0
  193. roadmap/adapters/persistence/storage/conflicts.py +101 -0
  194. roadmap/adapters/persistence/storage/connection_manager.py +79 -0
  195. roadmap/adapters/persistence/storage/issue_storage.py +89 -0
  196. roadmap/adapters/persistence/storage/milestone_storage.py +80 -0
  197. roadmap/adapters/persistence/storage/project_storage.py +102 -0
  198. roadmap/adapters/persistence/storage/queries.py +227 -0
  199. roadmap/adapters/persistence/storage/state_manager.py +652 -0
  200. roadmap/adapters/persistence/storage/sync_state_storage.py +207 -0
  201. roadmap/adapters/persistence/sync_metrics_repository.py +342 -0
  202. roadmap/adapters/persistence/sync_orchestrator.py +293 -0
  203. roadmap/adapters/persistence/sync_state_tracker.py +86 -0
  204. roadmap/adapters/persistence/yaml_repositories.py +711 -0
  205. roadmap/adapters/sync/__init__.py +21 -0
  206. roadmap/adapters/sync/backend_factory.py +108 -0
  207. roadmap/adapters/sync/backends/__init__.py +15 -0
  208. roadmap/adapters/sync/backends/converters.py +209 -0
  209. roadmap/adapters/sync/backends/github_backend_helpers.py +380 -0
  210. roadmap/adapters/sync/backends/github_client.py +99 -0
  211. roadmap/adapters/sync/backends/github_sync_backend.py +792 -0
  212. roadmap/adapters/sync/backends/github_sync_ops.py +908 -0
  213. roadmap/adapters/sync/backends/services/__init__.py +1 -0
  214. roadmap/adapters/sync/backends/services/github_authentication_service.py +105 -0
  215. roadmap/adapters/sync/backends/services/github_issue_delete_service.py +423 -0
  216. roadmap/adapters/sync/backends/services/github_issue_dependency_service.py +63 -0
  217. roadmap/adapters/sync/backends/services/github_issue_fetch_service.py +158 -0
  218. roadmap/adapters/sync/backends/services/github_label_sync_service.py +126 -0
  219. roadmap/adapters/sync/backends/services/github_local_issue_sync_service.py +229 -0
  220. roadmap/adapters/sync/backends/services/github_milestone_fetch_service.py +204 -0
  221. roadmap/adapters/sync/backends/vanilla_git_sync_backend.py +198 -0
  222. roadmap/adapters/sync/services/__init__.py +11 -0
  223. roadmap/adapters/sync/services/baseline_state_handler.py +83 -0
  224. roadmap/adapters/sync/services/conflict_converter.py +85 -0
  225. roadmap/adapters/sync/services/issue_persistence_service.py +263 -0
  226. roadmap/adapters/sync/services/issue_state_service.py +243 -0
  227. roadmap/adapters/sync/services/local_change_filter.py +129 -0
  228. roadmap/adapters/sync/services/pull_result_processor.py +71 -0
  229. roadmap/adapters/sync/services/remote_issue_creation_service.py +112 -0
  230. roadmap/adapters/sync/services/sync_analysis_service.py +250 -0
  231. roadmap/adapters/sync/services/sync_authentication_service.py +57 -0
  232. roadmap/adapters/sync/services/sync_data_fetch_service.py +212 -0
  233. roadmap/adapters/sync/services/sync_linking_service.py +329 -0
  234. roadmap/adapters/sync/services/sync_report_service.py +62 -0
  235. roadmap/adapters/sync/services/sync_state_update_service.py +51 -0
  236. roadmap/adapters/sync/sync_cache_orchestrator.py +454 -0
  237. roadmap/adapters/sync/sync_merge_engine.py +416 -0
  238. roadmap/adapters/sync/sync_merge_orchestrator.py +1313 -0
  239. roadmap/adapters/sync/sync_retrieval_orchestrator.py +810 -0
  240. roadmap/application/services/__init__.py +1 -0
  241. roadmap/application/services/deduplicate_service.py +517 -0
  242. roadmap/application/use_cases/__init__.py +1 -0
  243. roadmap/common/__init__.py +308 -0
  244. roadmap/common/cache.py +209 -0
  245. roadmap/common/cli_errors.py +147 -0
  246. roadmap/common/configuration/__init__.py +33 -0
  247. roadmap/common/configuration/config_loader.py +264 -0
  248. roadmap/common/configuration/config_manager.py +164 -0
  249. roadmap/common/configuration/config_schema.py +145 -0
  250. roadmap/common/configuration/github/__init__.py +9 -0
  251. roadmap/common/configuration/github/config_manager.py +154 -0
  252. roadmap/common/configuration/github/token_resolver.py +84 -0
  253. roadmap/common/console.py +184 -0
  254. roadmap/common/constants.py +134 -0
  255. roadmap/common/datetime_parser.py +319 -0
  256. roadmap/common/error_formatter.py +84 -0
  257. roadmap/common/errors/__init__.py +143 -0
  258. roadmap/common/errors/error_base.py +73 -0
  259. roadmap/common/errors/error_file.py +82 -0
  260. roadmap/common/errors/error_git.py +67 -0
  261. roadmap/common/errors/error_handler.py +166 -0
  262. roadmap/common/errors/error_network.py +90 -0
  263. roadmap/common/errors/error_security.py +78 -0
  264. roadmap/common/errors/error_standards.py +561 -0
  265. roadmap/common/errors/error_validation.py +111 -0
  266. roadmap/common/errors/exceptions.py +432 -0
  267. roadmap/common/formatters/__init__.py +29 -0
  268. roadmap/common/formatters/base_table_formatter.py +96 -0
  269. roadmap/common/formatters/export/__init__.py +7 -0
  270. roadmap/common/formatters/export/issue_exporter.py +97 -0
  271. roadmap/common/formatters/helpers.py +28 -0
  272. roadmap/common/formatters/kanban/__init__.py +9 -0
  273. roadmap/common/formatters/kanban/layout.py +48 -0
  274. roadmap/common/formatters/kanban/organizer.py +81 -0
  275. roadmap/common/formatters/output/__init__.py +15 -0
  276. roadmap/common/formatters/tables/__init__.py +11 -0
  277. roadmap/common/formatters/tables/column_factory.py +312 -0
  278. roadmap/common/formatters/tables/issue_table.py +276 -0
  279. roadmap/common/formatters/tables/milestone_table.py +247 -0
  280. roadmap/common/formatters/tables/project_table.py +195 -0
  281. roadmap/common/formatters/text/__init__.py +57 -0
  282. roadmap/common/formatters/text/basic.py +217 -0
  283. roadmap/common/formatters/text/display.py +42 -0
  284. roadmap/common/formatters/text/duration.py +36 -0
  285. roadmap/common/formatters/text/operations.py +325 -0
  286. roadmap/common/formatters/text/status_badges.py +57 -0
  287. roadmap/common/initialization/github/__init__.py +11 -0
  288. roadmap/common/initialization/github/setup_service.py +238 -0
  289. roadmap/common/initialization/github/setup_validator.py +78 -0
  290. roadmap/common/logging/__init__.py +113 -0
  291. roadmap/common/logging/audit_logging.py +5 -0
  292. roadmap/common/logging/correlation.py +45 -0
  293. roadmap/common/logging/decorators.py +267 -0
  294. roadmap/common/logging/error_logging.py +217 -0
  295. roadmap/common/logging/formatters.py +124 -0
  296. roadmap/common/logging/loggers.py +68 -0
  297. roadmap/common/logging/performance_tracking.py +267 -0
  298. roadmap/common/logging/utils.py +335 -0
  299. roadmap/common/models/__init__.py +44 -0
  300. roadmap/common/models/cli_models.py +118 -0
  301. roadmap/common/models/config_models.py +199 -0
  302. roadmap/common/models/output_models.py +381 -0
  303. roadmap/common/observability/__init__.py +28 -0
  304. roadmap/common/observability/instrumentation.py +103 -0
  305. roadmap/common/observability/observability.py +76 -0
  306. roadmap/common/observability/otel_init.py +109 -0
  307. roadmap/common/output_formatter.py +393 -0
  308. roadmap/common/progress.py +379 -0
  309. roadmap/common/result.py +396 -0
  310. roadmap/common/security/__init__.py +48 -0
  311. roadmap/common/security/exceptions.py +13 -0
  312. roadmap/common/security/export_cleanup.py +79 -0
  313. roadmap/common/security/file_operations.py +104 -0
  314. roadmap/common/security/filename_sanitization.py +54 -0
  315. roadmap/common/security/logging.py +27 -0
  316. roadmap/common/security/path_validation.py +137 -0
  317. roadmap/common/security/temp_files.py +41 -0
  318. roadmap/common/services/__init__.py +65 -0
  319. roadmap/common/services/decorators.py +183 -0
  320. roadmap/common/services/logging_utils.py +208 -0
  321. roadmap/common/services/metrics.py +161 -0
  322. roadmap/common/services/performance.py +219 -0
  323. roadmap/common/services/profiling.py +288 -0
  324. roadmap/common/services/retry.py +288 -0
  325. roadmap/common/status_style_manager.py +114 -0
  326. roadmap/common/union_find.py +88 -0
  327. roadmap/common/update_constants.py +13 -0
  328. roadmap/common/utils/__init__.py +65 -0
  329. roadmap/common/utils/cli_helpers.py +381 -0
  330. roadmap/common/utils/file_utils.py +440 -0
  331. roadmap/common/utils/path_utils.py +38 -0
  332. roadmap/common/utils/status_utils.py +130 -0
  333. roadmap/common/utils/timezone_utils.py +480 -0
  334. roadmap/common/validation/__init__.py +37 -0
  335. roadmap/common/validation/field_validator.py +104 -0
  336. roadmap/common/validation/result.py +37 -0
  337. roadmap/common/validation/roadmap_validator.py +310 -0
  338. roadmap/common/validation/schema_validator.py +36 -0
  339. roadmap/common/validation/validators.py +50 -0
  340. roadmap/core/__init__.py +1 -0
  341. roadmap/core/domain/__init__.py +30 -0
  342. roadmap/core/domain/comment.py +24 -0
  343. roadmap/core/domain/health.py +15 -0
  344. roadmap/core/domain/issue.py +274 -0
  345. roadmap/core/domain/milestone.py +173 -0
  346. roadmap/core/domain/ports/__init__.py +1 -0
  347. roadmap/core/domain/ports/baseline_repository.py +24 -0
  348. roadmap/core/domain/ports/issue_repository.py +34 -0
  349. roadmap/core/domain/ports/remote_backend_port.py +31 -0
  350. roadmap/core/domain/project.py +130 -0
  351. roadmap/core/interfaces/__init__.py +109 -0
  352. roadmap/core/interfaces/assignee_validator.py +40 -0
  353. roadmap/core/interfaces/backend_factory.py +175 -0
  354. roadmap/core/interfaces/github.py +102 -0
  355. roadmap/core/interfaces/parsers.py +140 -0
  356. roadmap/core/interfaces/persistence.py +45 -0
  357. roadmap/core/interfaces/repositories.py +174 -0
  358. roadmap/core/interfaces/state_managers.py +111 -0
  359. roadmap/core/interfaces/state_storage.py +64 -0
  360. roadmap/core/interfaces/sync_backend.py +275 -0
  361. roadmap/core/interfaces/sync_services.py +119 -0
  362. roadmap/core/interfaces/sync_validators.py +180 -0
  363. roadmap/core/models/__init__.py +31 -0
  364. roadmap/core/models/sync_models.py +162 -0
  365. roadmap/core/models.py +115 -0
  366. roadmap/core/observability/__init__.py +17 -0
  367. roadmap/core/observability/sync_metrics.py +699 -0
  368. roadmap/core/repositories.py +200 -0
  369. roadmap/core/services/__init__.py +313 -0
  370. roadmap/core/services/baseline/__init__.py +1 -0
  371. roadmap/core/services/baseline/baseline_builder_progress.py +274 -0
  372. roadmap/core/services/baseline/baseline_retriever.py +63 -0
  373. roadmap/core/services/baseline/baseline_selector.py +248 -0
  374. roadmap/core/services/baseline/baseline_state_retriever.py +284 -0
  375. roadmap/core/services/baseline/optimized_baseline_builder.py +425 -0
  376. roadmap/core/services/comment/__init__.py +1 -0
  377. roadmap/core/services/comment/comment_service.py +277 -0
  378. roadmap/core/services/git/__init__.py +1 -0
  379. roadmap/core/services/git/git_hook_auto_sync_service.py +403 -0
  380. roadmap/core/services/github/__init__.py +1 -0
  381. roadmap/core/services/github/github_change_detector.py +162 -0
  382. roadmap/core/services/github/github_config_validator.py +148 -0
  383. roadmap/core/services/github/github_conflict_detector.py +179 -0
  384. roadmap/core/services/github/github_entity_classifier.py +51 -0
  385. roadmap/core/services/github/github_integration_service.py +439 -0
  386. roadmap/core/services/github/github_issue_client.py +346 -0
  387. roadmap/core/services/health/__init__.py +1 -0
  388. roadmap/core/services/health/backup_cleanup_service.py +202 -0
  389. roadmap/core/services/health/data_integrity_validator_service.py +90 -0
  390. roadmap/core/services/health/entity_health_scanner.py +460 -0
  391. roadmap/core/services/health/file_repair_service.py +193 -0
  392. roadmap/core/services/health/health_check_service.py +166 -0
  393. roadmap/core/services/health/health_models.py +80 -0
  394. roadmap/core/services/health/infrastructure_validator_service.py +328 -0
  395. roadmap/core/services/health/issue_health_scanner.py +263 -0
  396. roadmap/core/services/helpers/__init__.py +18 -0
  397. roadmap/core/services/helpers/status_change_helpers.py +88 -0
  398. roadmap/core/services/initialization/__init__.py +19 -0
  399. roadmap/core/services/initialization/utils.py +104 -0
  400. roadmap/core/services/initialization/validator.py +78 -0
  401. roadmap/core/services/initialization/workflow.py +182 -0
  402. roadmap/core/services/initialization_service.py +111 -0
  403. roadmap/core/services/issue/__init__.py +1 -0
  404. roadmap/core/services/issue/assignee_validation_service.py +312 -0
  405. roadmap/core/services/issue/issue_creation_service.py +309 -0
  406. roadmap/core/services/issue/issue_filter_service.py +302 -0
  407. roadmap/core/services/issue/issue_matching_service.py +127 -0
  408. roadmap/core/services/issue/issue_service.py +765 -0
  409. roadmap/core/services/issue/issue_update_service.py +144 -0
  410. roadmap/core/services/issue/start_issue_service.py +174 -0
  411. roadmap/core/services/issue_helpers/__init__.py +18 -0
  412. roadmap/core/services/issue_helpers/issue_filters.py +296 -0
  413. roadmap/core/services/milestone_service.py +438 -0
  414. roadmap/core/services/project/__init__.py +1 -0
  415. roadmap/core/services/project/project_service.py +434 -0
  416. roadmap/core/services/project/project_status_service.py +125 -0
  417. roadmap/core/services/project_init/__init__.py +22 -0
  418. roadmap/core/services/project_init/context_detection.py +146 -0
  419. roadmap/core/services/project_init/creation.py +76 -0
  420. roadmap/core/services/project_init/detection.py +51 -0
  421. roadmap/core/services/project_init/template.py +228 -0
  422. roadmap/core/services/status_change_service.py +88 -0
  423. roadmap/core/services/sync/__init__.py +1 -0
  424. roadmap/core/services/sync/batch_processor.py +290 -0
  425. roadmap/core/services/sync/conflict_resolver.py +154 -0
  426. roadmap/core/services/sync/dependency_resolver.py +367 -0
  427. roadmap/core/services/sync/duplicate_detector.py +771 -0
  428. roadmap/core/services/sync/duplicate_resolver.py +315 -0
  429. roadmap/core/services/sync/error_classification.py +470 -0
  430. roadmap/core/services/sync/performance.py +263 -0
  431. roadmap/core/services/sync/sync_change_computer.py +211 -0
  432. roadmap/core/services/sync/sync_checkpoint.py +348 -0
  433. roadmap/core/services/sync/sync_conflict_detector.py +147 -0
  434. roadmap/core/services/sync/sync_conflict_resolver.py +448 -0
  435. roadmap/core/services/sync/sync_errors.py +383 -0
  436. roadmap/core/services/sync/sync_key_normalizer.py +222 -0
  437. roadmap/core/services/sync/sync_metadata_service.py +361 -0
  438. roadmap/core/services/sync/sync_plan.py +171 -0
  439. roadmap/core/services/sync/sync_plan_executor.py +447 -0
  440. roadmap/core/services/sync/sync_report.py +296 -0
  441. roadmap/core/services/sync/sync_state.py +173 -0
  442. roadmap/core/services/sync/sync_state_comparator.py +690 -0
  443. roadmap/core/services/sync/sync_state_manager.py +431 -0
  444. roadmap/core/services/sync/sync_state_normalizer.py +98 -0
  445. roadmap/core/services/sync/sync_three_way.py +78 -0
  446. roadmap/core/services/sync/three_way_merger.py +178 -0
  447. roadmap/core/services/utils/__init__.py +1 -0
  448. roadmap/core/services/utils/configuration_service.py +113 -0
  449. roadmap/core/services/utils/critical_path_calculator.py +418 -0
  450. roadmap/core/services/utils/dependency_analyzer.py +360 -0
  451. roadmap/core/services/utils/field_conflict_detector.py +126 -0
  452. roadmap/core/services/utils/remote_fetcher.py +202 -0
  453. roadmap/core/services/utils/remote_state_normalizer.py +110 -0
  454. roadmap/core/services/utils/retry_policy.py +51 -0
  455. roadmap/core/services/validator_base.py +130 -0
  456. roadmap/core/services/validators/__init__.py +28 -0
  457. roadmap/core/services/validators/_utils.py +20 -0
  458. roadmap/core/services/validators/archivable_issues_validator.py +71 -0
  459. roadmap/core/services/validators/archivable_milestones_validator.py +69 -0
  460. roadmap/core/services/validators/backup_validator.py +89 -0
  461. roadmap/core/services/validators/data_integrity_validator.py +84 -0
  462. roadmap/core/services/validators/duplicate_issues_validator.py +75 -0
  463. roadmap/core/services/validators/duplicate_milestones_validator.py +141 -0
  464. roadmap/core/services/validators/folder_structure_validator.py +165 -0
  465. roadmap/core/services/validators/health_status_utils.py +28 -0
  466. roadmap/core/services/validators/milestone_naming_validator.py +146 -0
  467. roadmap/core/services/validators/missing_headlines_validator.py +97 -0
  468. roadmap/core/services/validators/orphaned_issues_validator.py +142 -0
  469. roadmap/core/services/validators/orphaned_milestones_validator.py +85 -0
  470. roadmap/core/utils/git_remote_parser.py +83 -0
  471. roadmap/core/utils/github_urls.py +66 -0
  472. roadmap/domain/validation.py +30 -0
  473. roadmap/infrastructure/__init__.py +55 -0
  474. roadmap/infrastructure/coordination/__init__.py +8 -0
  475. roadmap/infrastructure/coordination/coordinator_params.py +82 -0
  476. roadmap/infrastructure/coordination/core.py +446 -0
  477. roadmap/infrastructure/coordination/git_coordinator.py +160 -0
  478. roadmap/infrastructure/coordination/initialization.py +348 -0
  479. roadmap/infrastructure/coordination/issue_coordinator.py +154 -0
  480. roadmap/infrastructure/coordination/issue_operations.py +456 -0
  481. roadmap/infrastructure/coordination/milestone_coordinator.py +135 -0
  482. roadmap/infrastructure/coordination/milestone_operations.py +201 -0
  483. roadmap/infrastructure/coordination/project_coordinator.py +113 -0
  484. roadmap/infrastructure/coordination/project_operations.py +144 -0
  485. roadmap/infrastructure/coordination/team_coordinator.py +107 -0
  486. roadmap/infrastructure/coordination/user_operations.py +150 -0
  487. roadmap/infrastructure/coordination/validation_coordinator.py +249 -0
  488. roadmap/infrastructure/coordination_gateway.py +152 -0
  489. roadmap/infrastructure/git/__init__.py +6 -0
  490. roadmap/infrastructure/git/git_integration_ops.py +234 -0
  491. roadmap/infrastructure/git_gateway.py +35 -0
  492. roadmap/infrastructure/github_gateway.py +52 -0
  493. roadmap/infrastructure/maintenance/__init__.py +5 -0
  494. roadmap/infrastructure/maintenance/cleanup.py +483 -0
  495. roadmap/infrastructure/observability/__init__.py +7 -0
  496. roadmap/infrastructure/observability/health.py +196 -0
  497. roadmap/infrastructure/observability/health_formatter.py +73 -0
  498. roadmap/infrastructure/observability/specialized_health_checkers.py +188 -0
  499. roadmap/infrastructure/persistence_gateway.py +164 -0
  500. roadmap/infrastructure/security/__init__.py +1 -0
  501. roadmap/infrastructure/security/credentials.py +489 -0
  502. roadmap/infrastructure/sync_gateway.py +94 -0
  503. roadmap/infrastructure/validation/__init__.py +7 -0
  504. roadmap/infrastructure/validation/file_enumeration.py +219 -0
  505. roadmap/infrastructure/validation/github_assignee_validator.py +47 -0
  506. roadmap/infrastructure/validation/github_validator.py +101 -0
  507. roadmap/infrastructure/validation/milestone_consistency_validator.py +96 -0
  508. roadmap/infrastructure/validation/vanilla_assignee_validator.py +37 -0
  509. roadmap/infrastructure/validation_gateway.py +96 -0
  510. roadmap/presentation/formatters/sync_metrics_formatter.py +355 -0
  511. roadmap/settings.py +345 -0
  512. roadmap/templates/github_workflows/ci-cd-roadmap.yml +241 -0
  513. roadmap/templates/github_workflows/issue-lifecycle.yml +236 -0
  514. roadmap/templates/github_workflows/roadmap-integration.yml +137 -0
  515. roadmap/templates/github_workflows/roadmap-starter.yml +59 -0
  516. roadmap/version.py +381 -0
  517. roadmap_cli-0.1.1.dist-info/METADATA +448 -0
  518. roadmap_cli-0.1.1.dist-info/RECORD +521 -0
  519. roadmap_cli-0.1.1.dist-info/WHEEL +4 -0
  520. roadmap_cli-0.1.1.dist-info/entry_points.txt +2 -0
  521. roadmap_cli-0.1.1.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,434 @@
1
+ """Project service - handles all project-related operations.
2
+
3
+ The ProjectService manages:
4
+ - Project listing and retrieval
5
+ - Project saving/persistence
6
+ - Milestone-based progress calculation
7
+ - Project completion tracking
8
+
9
+ Extracted from core.py to separate business logic.
10
+ """
11
+
12
+ import time
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+ from roadmap.common.constants import MilestoneStatus, ProjectStatus
17
+ from roadmap.common.errors import OperationType, safe_operation
18
+ from roadmap.common.logging import get_logger
19
+ from roadmap.common.logging.error_logging import (
20
+ log_database_error,
21
+ )
22
+ from roadmap.common.observability.instrumentation import traced
23
+ from roadmap.common.services import (
24
+ log_collection_operation,
25
+ log_event,
26
+ log_metric,
27
+ )
28
+ from roadmap.common.utils.timezone_utils import now_utc
29
+ from roadmap.core.domain.project import Project
30
+ from roadmap.core.repositories import ProjectRepository
31
+ from roadmap.infrastructure.persistence_gateway import PersistenceGateway
32
+ from roadmap.infrastructure.validation.file_enumeration import FileEnumerationService
33
+
34
+ logger = get_logger(__name__)
35
+
36
+
37
+ class ProjectService:
38
+ """Service for managing projects."""
39
+
40
+ def __init__(
41
+ self, repository: ProjectRepository, milestones_dir: Path | None = None
42
+ ):
43
+ """Initialize project service.
44
+
45
+ Args:
46
+ repository: Repository for project persistence
47
+ milestones_dir: Path to milestones directory (for progress calc, optional)
48
+ """
49
+ self.repository = repository
50
+ self.milestones_dir = milestones_dir
51
+
52
+ @traced("list_projects")
53
+ def list_projects(self) -> list[Project]:
54
+ """List all projects.
55
+
56
+ Returns:
57
+ List of Project objects sorted by creation date
58
+ """
59
+ start_time = time.time()
60
+ logger.debug("listing_projects_start")
61
+
62
+ try:
63
+ projects = self.repository.list()
64
+ except Exception as e:
65
+ log_database_error(
66
+ e,
67
+ operation="list",
68
+ entity_type="Project",
69
+ )
70
+ logger.warning(
71
+ "returning_empty_project_list_due_to_error", severity="operational"
72
+ )
73
+ return []
74
+
75
+ elapsed = time.time() - start_time
76
+
77
+ log_collection_operation("projects", len(projects), "retrieved", level="debug")
78
+ log_metric("list_projects_duration", elapsed, unit="seconds", level="debug")
79
+ logger.debug(
80
+ "listing_projects_complete",
81
+ count=len(projects),
82
+ elapsed_seconds=round(elapsed, 3),
83
+ )
84
+
85
+ return projects
86
+
87
+ @traced("get_project")
88
+ def get_project(self, project_id: str) -> Project | None:
89
+ """Get a specific project by ID.
90
+
91
+ Args:
92
+ project_id: Project identifier
93
+
94
+ Returns:
95
+ Project object if found, None otherwise
96
+ """
97
+ start_time = time.time()
98
+ logger.debug("get_project_start", project_id=project_id)
99
+
100
+ try:
101
+ result = self.repository.get(project_id)
102
+ except Exception as e:
103
+ log_database_error(
104
+ e,
105
+ operation="read",
106
+ entity_type="Project",
107
+ entity_id=project_id,
108
+ )
109
+ return None
110
+
111
+ elapsed = time.time() - start_time
112
+
113
+ if result:
114
+ logger.debug(
115
+ "get_project_found",
116
+ project_id=project_id,
117
+ project_name=result.name,
118
+ elapsed_seconds=round(elapsed, 3),
119
+ )
120
+ else:
121
+ logger.debug(
122
+ "get_project_not_found",
123
+ project_id=project_id,
124
+ elapsed_seconds=round(elapsed, 3),
125
+ )
126
+
127
+ return result
128
+
129
+ @safe_operation(OperationType.UPDATE, "Project")
130
+ def save_project(self, project: Project) -> bool:
131
+ """Save an updated project to disk.
132
+
133
+ Args:
134
+ project: Project object to save
135
+
136
+ Returns:
137
+ True if saved, False on error
138
+ """
139
+ start_time = time.time()
140
+ logger.debug(
141
+ "saving_project_start", project_id=project.id, project_name=project.name
142
+ )
143
+
144
+ project.updated = now_utc()
145
+ try:
146
+ self.repository.save(project)
147
+ except Exception as e:
148
+ log_database_error(
149
+ e,
150
+ operation="update",
151
+ entity_type="Project",
152
+ entity_id=project.id,
153
+ )
154
+ raise
155
+
156
+ elapsed = time.time() - start_time
157
+ log_event("project_saved", project_id=project.id)
158
+ logger.info(
159
+ "saving_project_complete",
160
+ project_id=project.id,
161
+ elapsed_seconds=round(elapsed, 3),
162
+ )
163
+ return True
164
+
165
+ @safe_operation(OperationType.CREATE, "Project", include_traceback=True)
166
+ @traced("create_project")
167
+ def create_project(
168
+ self,
169
+ name: str,
170
+ headline: str = "",
171
+ milestones: list | None = None,
172
+ status: str | None = None,
173
+ ) -> Project:
174
+ """Create a new project.
175
+
176
+ Args:
177
+ name: Project name
178
+ headline: Project headline (short summary)
179
+ milestones: List of associated milestone names
180
+ status: Project status (optional)
181
+
182
+ Returns:
183
+ Newly created Project object
184
+ """
185
+ start_time = time.time()
186
+ logger.info(
187
+ "creating_project_start",
188
+ project_name=name,
189
+ milestones_count=len(milestones or []),
190
+ status=status,
191
+ )
192
+
193
+ # Map status string to ProjectStatus enum if provided
194
+
195
+ status_str = status if status else "planning"
196
+ # Ensure static type checkers understand this is a ProjectStatus
197
+ project_status: ProjectStatus = ProjectStatus(status_str)
198
+
199
+ project = Project(
200
+ name=name,
201
+ headline=headline or "",
202
+ content="",
203
+ milestones=milestones or [],
204
+ status=project_status,
205
+ )
206
+
207
+ self.save_project(project)
208
+ elapsed = time.time() - start_time
209
+
210
+ log_event("project_created", project_id=project.id, project_name=name)
211
+ logger.info(
212
+ "creating_project_complete",
213
+ project_id=project.id,
214
+ project_name=name,
215
+ elapsed_seconds=round(elapsed, 3),
216
+ )
217
+
218
+ return project
219
+
220
+ @safe_operation(OperationType.UPDATE, "Project")
221
+ @traced("update_project")
222
+ def update_project(self, project_id: str, **updates) -> Project | None:
223
+ """Update a project.
224
+
225
+ Args:
226
+ project_id: Project identifier
227
+ **updates: Fields to update
228
+
229
+ Returns:
230
+ Updated Project object if found, None otherwise
231
+ """
232
+ start_time = time.time()
233
+ logger.info(
234
+ "updating_project_start",
235
+ project_id=project_id,
236
+ field_count=len(updates),
237
+ fields=list(updates.keys()),
238
+ )
239
+
240
+ project = self.get_project(project_id)
241
+ if not project:
242
+ logger.warning(
243
+ "updating_project_not_found",
244
+ project_id=project_id,
245
+ severity="operational",
246
+ )
247
+ return None
248
+
249
+ # Capture old state for change logging
250
+ old_state = {k: getattr(project, k, None) for k in updates.keys()}
251
+
252
+ # Update fields
253
+ for field, value in updates.items():
254
+ if hasattr(project, field):
255
+ setattr(project, field, value)
256
+
257
+ self.save_project(project)
258
+ elapsed = time.time() - start_time
259
+
260
+ # Log state changes
261
+ new_state = {k: getattr(project, k, None) for k in updates.keys()}
262
+ changed_fields = [
263
+ k for k in updates.keys() if old_state.get(k) != new_state.get(k)
264
+ ]
265
+
266
+ log_event(
267
+ "project_updated", project_id=project_id, updated_fields=changed_fields
268
+ )
269
+ logger.info(
270
+ "updating_project_complete",
271
+ project_id=project_id,
272
+ field_count=len(updates),
273
+ changed_count=len(changed_fields),
274
+ elapsed_seconds=round(elapsed, 3),
275
+ )
276
+
277
+ return project
278
+
279
+ @safe_operation(OperationType.DELETE, "Project", include_traceback=True)
280
+ def delete_project(self, project_id: str) -> bool:
281
+ """Delete a project.
282
+
283
+ Args:
284
+ project_id: Project identifier
285
+
286
+ Returns:
287
+ True if deleted, False if not found
288
+ """
289
+ start_time = time.time()
290
+ logger.info("deleting_project_start", project_id=project_id)
291
+
292
+ project = self.get_project(project_id)
293
+ if not project:
294
+ elapsed = time.time() - start_time
295
+ logger.warning(
296
+ "deleting_project_not_found",
297
+ project_id=project_id,
298
+ elapsed_seconds=round(elapsed, 3),
299
+ severity="operational",
300
+ )
301
+ return False
302
+
303
+ project_name = project.name
304
+ success = self.repository.delete(project_id)
305
+ elapsed = time.time() - start_time
306
+
307
+ if success:
308
+ log_event(
309
+ "project_deleted",
310
+ project_id=project_id,
311
+ project_name=project_name,
312
+ )
313
+ logger.info(
314
+ "deleting_project_complete",
315
+ project_id=project_id,
316
+ project_name=project_name,
317
+ elapsed_seconds=round(elapsed, 3),
318
+ )
319
+ return success
320
+
321
+ def calculate_progress(self, project_id: str) -> dict[str, Any]:
322
+ """Calculate project progress based on associated milestones.
323
+
324
+ Returns dict with:
325
+ - total_milestones: Total milestones in project
326
+ - completed_milestones: Completed milestones
327
+ - progress: Percentage complete
328
+ - milestone_status: Status breakdown by milestone
329
+
330
+ Args:
331
+ project_id: Project identifier
332
+
333
+ Returns:
334
+ Dict with progress metrics
335
+ """
336
+ start_time = time.time()
337
+ logger.debug("calculate_progress_start", project_id=project_id)
338
+
339
+ project = self.get_project(project_id)
340
+ if not project:
341
+ logger.warning(
342
+ "calculate_progress_project_not_found",
343
+ project_id=project_id,
344
+ severity="operational",
345
+ )
346
+ return {
347
+ "total_milestones": 0,
348
+ "completed_milestones": 0,
349
+ "progress": 0.0,
350
+ "milestone_status": {},
351
+ }
352
+
353
+ # Get milestones for this project
354
+ if not self.milestones_dir:
355
+ return {
356
+ "total_milestones": len(project.milestones),
357
+ "completed_milestones": 0,
358
+ "progress": 0.0,
359
+ "milestone_status": {},
360
+ }
361
+
362
+ milestones = FileEnumerationService.enumerate_and_parse(
363
+ self.milestones_dir,
364
+ PersistenceGateway.parse_milestone_file,
365
+ )
366
+
367
+ # Build lookup for project's milestones
368
+ milestone_statuses = {}
369
+ completed_count = 0
370
+
371
+ for milestone_name in project.milestones:
372
+ for milestone in milestones:
373
+ if milestone.name == milestone_name:
374
+ milestone_statuses[milestone_name] = milestone.status.value
375
+ if milestone.status == MilestoneStatus.CLOSED:
376
+ completed_count += 1
377
+ break
378
+
379
+ total = len(project.milestones)
380
+ progress = (completed_count / total * 100) if total > 0 else 0.0
381
+ elapsed = time.time() - start_time
382
+
383
+ result = {
384
+ "total_milestones": total,
385
+ "completed_milestones": completed_count,
386
+ "progress": progress,
387
+ "milestone_status": milestone_statuses,
388
+ }
389
+
390
+ log_metric(
391
+ "project_progress",
392
+ progress,
393
+ unit="percent",
394
+ project_id=project_id,
395
+ level="debug",
396
+ )
397
+ logger.debug(
398
+ "calculate_progress_complete",
399
+ project_id=project_id,
400
+ total_milestones=total,
401
+ completed_milestones=completed_count,
402
+ progress_percent=round(progress, 1),
403
+ elapsed_seconds=round(elapsed, 3),
404
+ )
405
+
406
+ return result
407
+
408
+ def complete_project(self, project_id: str) -> Project | None:
409
+ """Mark a project as completed.
410
+
411
+ Args:
412
+ project_id: Project identifier
413
+
414
+ Returns:
415
+ Completed Project object if found, None otherwise
416
+ """
417
+ from roadmap.core.domain.project import ProjectStatus
418
+
419
+ logger.info("completing_project_start", project_id=project_id)
420
+ result = self.update_project(project_id, status=ProjectStatus.COMPLETED)
421
+
422
+ if result:
423
+ log_event(
424
+ "project_completed", project_id=project_id, project_name=result.name
425
+ )
426
+ logger.info("completing_project_complete", project_id=project_id)
427
+ else:
428
+ logger.warning(
429
+ "completing_project_not_found",
430
+ project_id=project_id,
431
+ severity="operational",
432
+ )
433
+
434
+ return result
@@ -0,0 +1,125 @@
1
+ """Project status service for roadmap CLI.
2
+
3
+ This module handles displaying project status information including
4
+ milestones, issues, and status summaries.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from roadmap.common.logging import get_logger
10
+ from roadmap.infrastructure.coordination.core import RoadmapCore
11
+
12
+ logger = get_logger(__name__)
13
+
14
+
15
+ class ProjectStatusService:
16
+ """Displays and manages project status information."""
17
+
18
+ def __init__(self, core: RoadmapCore):
19
+ """Initialize the service.
20
+
21
+ Args:
22
+ core: RoadmapCore instance
23
+ """
24
+ self.core = core
25
+
26
+ def get_project_overview(self, project_id: str | None = None) -> dict[str, Any]:
27
+ """Get overview information for a project.
28
+
29
+ Args:
30
+ project_id: Project ID to get overview for
31
+
32
+ Returns:
33
+ Dictionary with project overview data
34
+ """
35
+ try:
36
+ project_info = {"issue_count": 0, "milestone_count": 0}
37
+ return project_info
38
+ except Exception as e:
39
+ logger.error(
40
+ "Failed to get project overview",
41
+ error=str(e),
42
+ severity="operational",
43
+ )
44
+ return {"error": str(e)}
45
+
46
+ def get_milestone_progress(
47
+ self, project_id: str | None = None
48
+ ) -> list[dict[str, Any]]:
49
+ """Get progress information for all milestones in a project.
50
+
51
+ Args:
52
+ project_id: Project ID
53
+
54
+ Returns:
55
+ List of milestone progress dictionaries
56
+ """
57
+ try:
58
+ return []
59
+ except Exception as e:
60
+ logger.error(
61
+ "Failed to get milestone progress",
62
+ error=str(e),
63
+ severity="operational",
64
+ )
65
+ return []
66
+
67
+ def get_issues_by_status(self, project_id: str | None = None) -> dict[str, int]:
68
+ """Get count of issues grouped by status.
69
+
70
+ Args:
71
+ project_id: Project ID
72
+
73
+ Returns:
74
+ Dictionary mapping Status to count
75
+ """
76
+ try:
77
+ return {}
78
+ except Exception as e:
79
+ logger.error(
80
+ "Failed to get issues by status",
81
+ error=str(e),
82
+ severity="operational",
83
+ )
84
+ return {}
85
+
86
+ def get_assignee_workload(self, project_id: str | None = None) -> dict[str, int]:
87
+ """Get issue count per assignee.
88
+
89
+ Args:
90
+ project_id: Project ID
91
+
92
+ Returns:
93
+ Dictionary mapping assignee to issue count
94
+ """
95
+ try:
96
+ return {}
97
+ except Exception as e:
98
+ logger.error(
99
+ "Failed to get assignee workload",
100
+ error=str(e),
101
+ severity="operational",
102
+ )
103
+ return {}
104
+
105
+ def get_status_summary(self, project_id: str | None = None) -> dict[str, Any]:
106
+ """Get comprehensive status summary for a project.
107
+
108
+ Args:
109
+ project_id: Project ID
110
+
111
+ Returns:
112
+ Dictionary with status summary
113
+ """
114
+ try:
115
+ return {
116
+ "total_issues": 0,
117
+ "total_milestones": 0,
118
+ }
119
+ except Exception as e:
120
+ logger.error(
121
+ "Failed to get status summary",
122
+ error=str(e),
123
+ severity="operational",
124
+ )
125
+ return {"error": str(e)}
@@ -0,0 +1,22 @@
1
+ """Project initialization services package.
2
+
3
+ Provides modularized services for:
4
+ - Detecting existing projects
5
+ - Detecting project context from git and filesystem
6
+ - Generating project templates
7
+ - Creating new projects
8
+ """
9
+
10
+ from roadmap.core.services.project_init.context_detection import (
11
+ ProjectContextDetectionService,
12
+ )
13
+ from roadmap.core.services.project_init.creation import ProjectCreationService
14
+ from roadmap.core.services.project_init.detection import ProjectDetectionService
15
+ from roadmap.core.services.project_init.template import ProjectTemplateService
16
+
17
+ __all__ = [
18
+ "ProjectDetectionService",
19
+ "ProjectContextDetectionService",
20
+ "ProjectTemplateService",
21
+ "ProjectCreationService",
22
+ ]