diff options
| author | soryu <soryu@soryu.co> | 2026-01-15 00:23:44 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-01-15 00:23:47 +0000 |
| commit | eff0d844ca6e35bfbc2d5fdaa2d2f92177611f2e (patch) | |
| tree | 90d87d6daf9dd78c31e4b816bb1d282db73821dd /makima/src/db/repository.rs | |
| parent | 87044a747b47bd83249d61a45842c7f7b2eae56d (diff) | |
| download | soryu-eff0d844ca6e35bfbc2d5fdaa2d2f92177611f2e.tar.gz soryu-eff0d844ca6e35bfbc2d5fdaa2d2f92177611f2e.zip | |
Contract type system
Diffstat (limited to 'makima/src/db/repository.rs')
| -rw-r--r-- | makima/src/db/repository.rs | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index 3b911c2..7933f1e 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -2019,29 +2019,50 @@ pub async fn create_contract_for_owner( owner_id: Uuid, req: CreateContractRequest, ) -> Result<Contract, sqlx::Error> { - // Use provided initial_phase or default to "research" - let phase = req.initial_phase.as_deref().unwrap_or("research"); + // Default contract type is "simple" + let contract_type = req.contract_type.as_deref().unwrap_or("simple"); - // Validate the phase - let valid_phases = ["research", "specify", "plan", "execute", "review"]; + // Validate contract type + let valid_types = ["simple", "specification"]; + if !valid_types.contains(&contract_type) { + return Err(sqlx::Error::Protocol(format!( + "Invalid contract_type '{}'. Must be one of: {}", + contract_type, + valid_types.join(", ") + ))); + } + + // Determine valid phases based on contract type + let (valid_phases, default_phase): (&[&str], &str) = match contract_type { + "simple" => (&["plan", "execute"], "plan"), + "specification" => (&["research", "specify", "plan", "execute", "review"], "research"), + _ => (&["plan", "execute"], "plan"), + }; + + // Use provided initial_phase or default based on contract type + let phase = req.initial_phase.as_deref().unwrap_or(default_phase); + + // Validate the phase is valid for this contract type if !valid_phases.contains(&phase) { return Err(sqlx::Error::Protocol(format!( - "Invalid initial_phase '{}'. Must be one of: {}", + "Invalid initial_phase '{}' for contract type '{}'. Must be one of: {}", phase, + contract_type, valid_phases.join(", ") ))); } sqlx::query_as::<_, Contract>( r#" - INSERT INTO contracts (owner_id, name, description, phase) - VALUES ($1, $2, $3, $4) + INSERT INTO contracts (owner_id, name, description, contract_type, phase) + VALUES ($1, $2, $3, $4, $5) RETURNING * "#, ) .bind(owner_id) .bind(&req.name) .bind(&req.description) + .bind(contract_type) .bind(phase) .fetch_one(pool) .await @@ -2074,7 +2095,7 @@ pub async fn list_contracts_for_owner( sqlx::query_as::<_, ContractSummary>( r#" SELECT - c.id, c.name, c.description, c.phase, c.status, + c.id, c.name, c.description, c.contract_type, c.phase, c.status, c.version, c.created_at, (SELECT COUNT(*) FROM files WHERE contract_id = c.id) as file_count, (SELECT COUNT(*) FROM tasks WHERE contract_id = c.id) as task_count, @@ -2098,7 +2119,7 @@ pub async fn get_contract_summary_for_owner( sqlx::query_as::<_, ContractSummary>( r#" SELECT - c.id, c.name, c.description, c.phase, c.status, + c.id, c.name, c.description, c.contract_type, c.phase, c.status, c.version, c.created_at, (SELECT COUNT(*) FROM files WHERE contract_id = c.id) as file_count, (SELECT COUNT(*) FROM tasks WHERE contract_id = c.id) as task_count, |
