From 0302b4596e14210884df5d645df9a179d8f0c1c6 Mon Sep 17 00:00:00 2001 From: soryu Date: Thu, 5 Feb 2026 00:48:38 +0000 Subject: Add multi-repository support for chains Chains can now have multiple repositories attached, with one marked as primary. Repositories are used by contracts created from chain definitions. Backend changes: - Add chain_repositories table migration - Add ChainRepository model with CRUD operations - Add API endpoints for listing, adding, deleting repositories - Add endpoint to set a repository as primary - Update Chain and ChainEditorData models to use repositories - Update chain parser to support repositories in YAML format - Remove deprecated repository_url/local_path from Chain Frontend changes: - Add ChainRepository interface and API functions - Add repository section to ChainEditor showing attached repos - Add modal for adding new repositories (remote or local) - Support setting primary repository and removing repositories Co-Authored-By: Claude Opus 4.5 --- makima/src/db/models.rs | 64 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 10 deletions(-) (limited to 'makima/src/db/models.rs') diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 4e569ec..30e1603 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -2652,16 +2652,40 @@ pub struct Chain { pub loop_current_iteration: Option, /// Progress check prompt/criteria for evaluating loop completion pub loop_progress_check: Option, - /// Repository URL for contracts in this chain (optional) - pub repository_url: Option, - /// Local path for contracts in this chain (optional) - pub local_path: Option, /// Version for optimistic locking pub version: i32, pub created_at: DateTime, pub updated_at: DateTime, } +/// Chain repository record from the database +#[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ChainRepository { + pub id: Uuid, + pub chain_id: Uuid, + pub name: String, + pub repository_url: Option, + pub local_path: Option, + pub source_type: String, + pub status: String, + pub is_primary: bool, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +impl ChainRepository { + /// Parse source_type string to RepositorySourceType enum + pub fn source_type_enum(&self) -> Result { + self.source_type.parse() + } + + /// Parse status string to RepositoryStatus enum + pub fn status_enum(&self) -> Result { + self.status.parse() + } +} + impl Chain { /// Parse status string to ChainStatus enum pub fn status_enum(&self) -> Result { @@ -2724,6 +2748,7 @@ pub struct ChainWithContracts { #[serde(flatten)] pub chain: Chain, pub contracts: Vec, + pub repositories: Vec, } /// Contract detail within a chain (includes contract info + chain link info) @@ -2790,10 +2815,8 @@ pub struct CreateChainRequest { pub name: String, /// Optional description pub description: Option, - /// Repository URL for contracts in this chain - pub repository_url: Option, - /// Local path for contracts in this chain - pub local_path: Option, + /// Repositories for this chain + pub repositories: Option>, /// Enable loop mode for iterative execution #[serde(default)] pub loop_enabled: Option, @@ -2805,6 +2828,28 @@ pub struct CreateChainRequest { pub contracts: Option>, } +/// Request to add a repository to a chain +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct AddChainRepositoryRequest { + /// Display name for the repository + pub name: String, + /// Remote repository URL (for remote repos) + pub repository_url: Option, + /// Local filesystem path (for local repos) + pub local_path: Option, + /// Source type: remote, local, or managed + #[serde(default = "default_source_type")] + pub source_type: String, + /// Whether this is the primary repository + #[serde(default)] + pub is_primary: bool, +} + +fn default_source_type() -> String { + "remote".to_string() +} + /// Request to create a contract within a chain #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] @@ -2934,8 +2979,7 @@ pub struct ChainEditorData { pub id: Option, pub name: String, pub description: Option, - pub repository_url: Option, - pub local_path: Option, + pub repositories: Vec, pub loop_enabled: bool, pub loop_max_iterations: Option, pub loop_progress_check: Option, -- cgit v1.2.3