diff options
| author | soryu <soryu@soryu.co> | 2026-01-25 03:53:55 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-25 03:53:55 +0000 |
| commit | c908854e7e3571c99cce9f46497ce5337ea0aed1 (patch) | |
| tree | 3d35137a452c562059ecd8c759393b90937df70c /makima/src | |
| parent | 03ab90836707954277597dc21fd8035019d8e221 (diff) | |
| download | soryu-c908854e7e3571c99cce9f46497ce5337ea0aed1.tar.gz soryu-c908854e7e3571c99cce9f46497ce5337ea0aed1.zip | |
Update create contract page to use dynamic templates (#29)
* feat: Add contract type templates API endpoint
Add a new API endpoint to provide contract type templates (workflow
definitions) separate from file templates. This enables the create
contract page to dynamically show available contract types.
Changes:
- Add ContractTypeTemplate struct in templates.rs with id, name,
description, phases, default_phase, and is_builtin fields
- Add built-in contract types: 'simple' (plan/execute) and
'specification' (research/specify/plan/execute/review)
- Add GET /api/v1/contract-types endpoint returning all contract types
- Add frontend ContractTypeTemplate interface and listContractTypes()
API function
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: Update create contract modal to use dynamic templates
- Add ContractTypeTemplate interface and listContractTypes API function
to frontend api.ts
- Add GET /api/v1/contract-types backend endpoint that returns built-in
contract types (simple, specification) with their phases and defaults
- Update create contract modal to fetch contract types dynamically when
opened, with loading state and fallback to hardcoded types on error
- Dynamically render contract type selection buttons from fetched types
- Update phase dropdown to use phases from selected contract type
- Replace static getValidPhases/getDefaultPhase calls with dynamic data
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'makima/src')
| -rw-r--r-- | makima/src/llm/templates.rs | 65 | ||||
| -rw-r--r-- | makima/src/server/handlers/templates.rs | 101 | ||||
| -rw-r--r-- | makima/src/server/mod.rs | 2 |
3 files changed, 168 insertions, 0 deletions
diff --git a/makima/src/llm/templates.rs b/makima/src/llm/templates.rs index 18ef46d..7a5bd38 100644 --- a/makima/src/llm/templates.rs +++ b/makima/src/llm/templates.rs @@ -8,6 +8,71 @@ use utoipa::ToSchema; use crate::db::models::BodyElement; +// ============================================================================= +// Contract Type Templates (Workflow Definitions) +// ============================================================================= + +/// A contract type template defining a workflow +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ContractTypeTemplate { + /// Unique identifier (e.g., 'simple', 'specification', 'feature-development') + pub id: String, + /// Display name + pub name: String, + /// What this contract type is for + pub description: String, + /// Ordered list of phases in the workflow + pub phases: Vec<String>, + /// Starting phase + pub default_phase: String, + /// True for built-in types ('simple', 'specification') + pub is_builtin: bool, +} + +/// Get all available contract type templates +pub fn all_contract_types() -> Vec<ContractTypeTemplate> { + vec![ + simple_contract_type(), + specification_contract_type(), + ] +} + +/// Simple contract type with basic plan/execute workflow +fn simple_contract_type() -> ContractTypeTemplate { + ContractTypeTemplate { + id: "simple".to_string(), + name: "Simple".to_string(), + description: "A basic workflow for straightforward tasks with planning and execution phases." + .to_string(), + phases: vec!["plan".to_string(), "execute".to_string()], + default_phase: "plan".to_string(), + is_builtin: true, + } +} + +/// Specification contract type with full research-to-review workflow +fn specification_contract_type() -> ContractTypeTemplate { + ContractTypeTemplate { + id: "specification".to_string(), + name: "Specification".to_string(), + description: "A comprehensive workflow for complex projects requiring research, specification, planning, execution, and review.".to_string(), + phases: vec![ + "research".to_string(), + "specify".to_string(), + "plan".to_string(), + "execute".to_string(), + "review".to_string(), + ], + default_phase: "research".to_string(), + is_builtin: true, + } +} + +// ============================================================================= +// File Templates +// ============================================================================= + /// A file template with suggested structure #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct FileTemplate { diff --git a/makima/src/server/handlers/templates.rs b/makima/src/server/handlers/templates.rs index 868d5b4..5cad44f 100644 --- a/makima/src/server/handlers/templates.rs +++ b/makima/src/server/handlers/templates.rs @@ -5,6 +5,77 @@ use serde::{Deserialize, Serialize}; use utoipa::ToSchema; use crate::llm::templates; +use crate::llm::templates::ContractTypeTemplate; + +// ============================================================================= +// Contract Type Templates +// ============================================================================= + +/// Contract type template for API response +#[derive(Debug, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ContractTypeTemplate { + /// Template identifier (e.g., "simple", "specification") + pub id: String, + /// Display name + pub name: String, + /// Description of the contract type workflow + pub description: String, + /// Ordered list of phases for this contract type + pub phases: Vec<String>, + /// Default starting phase + pub default_phase: String, + /// Whether this is a built-in type (always available) + pub is_builtin: bool, +} + +/// Response for listing contract types +#[derive(Debug, Serialize, ToSchema)] +pub struct ListContractTypesResponse { + pub types: Vec<ContractTypeTemplate>, +} + +/// List available contract type templates +#[utoipa::path( + get, + path = "/api/v1/contract-types", + responses( + (status = 200, description = "Contract types retrieved successfully", body = ListContractTypesResponse) + ), + tag = "contract-types" +)] +pub async fn list_contract_types() -> impl IntoResponse { + let types = vec![ + ContractTypeTemplate { + id: "simple".to_string(), + name: "Simple".to_string(), + description: "Plan \u{2192} Execute: Simple workflow with a plan document".to_string(), + phases: vec!["plan".to_string(), "execute".to_string()], + default_phase: "plan".to_string(), + is_builtin: true, + }, + ContractTypeTemplate { + id: "specification".to_string(), + name: "Specification".to_string(), + description: "Research \u{2192} Specify \u{2192} Plan \u{2192} Execute \u{2192} Review: Full specification-driven development with TDD".to_string(), + phases: vec![ + "research".to_string(), + "specify".to_string(), + "plan".to_string(), + "execute".to_string(), + "review".to_string(), + ], + default_phase: "research".to_string(), + is_builtin: true, + }, + ]; + + ( + StatusCode::OK, + Json(ListContractTypesResponse { types }), + ) + .into_response() +} /// Query parameters for listing templates #[derive(Debug, Deserialize, ToSchema)] @@ -105,3 +176,33 @@ pub async fn get_template( .into_response(), } } + +// ============================================================================= +// Contract Type Templates (Workflow Definitions) +// ============================================================================= + +/// Response for listing contract types +#[derive(Debug, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ListContractTypesResponse { + pub contract_types: Vec<ContractTypeTemplate>, +} + +/// List all available contract type templates +#[utoipa::path( + get, + path = "/api/v1/contract-types", + responses( + (status = 200, description = "Contract types retrieved successfully", body = ListContractTypesResponse) + ), + tag = "templates" +)] +pub async fn list_contract_types() -> impl IntoResponse { + let contract_types = templates::all_contract_types(); + + ( + StatusCode::OK, + Json(ListContractTypesResponse { contract_types }), + ) + .into_response() +} diff --git a/makima/src/server/mod.rs b/makima/src/server/mod.rs index de20569..75f64c6 100644 --- a/makima/src/server/mod.rs +++ b/makima/src/server/mod.rs @@ -208,6 +208,8 @@ pub fn make_router(state: SharedState) -> Router { // Template endpoints .route("/templates", get(templates::list_templates)) .route("/templates/{id}", get(templates::get_template)) + // Contract type templates (workflow definitions) + .route("/contract-types", get(templates::list_contract_types)) // Settings endpoints .route( "/settings/repository-history", |
