aidp 0.27.0 → 0.28.0

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +89 -0
  3. data/lib/aidp/cli/models_command.rb +5 -6
  4. data/lib/aidp/cli.rb +10 -8
  5. data/lib/aidp/config.rb +54 -0
  6. data/lib/aidp/debug_mixin.rb +23 -1
  7. data/lib/aidp/execute/agent_signal_parser.rb +22 -0
  8. data/lib/aidp/execute/repl_macros.rb +2 -2
  9. data/lib/aidp/execute/steps.rb +94 -1
  10. data/lib/aidp/execute/work_loop_runner.rb +209 -17
  11. data/lib/aidp/execute/workflow_selector.rb +2 -25
  12. data/lib/aidp/firewall/provider_requirements_collector.rb +262 -0
  13. data/lib/aidp/harness/ai_decision_engine.rb +35 -2
  14. data/lib/aidp/harness/config_manager.rb +0 -5
  15. data/lib/aidp/harness/config_schema.rb +8 -0
  16. data/lib/aidp/harness/configuration.rb +27 -19
  17. data/lib/aidp/harness/enhanced_runner.rb +1 -4
  18. data/lib/aidp/harness/error_handler.rb +1 -72
  19. data/lib/aidp/harness/provider_factory.rb +11 -2
  20. data/lib/aidp/harness/state_manager.rb +0 -7
  21. data/lib/aidp/harness/thinking_depth_manager.rb +47 -68
  22. data/lib/aidp/harness/ui/enhanced_tui.rb +8 -18
  23. data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +0 -18
  24. data/lib/aidp/harness/ui/progress_display.rb +6 -2
  25. data/lib/aidp/harness/user_interface.rb +0 -58
  26. data/lib/aidp/init/runner.rb +7 -2
  27. data/lib/aidp/planning/analyzers/feedback_analyzer.rb +365 -0
  28. data/lib/aidp/planning/builders/agile_plan_builder.rb +387 -0
  29. data/lib/aidp/planning/builders/project_plan_builder.rb +193 -0
  30. data/lib/aidp/planning/generators/gantt_generator.rb +190 -0
  31. data/lib/aidp/planning/generators/iteration_plan_generator.rb +392 -0
  32. data/lib/aidp/planning/generators/legacy_research_planner.rb +473 -0
  33. data/lib/aidp/planning/generators/marketing_report_generator.rb +348 -0
  34. data/lib/aidp/planning/generators/mvp_scope_generator.rb +310 -0
  35. data/lib/aidp/planning/generators/user_test_plan_generator.rb +373 -0
  36. data/lib/aidp/planning/generators/wbs_generator.rb +259 -0
  37. data/lib/aidp/planning/mappers/persona_mapper.rb +163 -0
  38. data/lib/aidp/planning/parsers/document_parser.rb +141 -0
  39. data/lib/aidp/planning/parsers/feedback_data_parser.rb +252 -0
  40. data/lib/aidp/provider_manager.rb +8 -32
  41. data/lib/aidp/providers/aider.rb +264 -0
  42. data/lib/aidp/providers/anthropic.rb +74 -2
  43. data/lib/aidp/providers/base.rb +25 -1
  44. data/lib/aidp/providers/codex.rb +26 -3
  45. data/lib/aidp/providers/cursor.rb +16 -0
  46. data/lib/aidp/providers/gemini.rb +13 -0
  47. data/lib/aidp/providers/github_copilot.rb +17 -0
  48. data/lib/aidp/providers/kilocode.rb +11 -0
  49. data/lib/aidp/providers/opencode.rb +11 -0
  50. data/lib/aidp/setup/wizard.rb +249 -39
  51. data/lib/aidp/version.rb +1 -1
  52. data/lib/aidp/watch/build_processor.rb +211 -30
  53. data/lib/aidp/watch/change_request_processor.rb +128 -14
  54. data/lib/aidp/watch/ci_fix_processor.rb +103 -37
  55. data/lib/aidp/watch/ci_log_extractor.rb +258 -0
  56. data/lib/aidp/watch/github_state_extractor.rb +177 -0
  57. data/lib/aidp/watch/implementation_verifier.rb +284 -0
  58. data/lib/aidp/watch/plan_generator.rb +7 -43
  59. data/lib/aidp/watch/plan_processor.rb +7 -6
  60. data/lib/aidp/watch/repository_client.rb +245 -17
  61. data/lib/aidp/watch/review_processor.rb +98 -17
  62. data/lib/aidp/watch/reviewers/base_reviewer.rb +1 -1
  63. data/lib/aidp/watch/runner.rb +181 -29
  64. data/lib/aidp/watch/state_store.rb +22 -1
  65. data/lib/aidp/workflows/definitions.rb +147 -0
  66. data/lib/aidp/workstream_cleanup.rb +245 -0
  67. data/lib/aidp/worktree.rb +19 -0
  68. data/templates/aidp.yml.example +57 -0
  69. data/templates/implementation/generate_tdd_specs.md +213 -0
  70. data/templates/implementation/iterative_implementation.md +122 -0
  71. data/templates/planning/agile/analyze_feedback.md +183 -0
  72. data/templates/planning/agile/generate_iteration_plan.md +179 -0
  73. data/templates/planning/agile/generate_legacy_research_plan.md +171 -0
  74. data/templates/planning/agile/generate_marketing_report.md +162 -0
  75. data/templates/planning/agile/generate_mvp_scope.md +127 -0
  76. data/templates/planning/agile/generate_user_test_plan.md +143 -0
  77. data/templates/planning/agile/ingest_feedback.md +174 -0
  78. data/templates/planning/assemble_project_plan.md +113 -0
  79. data/templates/planning/assign_personas.md +108 -0
  80. data/templates/planning/create_tasks.md +52 -6
  81. data/templates/planning/generate_gantt.md +86 -0
  82. data/templates/planning/generate_wbs.md +85 -0
  83. data/templates/planning/initialize_planning_mode.md +70 -0
  84. data/templates/skills/README.md +2 -2
  85. data/templates/skills/marketing_strategist/SKILL.md +279 -0
  86. data/templates/skills/product_manager/SKILL.md +177 -0
  87. data/templates/skills/ruby_aidp_planning/SKILL.md +497 -0
  88. data/templates/skills/ruby_rspec_tdd/SKILL.md +514 -0
  89. data/templates/skills/ux_researcher/SKILL.md +222 -0
  90. metadata +39 -1
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../logger"
4
+
5
+ module Aidp
6
+ module Planning
7
+ module Generators
8
+ # Generates user testing plan with recruitment criteria and survey templates
9
+ # Uses AI to create contextual testing questions based on feature set
10
+ # Follows Zero Framework Cognition (ZFC) pattern
11
+ class UserTestPlanGenerator
12
+ def initialize(ai_decision_engine:, config: nil)
13
+ @ai_decision_engine = ai_decision_engine
14
+ @config = config || Aidp::Config.agile_config
15
+ end
16
+
17
+ # Generate user test plan from MVP scope
18
+ # @param mvp_scope [Hash] MVP scope definition
19
+ # @param target_users [String] Description of target users (optional)
20
+ # @return [Hash] User test plan structure
21
+ def generate(mvp_scope:, target_users: nil)
22
+ Aidp.log_debug("user_test_plan_generator", "generate",
23
+ feature_count: mvp_scope[:mvp_features]&.size || 0)
24
+
25
+ # Use AI to generate contextual testing plan
26
+ test_plan = generate_test_plan_with_ai(mvp_scope, target_users)
27
+
28
+ {
29
+ overview: test_plan[:overview],
30
+ target_users: test_plan[:target_users],
31
+ recruitment: test_plan[:recruitment],
32
+ testing_stages: test_plan[:testing_stages],
33
+ survey_questions: test_plan[:survey_questions],
34
+ interview_script: test_plan[:interview_script],
35
+ success_metrics: test_plan[:success_metrics],
36
+ timeline: test_plan[:timeline],
37
+ metadata: {
38
+ generated_at: Time.now.iso8601,
39
+ mvp_feature_count: mvp_scope[:mvp_features]&.size || 0,
40
+ testing_stage_count: test_plan[:testing_stages]&.size || 0,
41
+ survey_question_count: test_plan[:survey_questions]&.size || 0
42
+ }
43
+ }
44
+ end
45
+
46
+ # Format user test plan as markdown
47
+ # @param test_plan [Hash] User test plan structure
48
+ # @return [String] Markdown formatted test plan
49
+ def format_as_markdown(test_plan)
50
+ Aidp.log_debug("user_test_plan_generator", "format_as_markdown")
51
+
52
+ output = ["# User Testing Plan", ""]
53
+ output << "**Generated:** #{test_plan[:metadata][:generated_at]}"
54
+ output << "**Features to Test:** #{test_plan[:metadata][:mvp_feature_count]}"
55
+ output << "**Testing Stages:** #{test_plan[:metadata][:testing_stage_count]}"
56
+ output << ""
57
+
58
+ output << "## Overview"
59
+ output << ""
60
+ output << test_plan[:overview]
61
+ output << ""
62
+
63
+ output << "## Target Users"
64
+ output << ""
65
+ test_plan[:target_users].each do |segment|
66
+ output << "### #{segment[:name]}"
67
+ output << ""
68
+ output << "**Description:** #{segment[:description]}"
69
+ output << ""
70
+ output << "**Characteristics:**"
71
+ segment[:characteristics].each do |char|
72
+ output << "- #{char}"
73
+ end
74
+ output << ""
75
+ output << "**Sample Size:** #{segment[:sample_size]}"
76
+ output << ""
77
+ end
78
+
79
+ output << "## Recruitment Criteria"
80
+ output << ""
81
+ output << "### Screener Questions"
82
+ output << ""
83
+ test_plan[:recruitment][:screener_questions].each_with_index do |q, idx|
84
+ output << "#{idx + 1}. **#{q[:question]}**"
85
+ output << " - Type: #{q[:type]}"
86
+ output << " - Qualifying Answer: #{q[:qualifying_answer]}" if q[:qualifying_answer]
87
+ output << ""
88
+ end
89
+
90
+ output << "### Recruitment Channels"
91
+ output << ""
92
+ test_plan[:recruitment][:channels].each do |channel|
93
+ output << "- #{channel}"
94
+ end
95
+ output << ""
96
+
97
+ output << "### Incentives"
98
+ output << ""
99
+ output << test_plan[:recruitment][:incentives]
100
+ output << ""
101
+
102
+ output << "## Testing Stages"
103
+ output << ""
104
+ test_plan[:testing_stages].each_with_index do |stage, idx|
105
+ output << "### Stage #{idx + 1}: #{stage[:name]}"
106
+ output << ""
107
+ output << "**Objective:** #{stage[:objective]}"
108
+ output << ""
109
+ output << "**Duration:** #{stage[:duration]}"
110
+ output << ""
111
+ output << "**Participants:** #{stage[:participants]}"
112
+ output << ""
113
+ output << "**Activities:**"
114
+ stage[:activities].each do |activity|
115
+ output << "- #{activity}"
116
+ end
117
+ output << ""
118
+ output << "**Success Criteria:**"
119
+ stage[:success_criteria].each do |criterion|
120
+ output << "- #{criterion}"
121
+ end
122
+ output << ""
123
+ end
124
+
125
+ output << "## Survey Questions"
126
+ output << ""
127
+ output << "### Likert Scale Questions (1-5: Strongly Disagree to Strongly Agree)"
128
+ output << ""
129
+ test_plan[:survey_questions][:likert].each_with_index do |q, idx|
130
+ output << "#{idx + 1}. #{q}"
131
+ end
132
+ output << ""
133
+
134
+ output << "### Multiple Choice Questions"
135
+ output << ""
136
+ test_plan[:survey_questions][:multiple_choice].each_with_index do |q, idx|
137
+ output << "#{idx + 1}. **#{q[:question]}**"
138
+ q[:options].each_with_index do |opt, oidx|
139
+ output << " #{("a".."z").to_a[oidx]}. #{opt}"
140
+ end
141
+ output << ""
142
+ end
143
+
144
+ output << "### Open-Ended Questions"
145
+ output << ""
146
+ test_plan[:survey_questions][:open_ended].each_with_index do |q, idx|
147
+ output << "#{idx + 1}. #{q}"
148
+ end
149
+ output << ""
150
+
151
+ output << "## Interview Script"
152
+ output << ""
153
+ output << "### Introduction"
154
+ output << ""
155
+ output << test_plan[:interview_script][:introduction]
156
+ output << ""
157
+
158
+ output << "### Main Questions"
159
+ output << ""
160
+ test_plan[:interview_script][:main_questions].each_with_index do |q, idx|
161
+ output << "#{idx + 1}. #{q[:question]}"
162
+ output << " - **Follow-ups:** #{q[:follow_ups].join(", ")}" if q[:follow_ups]&.any?
163
+ output << ""
164
+ end
165
+
166
+ output << "### Closing"
167
+ output << ""
168
+ output << test_plan[:interview_script][:closing]
169
+ output << ""
170
+
171
+ output << "## Success Metrics"
172
+ output << ""
173
+ test_plan[:success_metrics].each do |metric|
174
+ output << "- **#{metric[:name]}:** #{metric[:description]}"
175
+ output << " - Target: #{metric[:target]}"
176
+ output << ""
177
+ end
178
+
179
+ output << "## Timeline"
180
+ output << ""
181
+ test_plan[:timeline].each do |phase|
182
+ output << "- **#{phase[:phase]}:** #{phase[:duration]}"
183
+ end
184
+ output << ""
185
+
186
+ output.join("\n")
187
+ end
188
+
189
+ private
190
+
191
+ def generate_test_plan_with_ai(mvp_scope, target_users)
192
+ Aidp.log_debug("user_test_plan_generator", "generate_test_plan_with_ai")
193
+
194
+ prompt = build_test_plan_prompt(mvp_scope, target_users)
195
+
196
+ schema = {
197
+ type: "object",
198
+ properties: {
199
+ overview: {type: "string"},
200
+ target_users: {
201
+ type: "array",
202
+ items: {
203
+ type: "object",
204
+ properties: {
205
+ name: {type: "string"},
206
+ description: {type: "string"},
207
+ characteristics: {type: "array", items: {type: "string"}},
208
+ sample_size: {type: "string"}
209
+ }
210
+ }
211
+ },
212
+ recruitment: {
213
+ type: "object",
214
+ properties: {
215
+ screener_questions: {
216
+ type: "array",
217
+ items: {
218
+ type: "object",
219
+ properties: {
220
+ question: {type: "string"},
221
+ type: {type: "string"},
222
+ qualifying_answer: {type: "string"}
223
+ }
224
+ }
225
+ },
226
+ channels: {type: "array", items: {type: "string"}},
227
+ incentives: {type: "string"}
228
+ }
229
+ },
230
+ testing_stages: {
231
+ type: "array",
232
+ items: {
233
+ type: "object",
234
+ properties: {
235
+ name: {type: "string"},
236
+ objective: {type: "string"},
237
+ duration: {type: "string"},
238
+ participants: {type: "string"},
239
+ activities: {type: "array", items: {type: "string"}},
240
+ success_criteria: {type: "array", items: {type: "string"}}
241
+ }
242
+ }
243
+ },
244
+ survey_questions: {
245
+ type: "object",
246
+ properties: {
247
+ likert: {type: "array", items: {type: "string"}},
248
+ multiple_choice: {
249
+ type: "array",
250
+ items: {
251
+ type: "object",
252
+ properties: {
253
+ question: {type: "string"},
254
+ options: {type: "array", items: {type: "string"}}
255
+ }
256
+ }
257
+ },
258
+ open_ended: {type: "array", items: {type: "string"}}
259
+ }
260
+ },
261
+ interview_script: {
262
+ type: "object",
263
+ properties: {
264
+ introduction: {type: "string"},
265
+ main_questions: {
266
+ type: "array",
267
+ items: {
268
+ type: "object",
269
+ properties: {
270
+ question: {type: "string"},
271
+ follow_ups: {type: "array", items: {type: "string"}}
272
+ }
273
+ }
274
+ },
275
+ closing: {type: "string"}
276
+ }
277
+ },
278
+ success_metrics: {
279
+ type: "array",
280
+ items: {
281
+ type: "object",
282
+ properties: {
283
+ name: {type: "string"},
284
+ description: {type: "string"},
285
+ target: {type: "string"}
286
+ }
287
+ }
288
+ },
289
+ timeline: {
290
+ type: "array",
291
+ items: {
292
+ type: "object",
293
+ properties: {
294
+ phase: {type: "string"},
295
+ duration: {type: "string"}
296
+ }
297
+ }
298
+ }
299
+ },
300
+ required: ["overview", "target_users", "recruitment", "testing_stages", "survey_questions"]
301
+ }
302
+
303
+ decision = @ai_decision_engine.decide(
304
+ context: "user_test_plan_generation",
305
+ prompt: prompt,
306
+ data: {
307
+ mvp_scope: mvp_scope,
308
+ target_users: target_users
309
+ },
310
+ schema: schema
311
+ )
312
+
313
+ Aidp.log_debug("user_test_plan_generator", "ai_plan_generated",
314
+ stages: decision[:testing_stages]&.size || 0,
315
+ questions: decision[:survey_questions][:likert]&.size || 0)
316
+
317
+ decision
318
+ end
319
+
320
+ def build_test_plan_prompt(mvp_scope, target_users)
321
+ <<~PROMPT
322
+ Generate a comprehensive user testing plan for the following MVP scope.
323
+
324
+ MVP FEATURES:
325
+ #{mvp_scope[:mvp_features]&.map { |f| "- #{f[:name]}: #{f[:description]}" }&.join("\n") || "No features provided"}
326
+
327
+ TARGET USERS:
328
+ #{target_users || mvp_scope.dig(:metadata, :user_priorities)&.find { |p| p.start_with?("Target users:") } || "General users"}
329
+
330
+ TASK:
331
+ Create a detailed user testing plan that includes:
332
+
333
+ 1. OVERVIEW
334
+ - Brief description of testing goals
335
+ - Why user testing is important for this MVP
336
+
337
+ 2. TARGET USERS (segments)
338
+ - Define 2-3 user segments to test
339
+ - For each: name, description, characteristics, recommended sample size
340
+
341
+ 3. RECRUITMENT
342
+ - Screener questions to qualify participants
343
+ - Recruitment channels (where to find users)
344
+ - Suggested incentives
345
+
346
+ 4. TESTING STAGES
347
+ - Define 3-4 testing stages (e.g., Alpha, Beta, Launch)
348
+ - For each stage: objective, duration, number of participants, activities, success criteria
349
+
350
+ 5. SURVEY QUESTIONS
351
+ - 5-7 Likert scale questions (1-5 scale)
352
+ - 3-5 multiple choice questions with options
353
+ - 3-5 open-ended questions
354
+
355
+ 6. INTERVIEW SCRIPT
356
+ - Introduction text
357
+ - 5-7 main interview questions with follow-ups
358
+ - Closing text
359
+
360
+ 7. SUCCESS METRICS
361
+ - Quantitative and qualitative metrics
362
+ - Target values for each metric
363
+
364
+ 8. TIMELINE
365
+ - Estimated duration for each phase (recruitment, testing, analysis)
366
+
367
+ Make questions specific to the MVP features. Focus on usability, value proposition, and user satisfaction.
368
+ PROMPT
369
+ end
370
+ end
371
+ end
372
+ end
373
+ end
@@ -0,0 +1,259 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../logger"
4
+
5
+ module Aidp
6
+ module Planning
7
+ module Generators
8
+ # Generates Work Breakdown Structure (WBS) with phase-based decomposition
9
+ # Breaks down projects into phases, tasks, and subtasks with dependencies
10
+ class WBSGenerator
11
+ DEFAULT_PHASES = [
12
+ "Requirements",
13
+ "Design",
14
+ "Implementation",
15
+ "Testing",
16
+ "Deployment"
17
+ ].freeze
18
+
19
+ def initialize(phases: DEFAULT_PHASES, config: nil)
20
+ @phases = phases
21
+ @config = config || Aidp::Config.waterfall_config
22
+ end
23
+
24
+ # Generate WBS from PRD and technical design
25
+ # @param prd [Hash] Parsed PRD document
26
+ # @param tech_design [Hash] Parsed technical design document
27
+ # @return [Hash] WBS structure with phases and tasks
28
+ def generate(prd:, tech_design: nil)
29
+ Aidp.log_debug("wbs_generator", "generate", has_prd: !prd.nil?, has_design: !tech_design.nil?)
30
+
31
+ wbs = {
32
+ phases: build_phases(prd, tech_design),
33
+ metadata: {
34
+ generated_at: Time.now.iso8601,
35
+ phase_count: @phases.size,
36
+ total_tasks: 0
37
+ }
38
+ }
39
+
40
+ wbs[:metadata][:total_tasks] = count_total_tasks(wbs[:phases])
41
+
42
+ Aidp.log_debug("wbs_generator", "generated", total_tasks: wbs[:metadata][:total_tasks])
43
+ wbs
44
+ end
45
+
46
+ # Format WBS as markdown
47
+ # @param wbs [Hash] WBS structure
48
+ # @return [String] Markdown formatted WBS
49
+ def format_as_markdown(wbs)
50
+ Aidp.log_debug("wbs_generator", "format_as_markdown")
51
+
52
+ output = ["# Work Breakdown Structure", ""]
53
+ output << "Generated: #{wbs[:metadata][:generated_at]}"
54
+ output << "Total Phases: #{wbs[:metadata][:phase_count]}"
55
+ output << "Total Tasks: #{wbs[:metadata][:total_tasks]}"
56
+ output << ""
57
+
58
+ wbs[:phases].each do |phase|
59
+ output << "## Phase: #{phase[:name]}"
60
+ output << ""
61
+ output << phase[:description] if phase[:description]
62
+ output << ""
63
+
64
+ phase[:tasks].each_with_index do |task, idx|
65
+ output << "### #{idx + 1}. #{task[:name]}"
66
+ output << ""
67
+ output << task[:description] if task[:description]
68
+ output << ""
69
+
70
+ if task[:subtasks]&.any?
71
+ task[:subtasks].each do |subtask|
72
+ output << " - #{subtask[:name]}"
73
+ end
74
+ output << ""
75
+ end
76
+
77
+ if task[:dependencies]&.any?
78
+ output << "**Dependencies:** #{task[:dependencies].join(", ")}"
79
+ output << ""
80
+ end
81
+
82
+ if task[:effort]
83
+ output << "**Effort:** #{task[:effort]}"
84
+ output << ""
85
+ end
86
+ end
87
+ end
88
+
89
+ output.join("\n")
90
+ end
91
+
92
+ private
93
+
94
+ # Build phase structure from documents
95
+ def build_phases(prd, tech_design)
96
+ Aidp.log_debug("wbs_generator", "build_phases", phase_count: @phases.size)
97
+
98
+ @phases.map do |phase_name|
99
+ {
100
+ name: phase_name,
101
+ description: phase_description(phase_name),
102
+ tasks: build_phase_tasks(phase_name, prd, tech_design)
103
+ }
104
+ end
105
+ end
106
+
107
+ # Get description for a phase
108
+ def phase_description(phase_name)
109
+ descriptions = {
110
+ "Requirements" => "Gather and document all requirements",
111
+ "Design" => "Design system architecture and components",
112
+ "Implementation" => "Implement features and functionality",
113
+ "Testing" => "Test all features and fix bugs",
114
+ "Deployment" => "Deploy to production and monitor"
115
+ }
116
+
117
+ descriptions[phase_name] || "Complete #{phase_name} activities"
118
+ end
119
+
120
+ # Build tasks for a specific phase
121
+ # This is a simplified version - in production, would use AI to extract tasks
122
+ def build_phase_tasks(phase_name, prd, tech_design)
123
+ case phase_name
124
+ when "Requirements"
125
+ requirements_tasks(prd)
126
+ when "Design"
127
+ design_tasks(tech_design)
128
+ when "Implementation"
129
+ implementation_tasks(prd, tech_design)
130
+ when "Testing"
131
+ testing_tasks(prd)
132
+ when "Deployment"
133
+ deployment_tasks
134
+ else
135
+ []
136
+ end
137
+ end
138
+
139
+ def requirements_tasks(prd)
140
+ [
141
+ {
142
+ name: "Document functional requirements",
143
+ description: "Extract and document all functional requirements from PRD",
144
+ effort: "3 story points",
145
+ dependencies: []
146
+ },
147
+ {
148
+ name: "Document non-functional requirements",
149
+ description: "Extract and document NFRs including performance, security, scalability",
150
+ effort: "2 story points",
151
+ dependencies: []
152
+ }
153
+ ]
154
+ end
155
+
156
+ def design_tasks(tech_design)
157
+ [
158
+ {
159
+ name: "Design system architecture",
160
+ description: "Create high-level architecture diagram and component breakdown",
161
+ effort: "5 story points",
162
+ dependencies: []
163
+ },
164
+ {
165
+ name: "Design data models",
166
+ description: "Define data models and database schema",
167
+ effort: "3 story points",
168
+ dependencies: ["Design system architecture"]
169
+ },
170
+ {
171
+ name: "Design API interfaces",
172
+ description: "Define API endpoints and contracts",
173
+ effort: "3 story points",
174
+ dependencies: ["Design system architecture"]
175
+ }
176
+ ]
177
+ end
178
+
179
+ def implementation_tasks(prd, tech_design)
180
+ [
181
+ {
182
+ name: "Set up project infrastructure",
183
+ description: "Initialize project, configure build tools, set up CI/CD",
184
+ effort: "3 story points",
185
+ dependencies: []
186
+ },
187
+ {
188
+ name: "Implement core features",
189
+ description: "Implement main functionality per PRD",
190
+ effort: "13 story points",
191
+ dependencies: ["Set up project infrastructure"],
192
+ subtasks: [
193
+ {name: "Feature module 1"},
194
+ {name: "Feature module 2"},
195
+ {name: "Feature module 3"}
196
+ ]
197
+ },
198
+ {
199
+ name: "Implement API layer",
200
+ description: "Build API endpoints per design",
201
+ effort: "8 story points",
202
+ dependencies: ["Implement core features"]
203
+ }
204
+ ]
205
+ end
206
+
207
+ def testing_tasks(prd)
208
+ [
209
+ {
210
+ name: "Write unit tests",
211
+ description: "Achieve 85%+ code coverage with unit tests",
212
+ effort: "8 story points",
213
+ dependencies: []
214
+ },
215
+ {
216
+ name: "Write integration tests",
217
+ description: "Test component integration and workflows",
218
+ effort: "5 story points",
219
+ dependencies: ["Write unit tests"]
220
+ },
221
+ {
222
+ name: "Perform UAT",
223
+ description: "User acceptance testing against PRD success criteria",
224
+ effort: "3 story points",
225
+ dependencies: ["Write integration tests"]
226
+ }
227
+ ]
228
+ end
229
+
230
+ def deployment_tasks
231
+ [
232
+ {
233
+ name: "Set up production environment",
234
+ description: "Configure production infrastructure and monitoring",
235
+ effort: "3 story points",
236
+ dependencies: []
237
+ },
238
+ {
239
+ name: "Deploy to production",
240
+ description: "Execute deployment and verify health",
241
+ effort: "2 story points",
242
+ dependencies: ["Set up production environment"]
243
+ },
244
+ {
245
+ name: "Monitor and stabilize",
246
+ description: "Monitor system performance and fix production issues",
247
+ effort: "3 story points",
248
+ dependencies: ["Deploy to production"]
249
+ }
250
+ ]
251
+ end
252
+
253
+ def count_total_tasks(phases)
254
+ phases.sum { |phase| phase[:tasks].size }
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end