From eff0d844ca6e35bfbc2d5fdaa2d2f92177611f2e Mon Sep 17 00:00:00 2001 From: soryu Date: Thu, 15 Jan 2026 00:23:44 +0000 Subject: Contract type system --- makima/src/db/models.rs | 78 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) (limited to 'makima/src/db/models.rs') diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index e16c43f..ca12eb2 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -991,6 +991,50 @@ pub struct MergeCompleteCheckResponse { // Contract Types // ============================================================================= +/// Contract type determines the workflow and required documents +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "lowercase")] +pub enum ContractType { + /// Simple Plan -> Execute workflow (default) + /// - Plan phase: requires a "Plan" document + /// - Execute phase: no documents, fulfills the plan + Simple, + /// Specification-based development with TDD + /// - Research: gather requirements and context + /// - Specify: write specifications and test cases + /// - Plan: create implementation plan + /// - Execute: implement according to specs + /// - Review: verify against specifications + Specification, +} + +impl Default for ContractType { + fn default() -> Self { + ContractType::Simple + } +} + +impl std::fmt::Display for ContractType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ContractType::Simple => write!(f, "simple"), + ContractType::Specification => write!(f, "specification"), + } + } +} + +impl std::str::FromStr for ContractType { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "simple" => Ok(ContractType::Simple), + "specification" => Ok(ContractType::Specification), + _ => Err(format!("Unknown contract type: {}", s)), + } + } +} + /// Contract phase for workflow progression #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "lowercase")] @@ -1143,6 +1187,8 @@ pub struct Contract { pub owner_id: Uuid, pub name: String, pub description: Option, + /// Contract type: "simple" or "specification" + pub contract_type: String, pub phase: String, pub status: String, /// The long-running supervisor task that orchestrates this contract @@ -1154,6 +1200,11 @@ pub struct Contract { } impl Contract { + /// Parse contract_type string to ContractType enum + pub fn contract_type_enum(&self) -> Result { + self.contract_type.parse() + } + /// Parse phase string to ContractPhase enum pub fn phase_enum(&self) -> Result { self.phase.parse() @@ -1163,6 +1214,21 @@ impl Contract { pub fn status_enum(&self) -> Result { self.status.parse() } + + /// Get valid phases for this contract type + pub fn valid_phases(&self) -> Vec { + match self.contract_type.as_str() { + "simple" => vec![ContractPhase::Plan, ContractPhase::Execute], + "specification" => vec![ + ContractPhase::Research, + ContractPhase::Specify, + ContractPhase::Plan, + ContractPhase::Execute, + ContractPhase::Review, + ], + _ => vec![ContractPhase::Plan, ContractPhase::Execute], // Default to simple + } + } } /// Contract repository record from the database @@ -1200,6 +1266,8 @@ pub struct ContractSummary { pub id: Uuid, pub name: String, pub description: Option, + /// Contract type: "simple" or "specification" + pub contract_type: String, pub phase: String, pub status: String, pub file_count: i64, @@ -1236,8 +1304,14 @@ pub struct CreateContractRequest { pub name: String, /// Optional description pub description: Option, - /// Initial phase to start in (defaults to "research") - /// Valid values: "research", "specify", "plan", "execute", "review" + /// Contract type: "simple" (default) or "specification" + /// - simple: Plan -> Execute workflow + /// - specification: Research -> Specify -> Plan -> Execute -> Review + #[serde(default)] + pub contract_type: Option, + /// Initial phase to start in (defaults based on contract_type) + /// - simple: defaults to "plan" + /// - specification: defaults to "research" #[serde(default)] pub initial_phase: Option, } -- cgit v1.2.3