diff options
Diffstat (limited to 'makima/src/server/handlers/contract_chat.rs')
| -rw-r--r-- | makima/src/server/handlers/contract_chat.rs | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/makima/src/server/handlers/contract_chat.rs b/makima/src/server/handlers/contract_chat.rs index 101b257..29ec620 100644 --- a/makima/src/server/handlers/contract_chat.rs +++ b/makima/src/server/handlers/contract_chat.rs @@ -1689,7 +1689,7 @@ async fn handle_contract_request( } } - ContractToolRequest::AdvancePhase { new_phase } => { + ContractToolRequest::AdvancePhase { new_phase, confirmed, feedback } => { let contract = match repository::get_contract_for_owner(pool, contract_id, owner_id).await { Ok(Some(c)) => c, Ok(None) => { @@ -1723,7 +1723,88 @@ async fn handle_contract_request( }; } - // Update phase + // Check if phase_guard is enabled + if contract.phase_guard { + // If user provided feedback, return it for the task to address + if let Some(ref user_feedback) = feedback { + return ContractRequestResult { + success: true, + message: format!( + "Phase transition to '{}' requires changes. User feedback: {}", + new_phase, user_feedback + ), + data: Some(json!({ + "status": "changes_requested", + "currentPhase": current_phase, + "requestedPhase": new_phase, + "feedback": user_feedback, + "action": "Address the user feedback and try again when ready" + })), + }; + } + + // If not confirmed, return pending confirmation with phase deliverables + if !confirmed { + // Get files created in this phase + let phase_files = match repository::list_files_in_contract(pool, contract_id, owner_id).await { + Ok(files) => files + .into_iter() + .filter(|f| f.contract_phase.as_deref() == Some(current_phase)) + .map(|f| json!({ + "id": f.id, + "name": f.name, + "description": f.description + })) + .collect::<Vec<_>>(), + Err(_) => Vec::new(), + }; + + // Get tasks completed in this contract + let phase_tasks = match repository::list_tasks_in_contract(pool, contract_id, owner_id).await { + Ok(tasks) => tasks + .into_iter() + .filter(|t| t.status == "done" || t.status == "completed") + .map(|t| json!({ + "id": t.id, + "name": t.name, + "status": t.status + })) + .collect::<Vec<_>>(), + Err(_) => Vec::new(), + }; + + // Build deliverables summary + let deliverables_summary = format!( + "Phase '{}' deliverables: {} files created, {} tasks completed.", + current_phase, + phase_files.len(), + phase_tasks.len() + ); + + let transition_id = uuid::Uuid::new_v4().to_string(); + + return ContractRequestResult { + success: true, + message: format!( + "Phase transition to '{}' requires user confirmation. Review the deliverables and call advance_phase again with confirmed=true to proceed, or provide feedback to request changes.", + new_phase + ), + data: Some(json!({ + "status": "pending_confirmation", + "transitionId": transition_id, + "currentPhase": current_phase, + "nextPhase": new_phase, + "deliverablesSummary": deliverables_summary, + "phaseFiles": phase_files, + "phaseTasks": phase_tasks, + "requiresConfirmation": true, + "instructions": "To proceed: call advance_phase with confirmed=true. To request changes: call advance_phase with feedback='your feedback here'" + })), + }; + } + } + + // Update phase (either phase_guard is disabled, or user confirmed) match repository::change_contract_phase_for_owner(pool, contract_id, owner_id, &new_phase).await { Ok(Some(updated)) => { // Get deliverables for the new phase @@ -1748,6 +1829,7 @@ async fn handle_contract_request( current_phase, new_phase, deliverables.guidance ), data: Some(json!({ + "status": "advanced", "previousPhase": current_phase, "newPhase": updated.phase, "phaseGuidance": deliverables.guidance, @@ -2377,6 +2459,7 @@ async fn handle_contract_request( contract_type: Some("specification".to_string()), initial_phase: Some("research".to_string()), autonomous_loop: None, + phase_guard: None, }; let contract = match repository::create_contract_for_owner(pool, owner_id, contract_req).await { |
