taskdog-core 0.18.1__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 (190) hide show
  1. taskdog_core-0.18.1/PKG-INFO +141 -0
  2. taskdog_core-0.18.1/README.md +115 -0
  3. taskdog_core-0.18.1/pyproject.toml +112 -0
  4. taskdog_core-0.18.1/setup.cfg +4 -0
  5. taskdog_core-0.18.1/src/taskdog_core/__init__.py +0 -0
  6. taskdog_core-0.18.1/src/taskdog_core/application/__init__.py +1 -0
  7. taskdog_core-0.18.1/src/taskdog_core/application/constants/__init__.py +27 -0
  8. taskdog_core-0.18.1/src/taskdog_core/application/constants/optimization.py +29 -0
  9. taskdog_core-0.18.1/src/taskdog_core/application/dto/__init__.py +40 -0
  10. taskdog_core-0.18.1/src/taskdog_core/application/dto/audit_log_dto.py +139 -0
  11. taskdog_core-0.18.1/src/taskdog_core/application/dto/base.py +17 -0
  12. taskdog_core-0.18.1/src/taskdog_core/application/dto/bulk_operation_output.py +24 -0
  13. taskdog_core-0.18.1/src/taskdog_core/application/dto/create_task_input.py +29 -0
  14. taskdog_core-0.18.1/src/taskdog_core/application/dto/delete_tag_input.py +14 -0
  15. taskdog_core-0.18.1/src/taskdog_core/application/dto/delete_tag_output.py +16 -0
  16. taskdog_core-0.18.1/src/taskdog_core/application/dto/fix_actual_times_input.py +26 -0
  17. taskdog_core-0.18.1/src/taskdog_core/application/dto/gantt_output.py +79 -0
  18. taskdog_core-0.18.1/src/taskdog_core/application/dto/get_task_by_id_output.py +21 -0
  19. taskdog_core-0.18.1/src/taskdog_core/application/dto/manage_dependencies_input.py +29 -0
  20. taskdog_core-0.18.1/src/taskdog_core/application/dto/optimization_output.py +59 -0
  21. taskdog_core-0.18.1/src/taskdog_core/application/dto/optimization_summary.py +28 -0
  22. taskdog_core-0.18.1/src/taskdog_core/application/dto/optimize_params.py +28 -0
  23. taskdog_core-0.18.1/src/taskdog_core/application/dto/optimize_result.py +53 -0
  24. taskdog_core-0.18.1/src/taskdog_core/application/dto/optimize_schedule_input.py +25 -0
  25. taskdog_core-0.18.1/src/taskdog_core/application/dto/query_inputs.py +64 -0
  26. taskdog_core-0.18.1/src/taskdog_core/application/dto/set_task_tags_input.py +16 -0
  27. taskdog_core-0.18.1/src/taskdog_core/application/dto/statistics_output.py +157 -0
  28. taskdog_core-0.18.1/src/taskdog_core/application/dto/status_change_output.py +23 -0
  29. taskdog_core-0.18.1/src/taskdog_core/application/dto/tag_statistics_output.py +25 -0
  30. taskdog_core-0.18.1/src/taskdog_core/application/dto/task_detail_output.py +20 -0
  31. taskdog_core-0.18.1/src/taskdog_core/application/dto/task_dto.py +274 -0
  32. taskdog_core-0.18.1/src/taskdog_core/application/dto/task_list_output.py +33 -0
  33. taskdog_core-0.18.1/src/taskdog_core/application/dto/task_operation_output.py +93 -0
  34. taskdog_core-0.18.1/src/taskdog_core/application/dto/update_task_input.py +35 -0
  35. taskdog_core-0.18.1/src/taskdog_core/application/dto/update_task_output.py +40 -0
  36. taskdog_core-0.18.1/src/taskdog_core/application/queries/__init__.py +5 -0
  37. taskdog_core-0.18.1/src/taskdog_core/application/queries/base.py +31 -0
  38. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/__init__.py +1 -0
  39. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/composite_filter.py +60 -0
  40. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/date_range_filter.py +93 -0
  41. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/incomplete_filter.py +23 -0
  42. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/non_archived_filter.py +23 -0
  43. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/status_filter.py +30 -0
  44. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/tag_filter.py +42 -0
  45. taskdog_core-0.18.1/src/taskdog_core/application/queries/filters/task_filter.py +71 -0
  46. taskdog_core-0.18.1/src/taskdog_core/application/queries/task_filter_builder.py +124 -0
  47. taskdog_core-0.18.1/src/taskdog_core/application/queries/task_query_service.py +495 -0
  48. taskdog_core-0.18.1/src/taskdog_core/application/queries/workload/__init__.py +24 -0
  49. taskdog_core-0.18.1/src/taskdog_core/application/queries/workload/_strategies/__init__.py +26 -0
  50. taskdog_core-0.18.1/src/taskdog_core/application/queries/workload/_strategies/actual_schedule.py +179 -0
  51. taskdog_core-0.18.1/src/taskdog_core/application/queries/workload/_strategies/all_days.py +82 -0
  52. taskdog_core-0.18.1/src/taskdog_core/application/queries/workload/_strategies/base.py +101 -0
  53. taskdog_core-0.18.1/src/taskdog_core/application/queries/workload/_strategies/weekday_only.py +105 -0
  54. taskdog_core-0.18.1/src/taskdog_core/application/services/__init__.py +0 -0
  55. taskdog_core-0.18.1/src/taskdog_core/application/services/dependency_graph_service.py +75 -0
  56. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/__init__.py +21 -0
  57. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/allocation_helpers.py +86 -0
  58. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/backward_optimization_strategy.py +135 -0
  59. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/balanced_optimization_strategy.py +199 -0
  60. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/dependency_aware_optimization_strategy.py +51 -0
  61. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/earliest_deadline_optimization_strategy.py +32 -0
  62. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/genetic_optimization_strategy.py +376 -0
  63. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/greedy_based_optimization_strategy.py +163 -0
  64. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/greedy_optimization_strategy.py +24 -0
  65. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/monte_carlo_optimization_strategy.py +219 -0
  66. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/optimization_strategy.py +55 -0
  67. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/priority_first_optimization_strategy.py +29 -0
  68. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/round_robin_optimization_strategy.py +293 -0
  69. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/schedule_fitness_calculator.py +115 -0
  70. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization/strategy_factory.py +101 -0
  71. taskdog_core-0.18.1/src/taskdog_core/application/services/optimization_summary_builder.py +212 -0
  72. taskdog_core-0.18.1/src/taskdog_core/application/services/task_statistics_calculator.py +410 -0
  73. taskdog_core-0.18.1/src/taskdog_core/application/services/task_status_service.py +72 -0
  74. taskdog_core-0.18.1/src/taskdog_core/application/sorters/__init__.py +8 -0
  75. taskdog_core-0.18.1/src/taskdog_core/application/sorters/optimization_task_sorter.py +55 -0
  76. taskdog_core-0.18.1/src/taskdog_core/application/sorters/task_sorter.py +128 -0
  77. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/__init__.py +6 -0
  78. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/add_dependency.py +75 -0
  79. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/archive_task.py +53 -0
  80. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/base.py +62 -0
  81. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/calculate_statistics.py +47 -0
  82. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/cancel_task.py +25 -0
  83. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/complete_task.py +25 -0
  84. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/create_task.py +103 -0
  85. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/delete_tag.py +41 -0
  86. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/fix_actual_times.py +51 -0
  87. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/get_gantt_data.py +62 -0
  88. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/get_task_detail.py +51 -0
  89. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/list_tasks.py +69 -0
  90. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/optimize_schedule.py +246 -0
  91. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/pause_task.py +27 -0
  92. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/remove_dependency.py +49 -0
  93. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/remove_task.py +49 -0
  94. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/reopen_task.py +66 -0
  95. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/restore_task.py +59 -0
  96. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/set_task_tags.py +52 -0
  97. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/start_task.py +25 -0
  98. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/status_change_use_case.py +137 -0
  99. taskdog_core-0.18.1/src/taskdog_core/application/use_cases/update_task.py +171 -0
  100. taskdog_core-0.18.1/src/taskdog_core/application/utils/__init__.py +1 -0
  101. taskdog_core-0.18.1/src/taskdog_core/application/utils/date_helper.py +49 -0
  102. taskdog_core-0.18.1/src/taskdog_core/application/validators/__init__.py +8 -0
  103. taskdog_core-0.18.1/src/taskdog_core/application/validators/datetime_validator.py +64 -0
  104. taskdog_core-0.18.1/src/taskdog_core/application/validators/dependency_validator.py +57 -0
  105. taskdog_core-0.18.1/src/taskdog_core/application/validators/field_validator.py +28 -0
  106. taskdog_core-0.18.1/src/taskdog_core/application/validators/numeric_field_validator.py +55 -0
  107. taskdog_core-0.18.1/src/taskdog_core/application/validators/status_validator.py +95 -0
  108. taskdog_core-0.18.1/src/taskdog_core/application/validators/validator_registry.py +59 -0
  109. taskdog_core-0.18.1/src/taskdog_core/controllers/__init__.py +7 -0
  110. taskdog_core-0.18.1/src/taskdog_core/controllers/audit_log_controller.py +137 -0
  111. taskdog_core-0.18.1/src/taskdog_core/controllers/base_controller.py +34 -0
  112. taskdog_core-0.18.1/src/taskdog_core/controllers/bulk_task_controller.py +177 -0
  113. taskdog_core-0.18.1/src/taskdog_core/controllers/query_controller.py +219 -0
  114. taskdog_core-0.18.1/src/taskdog_core/controllers/task_analytics_controller.py +120 -0
  115. taskdog_core-0.18.1/src/taskdog_core/controllers/task_crud_controller.py +260 -0
  116. taskdog_core-0.18.1/src/taskdog_core/controllers/task_lifecycle_controller.py +190 -0
  117. taskdog_core-0.18.1/src/taskdog_core/controllers/task_relationship_controller.py +112 -0
  118. taskdog_core-0.18.1/src/taskdog_core/domain/__init__.py +1 -0
  119. taskdog_core-0.18.1/src/taskdog_core/domain/constants.py +33 -0
  120. taskdog_core-0.18.1/src/taskdog_core/domain/entities/__init__.py +1 -0
  121. taskdog_core-0.18.1/src/taskdog_core/domain/entities/task.py +458 -0
  122. taskdog_core-0.18.1/src/taskdog_core/domain/exceptions/__init__.py +1 -0
  123. taskdog_core-0.18.1/src/taskdog_core/domain/exceptions/tag_exceptions.py +11 -0
  124. taskdog_core-0.18.1/src/taskdog_core/domain/exceptions/task_exceptions.py +163 -0
  125. taskdog_core-0.18.1/src/taskdog_core/domain/repositories/__init__.py +7 -0
  126. taskdog_core-0.18.1/src/taskdog_core/domain/repositories/audit_log_repository.py +64 -0
  127. taskdog_core-0.18.1/src/taskdog_core/domain/repositories/notes_repository.py +82 -0
  128. taskdog_core-0.18.1/src/taskdog_core/domain/repositories/task_repository.py +280 -0
  129. taskdog_core-0.18.1/src/taskdog_core/domain/services/__init__.py +1 -0
  130. taskdog_core-0.18.1/src/taskdog_core/domain/services/holiday_checker.py +41 -0
  131. taskdog_core-0.18.1/src/taskdog_core/domain/services/logger.py +53 -0
  132. taskdog_core-0.18.1/src/taskdog_core/domain/services/time_provider.py +34 -0
  133. taskdog_core-0.18.1/src/taskdog_core/infrastructure/__init__.py +1 -0
  134. taskdog_core-0.18.1/src/taskdog_core/infrastructure/holiday_checker.py +110 -0
  135. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/__init__.py +1 -0
  136. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/__init__.py +1 -0
  137. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/base_repository.py +48 -0
  138. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/engine_factory.py +70 -0
  139. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migration_runner.py +138 -0
  140. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/__init__.py +1 -0
  141. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/env.py +89 -0
  142. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/script.py.mako +26 -0
  143. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/001_initial_schema.py +133 -0
  144. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/002_remove_actual_daily_hours.py +47 -0
  145. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/003_make_priority_nullable.py +50 -0
  146. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/004_add_notes_table.py +65 -0
  147. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/005_add_daily_allocations_table.py +133 -0
  148. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/006_remove_daily_allocations_json.py +122 -0
  149. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/migrations/versions/__init__.py +1 -0
  150. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/models/__init__.py +17 -0
  151. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/models/audit_log_model.py +92 -0
  152. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/models/daily_allocation_model.py +78 -0
  153. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/models/note_model.py +52 -0
  154. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/models/tag_model.py +93 -0
  155. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/models/task_model.py +100 -0
  156. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/mutation_builders/__init__.py +38 -0
  157. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/mutation_builders/daily_allocation_builder.py +86 -0
  158. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/mutation_builders/task_delete_builder.py +55 -0
  159. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/mutation_builders/task_insert_builder.py +55 -0
  160. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/mutation_builders/task_tag_relationship_builder.py +92 -0
  161. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/mutation_builders/task_update_builder.py +54 -0
  162. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/query_builders/__init__.py +16 -0
  163. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/query_builders/task_query_builder.py +226 -0
  164. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/sqlite_audit_log_repository.py +224 -0
  165. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/sqlite_notes_repository.py +253 -0
  166. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/database/sqlite_task_repository.py +664 -0
  167. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/mappers/__init__.py +5 -0
  168. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/mappers/tag_resolver.py +102 -0
  169. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/mappers/task_db_mapper.py +168 -0
  170. taskdog_core-0.18.1/src/taskdog_core/infrastructure/persistence/repository_factory.py +77 -0
  171. taskdog_core-0.18.1/src/taskdog_core/infrastructure/time_provider.py +25 -0
  172. taskdog_core-0.18.1/src/taskdog_core/py.typed +0 -0
  173. taskdog_core-0.18.1/src/taskdog_core/shared/__init__.py +0 -0
  174. taskdog_core-0.18.1/src/taskdog_core/shared/config_loader.py +138 -0
  175. taskdog_core-0.18.1/src/taskdog_core/shared/config_manager.py +176 -0
  176. taskdog_core-0.18.1/src/taskdog_core/shared/constants/__init__.py +64 -0
  177. taskdog_core-0.18.1/src/taskdog_core/shared/constants/config_defaults.py +12 -0
  178. taskdog_core-0.18.1/src/taskdog_core/shared/constants/file_management.py +4 -0
  179. taskdog_core-0.18.1/src/taskdog_core/shared/constants/formats.py +8 -0
  180. taskdog_core-0.18.1/src/taskdog_core/shared/constants/status_verbs.py +12 -0
  181. taskdog_core-0.18.1/src/taskdog_core/shared/constants/time.py +12 -0
  182. taskdog_core-0.18.1/src/taskdog_core/shared/utils/__init__.py +11 -0
  183. taskdog_core-0.18.1/src/taskdog_core/shared/utils/date_utils.py +49 -0
  184. taskdog_core-0.18.1/src/taskdog_core/shared/utils/datetime_parser.py +101 -0
  185. taskdog_core-0.18.1/src/taskdog_core/shared/xdg_utils.py +61 -0
  186. taskdog_core-0.18.1/src/taskdog_core.egg-info/PKG-INFO +141 -0
  187. taskdog_core-0.18.1/src/taskdog_core.egg-info/SOURCES.txt +188 -0
  188. taskdog_core-0.18.1/src/taskdog_core.egg-info/dependency_links.txt +1 -0
  189. taskdog_core-0.18.1/src/taskdog_core.egg-info/requires.txt +9 -0
  190. taskdog_core-0.18.1/src/taskdog_core.egg-info/top_level.txt +1 -0
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: taskdog-core
3
+ Version: 0.18.1
4
+ Summary: Core business logic and infrastructure for Taskdog
5
+ Author: Kohei Wada
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Kohei-Wada/taskdog
8
+ Project-URL: Repository, https://github.com/Kohei-Wada/taskdog
9
+ Project-URL: Bug Tracker, https://github.com/Kohei-Wada/taskdog/issues
10
+ Keywords: task,management,scheduling
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Python: >=3.12
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: alembic>=1.13.0
19
+ Requires-Dist: holidays>=0.60.0
20
+ Requires-Dist: sqlalchemy>=2.0.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
23
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
24
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
25
+ Requires-Dist: ruff>=0.7.0; extra == "dev"
26
+
27
+ # taskdog-core
28
+
29
+ Core business logic and infrastructure for Taskdog task management system.
30
+
31
+ ## Overview
32
+
33
+ This package contains the core components shared by both the Taskdog server and UI:
34
+
35
+ - **Domain Layer**: Business entities, domain services, and interfaces
36
+ - **Application Layer**: Use cases, queries, DTOs, and business logic orchestration
37
+ - **Infrastructure Layer**: Persistence implementations, external service integrations
38
+ - **Controllers**: Business logic orchestrators used by presentation layers
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ pip install taskdog-core
44
+ ```
45
+
46
+ For development:
47
+
48
+ ```bash
49
+ pip install -e ".[dev]"
50
+ ```
51
+
52
+ ## Architecture
53
+
54
+ Follows Clean Architecture principles:
55
+
56
+ ```text
57
+ Domain (entities, services, repositories)
58
+
59
+ Application (use cases, queries, DTOs)
60
+
61
+ Infrastructure (SQLite, file storage)
62
+
63
+ Controllers (orchestration layer)
64
+ ```
65
+
66
+ ### Key Components
67
+
68
+ **Domain Layer** (`taskdog_core/domain/`):
69
+
70
+ - `Task` - Core entity with status, priority, deadlines, dependencies
71
+ - `TaskStatus` - PENDING, IN_PROGRESS, COMPLETED, CANCELED
72
+ - `TimeTracker` - Records actual_start/actual_end timestamps
73
+ - `TaskNotFoundException`, `TaskValidationError` - Domain exceptions
74
+
75
+ **Application Layer** (`taskdog_core/application/`):
76
+
77
+ - **Use Cases**: CreateTaskUseCase, StartTaskUseCase, OptimizeScheduleUseCase, etc.
78
+ - **Validators**: TaskFieldValidatorRegistry with Status and Dependency validators
79
+ - **Services**: WorkloadAllocator, OptimizationSummaryBuilder, TaskQueryService
80
+ - **Optimization**: 9 scheduling strategies (greedy, balanced, backward, priority_first, earliest_deadline, round_robin, dependency_aware, genetic, monte_carlo)
81
+
82
+ **Infrastructure Layer** (`taskdog_core/infrastructure/`):
83
+
84
+ - `SqliteTaskRepository` - SQLite persistence with transactional writes
85
+ - `SqliteNotesRepository` - Database-based notes storage
86
+ - `ConfigManager` - TOML configuration loading
87
+
88
+ **Controllers** (`taskdog_core/controllers/`):
89
+
90
+ - `TaskCrudController` - Create, update, delete operations
91
+ - `TaskLifecycleController` - Start, complete, pause, cancel, reopen
92
+ - `TaskRelationshipController` - Dependencies and tags
93
+ - `TaskAnalyticsController` - Statistics and optimization
94
+ - `QueryController` - Read-only operations
95
+
96
+ ## Usage Example
97
+
98
+ ```python
99
+ from taskdog_core.domain.entities.task import Task, TaskStatus
100
+ from taskdog_core.infrastructure.persistence.database.sqlite_task_repository import SqliteTaskRepository
101
+ from taskdog_core.controllers.task_crud_controller import TaskCrudController
102
+ from taskdog_core.infrastructure.config.config_manager import ConfigManager
103
+ from taskdog_core.shared.utils.logger import StandardLogger
104
+
105
+ # Setup
106
+ repository = SqliteTaskRepository("sqlite:///tasks.db")
107
+ config = ConfigManager()
108
+ logger = StandardLogger("example")
109
+
110
+ # Create controller
111
+ crud_controller = TaskCrudController(repository, config, logger)
112
+
113
+ # Create a task
114
+ from taskdog_core.application.dto.task_request import CreateTaskRequest
115
+ request = CreateTaskRequest(name="My Task", priority=100)
116
+ task = crud_controller.create_task(request)
117
+ ```
118
+
119
+ ## Dependencies
120
+
121
+ - `holidays`: Holiday checking for scheduling
122
+ - `python-dateutil`: Date/time utilities
123
+ - `sqlalchemy`: Database ORM
124
+
125
+ ## Related Packages
126
+
127
+ - [taskdog-server](../taskdog-server/): FastAPI REST API server using this package
128
+ - [taskdog-ui](../taskdog-ui/): CLI and TUI interfaces using this package
129
+ - [taskdog-client](../taskdog-client/): HTTP client library for API access
130
+
131
+ For detailed architecture documentation, see [CLAUDE.md](../../CLAUDE.md).
132
+
133
+ ## Testing
134
+
135
+ ```bash
136
+ pytest tests/
137
+ ```
138
+
139
+ ## License
140
+
141
+ MIT
@@ -0,0 +1,115 @@
1
+ # taskdog-core
2
+
3
+ Core business logic and infrastructure for Taskdog task management system.
4
+
5
+ ## Overview
6
+
7
+ This package contains the core components shared by both the Taskdog server and UI:
8
+
9
+ - **Domain Layer**: Business entities, domain services, and interfaces
10
+ - **Application Layer**: Use cases, queries, DTOs, and business logic orchestration
11
+ - **Infrastructure Layer**: Persistence implementations, external service integrations
12
+ - **Controllers**: Business logic orchestrators used by presentation layers
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install taskdog-core
18
+ ```
19
+
20
+ For development:
21
+
22
+ ```bash
23
+ pip install -e ".[dev]"
24
+ ```
25
+
26
+ ## Architecture
27
+
28
+ Follows Clean Architecture principles:
29
+
30
+ ```text
31
+ Domain (entities, services, repositories)
32
+
33
+ Application (use cases, queries, DTOs)
34
+
35
+ Infrastructure (SQLite, file storage)
36
+
37
+ Controllers (orchestration layer)
38
+ ```
39
+
40
+ ### Key Components
41
+
42
+ **Domain Layer** (`taskdog_core/domain/`):
43
+
44
+ - `Task` - Core entity with status, priority, deadlines, dependencies
45
+ - `TaskStatus` - PENDING, IN_PROGRESS, COMPLETED, CANCELED
46
+ - `TimeTracker` - Records actual_start/actual_end timestamps
47
+ - `TaskNotFoundException`, `TaskValidationError` - Domain exceptions
48
+
49
+ **Application Layer** (`taskdog_core/application/`):
50
+
51
+ - **Use Cases**: CreateTaskUseCase, StartTaskUseCase, OptimizeScheduleUseCase, etc.
52
+ - **Validators**: TaskFieldValidatorRegistry with Status and Dependency validators
53
+ - **Services**: WorkloadAllocator, OptimizationSummaryBuilder, TaskQueryService
54
+ - **Optimization**: 9 scheduling strategies (greedy, balanced, backward, priority_first, earliest_deadline, round_robin, dependency_aware, genetic, monte_carlo)
55
+
56
+ **Infrastructure Layer** (`taskdog_core/infrastructure/`):
57
+
58
+ - `SqliteTaskRepository` - SQLite persistence with transactional writes
59
+ - `SqliteNotesRepository` - Database-based notes storage
60
+ - `ConfigManager` - TOML configuration loading
61
+
62
+ **Controllers** (`taskdog_core/controllers/`):
63
+
64
+ - `TaskCrudController` - Create, update, delete operations
65
+ - `TaskLifecycleController` - Start, complete, pause, cancel, reopen
66
+ - `TaskRelationshipController` - Dependencies and tags
67
+ - `TaskAnalyticsController` - Statistics and optimization
68
+ - `QueryController` - Read-only operations
69
+
70
+ ## Usage Example
71
+
72
+ ```python
73
+ from taskdog_core.domain.entities.task import Task, TaskStatus
74
+ from taskdog_core.infrastructure.persistence.database.sqlite_task_repository import SqliteTaskRepository
75
+ from taskdog_core.controllers.task_crud_controller import TaskCrudController
76
+ from taskdog_core.infrastructure.config.config_manager import ConfigManager
77
+ from taskdog_core.shared.utils.logger import StandardLogger
78
+
79
+ # Setup
80
+ repository = SqliteTaskRepository("sqlite:///tasks.db")
81
+ config = ConfigManager()
82
+ logger = StandardLogger("example")
83
+
84
+ # Create controller
85
+ crud_controller = TaskCrudController(repository, config, logger)
86
+
87
+ # Create a task
88
+ from taskdog_core.application.dto.task_request import CreateTaskRequest
89
+ request = CreateTaskRequest(name="My Task", priority=100)
90
+ task = crud_controller.create_task(request)
91
+ ```
92
+
93
+ ## Dependencies
94
+
95
+ - `holidays`: Holiday checking for scheduling
96
+ - `python-dateutil`: Date/time utilities
97
+ - `sqlalchemy`: Database ORM
98
+
99
+ ## Related Packages
100
+
101
+ - [taskdog-server](../taskdog-server/): FastAPI REST API server using this package
102
+ - [taskdog-ui](../taskdog-ui/): CLI and TUI interfaces using this package
103
+ - [taskdog-client](../taskdog-client/): HTTP client library for API access
104
+
105
+ For detailed architecture documentation, see [CLAUDE.md](../../CLAUDE.md).
106
+
107
+ ## Testing
108
+
109
+ ```bash
110
+ pytest tests/
111
+ ```
112
+
113
+ ## License
114
+
115
+ MIT
@@ -0,0 +1,112 @@
1
+ [project]
2
+ name = "taskdog-core"
3
+ version = "0.18.1"
4
+ description = "Core business logic and infrastructure for Taskdog"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ authors = [
8
+ { name = "Kohei Wada" }
9
+ ]
10
+ license = { text = "MIT" }
11
+ keywords = ["task", "management", "scheduling"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ ]
19
+
20
+ dependencies = [
21
+ "alembic>=1.13.0",
22
+ "holidays>=0.60.0",
23
+ "sqlalchemy>=2.0.0",
24
+ ]
25
+
26
+ [project.optional-dependencies]
27
+ dev = [
28
+ "pytest>=7.0.0",
29
+ "pytest-cov>=4.0.0",
30
+ "mypy>=1.0.0",
31
+ "ruff>=0.7.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/Kohei-Wada/taskdog"
36
+ Repository = "https://github.com/Kohei-Wada/taskdog"
37
+ "Bug Tracker" = "https://github.com/Kohei-Wada/taskdog/issues"
38
+
39
+ [build-system]
40
+ requires = ["setuptools>=68.0.0", "wheel"]
41
+ build-backend = "setuptools.build_meta"
42
+
43
+ [tool.setuptools]
44
+ packages = [
45
+ "taskdog_core",
46
+ "taskdog_core.domain",
47
+ "taskdog_core.domain.entities",
48
+ "taskdog_core.domain.services",
49
+ "taskdog_core.domain.repositories",
50
+ "taskdog_core.domain.exceptions",
51
+ "taskdog_core.application",
52
+ "taskdog_core.application.dto",
53
+ "taskdog_core.application.use_cases",
54
+ "taskdog_core.application.services",
55
+ "taskdog_core.application.services.optimization",
56
+ "taskdog_core.application.queries",
57
+ "taskdog_core.application.queries.filters",
58
+ "taskdog_core.application.queries.workload",
59
+ "taskdog_core.application.queries.workload._strategies",
60
+ "taskdog_core.application.sorters",
61
+ "taskdog_core.application.validators",
62
+ "taskdog_core.application.constants",
63
+ "taskdog_core.application.utils",
64
+ "taskdog_core.infrastructure",
65
+ "taskdog_core.infrastructure.persistence",
66
+ "taskdog_core.infrastructure.persistence.database",
67
+ "taskdog_core.infrastructure.persistence.database.models",
68
+ "taskdog_core.infrastructure.persistence.database.query_builders",
69
+ "taskdog_core.infrastructure.persistence.database.mutation_builders",
70
+ "taskdog_core.infrastructure.persistence.mappers",
71
+ "taskdog_core.controllers",
72
+ "taskdog_core.shared",
73
+ "taskdog_core.shared.constants",
74
+ "taskdog_core.shared.utils",
75
+ "taskdog_core.infrastructure.persistence.database.migrations",
76
+ "taskdog_core.infrastructure.persistence.database.migrations.versions",
77
+ ]
78
+ package-dir = { "" = "src" }
79
+
80
+ [tool.setuptools.package-data]
81
+ taskdog_core = ["py.typed"]
82
+ "taskdog_core.infrastructure.persistence.database.migrations" = ["*.mako"]
83
+
84
+ [tool.mypy]
85
+ python_version = "3.13"
86
+ strict = true
87
+ # Disable unused-ignore warnings (SQLAlchemy attr-defined errors are environment-dependent)
88
+ warn_unused_ignores = false
89
+
90
+ [[tool.mypy.overrides]]
91
+ module = "alembic.*"
92
+ ignore_missing_imports = true
93
+
94
+ [tool.pytest.ini_options]
95
+ testpaths = ["tests"]
96
+ python_files = ["test_*.py"]
97
+ python_classes = ["Test*"]
98
+ python_functions = ["test_*"]
99
+
100
+ [tool.coverage.run]
101
+ omit = [
102
+ "*/migrations/*",
103
+ "*/migrations/versions/*",
104
+ ]
105
+
106
+ [tool.coverage.report]
107
+ exclude_lines = [
108
+ "pragma: no cover",
109
+ "if TYPE_CHECKING:",
110
+ "raise NotImplementedError",
111
+ "@abstractmethod",
112
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1 @@
1
+ """Application layer - Use cases and queries."""
@@ -0,0 +1,27 @@
1
+ """Application layer constants."""
2
+
3
+ from taskdog_core.application.constants.optimization import (
4
+ DEADLINE_PENALTY_MULTIPLIER,
5
+ GENETIC_CROSSOVER_RATE,
6
+ GENETIC_EARLY_TERMINATION_GENERATIONS,
7
+ GENETIC_GENERATIONS,
8
+ GENETIC_MUTATION_RATE,
9
+ GENETIC_POPULATION_SIZE,
10
+ GENETIC_TOURNAMENT_SIZE,
11
+ MONTE_CARLO_NUM_SIMULATIONS,
12
+ ROUND_ROBIN_MAX_ITERATIONS,
13
+ SCHEDULING_EPSILON,
14
+ )
15
+
16
+ __all__ = [
17
+ "DEADLINE_PENALTY_MULTIPLIER",
18
+ "GENETIC_CROSSOVER_RATE",
19
+ "GENETIC_EARLY_TERMINATION_GENERATIONS",
20
+ "GENETIC_GENERATIONS",
21
+ "GENETIC_MUTATION_RATE",
22
+ "GENETIC_POPULATION_SIZE",
23
+ "GENETIC_TOURNAMENT_SIZE",
24
+ "MONTE_CARLO_NUM_SIMULATIONS",
25
+ "ROUND_ROBIN_MAX_ITERATIONS",
26
+ "SCHEDULING_EPSILON",
27
+ ]
@@ -0,0 +1,29 @@
1
+ """Optimization algorithm constants and default parameters."""
2
+
3
+ # Genetic Algorithm Parameters
4
+ GENETIC_POPULATION_SIZE = 20 # Number of individuals in population
5
+ GENETIC_GENERATIONS = (
6
+ 30 # Number of evolution generations (reduced from 50 for performance)
7
+ )
8
+ GENETIC_CROSSOVER_RATE = 0.8 # Probability of crossover between parents
9
+ GENETIC_MUTATION_RATE = 0.2 # Probability of mutation in offspring
10
+ GENETIC_TOURNAMENT_SIZE = 3 # Number of individuals in tournament selection
11
+ GENETIC_EARLY_TERMINATION_GENERATIONS = (
12
+ 10 # Stop if no improvement for this many generations
13
+ )
14
+
15
+ # Monte Carlo Parameters
16
+ MONTE_CARLO_NUM_SIMULATIONS = (
17
+ 50 # Number of random simulations to run (reduced from 100 for performance)
18
+ )
19
+
20
+ # Round Robin Parameters
21
+ ROUND_ROBIN_MAX_ITERATIONS = 10000 # Safety limit to prevent infinite loops
22
+
23
+ # Penalty Multipliers (shared across multiple algorithms)
24
+ DEADLINE_PENALTY_MULTIPLIER = (
25
+ 100 # Penalty for missing deadlines in fitness calculations
26
+ )
27
+
28
+ # Scheduling Precision
29
+ SCHEDULING_EPSILON = 0.001 # Minimum hours threshold for scheduling calculations
@@ -0,0 +1,40 @@
1
+ """Data Transfer Objects."""
2
+
3
+ from taskdog_core.application.dto.base import SingleTaskInput
4
+ from taskdog_core.application.dto.gantt_output import GanttDateRange, GanttOutput
5
+ from taskdog_core.application.dto.query_inputs import (
6
+ GetGanttDataInput,
7
+ ListTasksInput,
8
+ TimeRange,
9
+ )
10
+ from taskdog_core.application.dto.statistics_output import (
11
+ CalculateStatisticsInput,
12
+ DeadlineComplianceStatistics,
13
+ EstimationAccuracyStatistics,
14
+ PriorityDistributionStatistics,
15
+ StatisticsOutput,
16
+ TaskStatistics,
17
+ TimeStatistics,
18
+ TrendStatistics,
19
+ )
20
+ from taskdog_core.application.dto.status_change_output import StatusChangeOutput
21
+ from taskdog_core.application.dto.task_detail_output import TaskDetailOutput
22
+
23
+ __all__ = [
24
+ "CalculateStatisticsInput",
25
+ "DeadlineComplianceStatistics",
26
+ "EstimationAccuracyStatistics",
27
+ "GanttDateRange",
28
+ "GanttOutput",
29
+ "GetGanttDataInput",
30
+ "ListTasksInput",
31
+ "PriorityDistributionStatistics",
32
+ "SingleTaskInput",
33
+ "StatisticsOutput",
34
+ "StatusChangeOutput",
35
+ "TaskDetailOutput",
36
+ "TaskStatistics",
37
+ "TimeRange",
38
+ "TimeStatistics",
39
+ "TrendStatistics",
40
+ ]
@@ -0,0 +1,139 @@
1
+ """DTOs for audit logging operations.
2
+
3
+ This module defines data transfer objects for audit log operations,
4
+ including the audit event structure and query parameters.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from datetime import datetime
9
+ from typing import Any
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class AuditEvent:
14
+ """Represents a single audit log event.
15
+
16
+ This DTO is used to capture audit information when API operations
17
+ are performed. It tracks who did what, when, and what changed.
18
+ """
19
+
20
+ timestamp: datetime
21
+ """When the operation occurred."""
22
+
23
+ operation: str
24
+ """The type of operation (e.g., 'create_task', 'complete_task')."""
25
+
26
+ resource_type: str
27
+ """The type of resource (e.g., 'task', 'schedule')."""
28
+
29
+ success: bool
30
+ """Whether the operation succeeded."""
31
+
32
+ client_name: str | None = None
33
+ """The authenticated client name (e.g., 'claude-code')."""
34
+
35
+ resource_id: int | None = None
36
+ """The ID of the affected resource (task ID, etc.)."""
37
+
38
+ resource_name: str | None = None
39
+ """The name of the affected resource (task name, etc.)."""
40
+
41
+ old_values: dict[str, Any] | None = None
42
+ """Values before the change (for update operations)."""
43
+
44
+ new_values: dict[str, Any] | None = None
45
+ """Values after the change."""
46
+
47
+ error_message: str | None = None
48
+ """Error message if the operation failed."""
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ class AuditQuery:
53
+ """Query parameters for filtering audit logs.
54
+
55
+ All fields are optional. If not specified, no filtering is applied
56
+ for that field.
57
+ """
58
+
59
+ client_name: str | None = None
60
+ """Filter by client name."""
61
+
62
+ operation: str | None = None
63
+ """Filter by operation type."""
64
+
65
+ resource_type: str | None = None
66
+ """Filter by resource type."""
67
+
68
+ resource_id: int | None = None
69
+ """Filter by resource ID (task ID)."""
70
+
71
+ success: bool | None = None
72
+ """Filter by success status."""
73
+
74
+ start_date: datetime | None = None
75
+ """Filter logs from this date onwards."""
76
+
77
+ end_date: datetime | None = None
78
+ """Filter logs up to this date."""
79
+
80
+ limit: int = 100
81
+ """Maximum number of logs to return."""
82
+
83
+ offset: int = 0
84
+ """Number of logs to skip (for pagination)."""
85
+
86
+
87
+ @dataclass(frozen=True)
88
+ class AuditLogOutput:
89
+ """Output DTO for a single audit log entry."""
90
+
91
+ id: int
92
+ """Unique identifier for the audit log entry."""
93
+
94
+ timestamp: datetime
95
+ """When the operation occurred."""
96
+
97
+ client_name: str | None
98
+ """The authenticated client name."""
99
+
100
+ operation: str
101
+ """The type of operation."""
102
+
103
+ resource_type: str
104
+ """The type of resource."""
105
+
106
+ resource_id: int | None
107
+ """The ID of the affected resource."""
108
+
109
+ resource_name: str | None
110
+ """The name of the affected resource."""
111
+
112
+ old_values: dict[str, Any] | None
113
+ """Values before the change."""
114
+
115
+ new_values: dict[str, Any] | None
116
+ """Values after the change."""
117
+
118
+ success: bool
119
+ """Whether the operation succeeded."""
120
+
121
+ error_message: str | None
122
+ """Error message if the operation failed."""
123
+
124
+
125
+ @dataclass(frozen=True)
126
+ class AuditLogListOutput:
127
+ """Output DTO for audit log list with pagination info."""
128
+
129
+ logs: list[AuditLogOutput] = field(default_factory=list)
130
+ """List of audit log entries."""
131
+
132
+ total_count: int = 0
133
+ """Total number of logs matching the query (for pagination)."""
134
+
135
+ limit: int = 100
136
+ """Maximum number of logs returned."""
137
+
138
+ offset: int = 0
139
+ """Number of logs skipped."""
@@ -0,0 +1,17 @@
1
+ """Base DTO classes for task operations."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass
7
+ class SingleTaskInput:
8
+ """Request data for single-task operations.
9
+
10
+ This base class is used for operations that only require a task ID,
11
+ such as starting, completing, pausing, removing, or archiving a task.
12
+
13
+ Attributes:
14
+ task_id: ID of the task to operate on
15
+ """
16
+
17
+ task_id: int
@@ -0,0 +1,24 @@
1
+ """Output DTOs for bulk task operations."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from taskdog_core.application.dto.task_operation_output import TaskOperationOutput
6
+
7
+
8
+ @dataclass
9
+ class BulkTaskResultOutput:
10
+ """Result for a single task in a bulk operation."""
11
+
12
+ task_id: int
13
+ success: bool
14
+ task: TaskOperationOutput | None
15
+ error: str | None
16
+ old_status: str | None = None
17
+ task_name: str | None = None
18
+
19
+
20
+ @dataclass
21
+ class BulkOperationOutput:
22
+ """Output DTO for bulk task operations."""
23
+
24
+ results: list[BulkTaskResultOutput]
@@ -0,0 +1,29 @@
1
+ """DTO for creating a task."""
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import datetime
5
+
6
+
7
+ @dataclass
8
+ class CreateTaskInput:
9
+ """Request data for creating a task.
10
+
11
+ Attributes:
12
+ name: Task name
13
+ priority: Task priority (higher value = higher priority), or None if not set
14
+ planned_start: Planned start datetime (optional)
15
+ planned_end: Planned end datetime (optional)
16
+ deadline: Deadline datetime (optional)
17
+ estimated_duration: Estimated duration in hours (optional)
18
+ is_fixed: Whether task schedule is fixed and shouldn't be changed by optimizer (optional)
19
+ tags: List of tags for categorization and filtering (optional)
20
+ """
21
+
22
+ name: str
23
+ priority: int | None = None
24
+ planned_start: datetime | None = None
25
+ planned_end: datetime | None = None
26
+ deadline: datetime | None = None
27
+ estimated_duration: float | None = None
28
+ is_fixed: bool = False
29
+ tags: list[str] | None = None