From 507e6f10a7876ea376f61baf7ca2df5a09e4cd6d Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 18 Mar 2026 12:00:57 +0100 Subject: [PATCH] feat: tag forked datatables with nonDiffable and forkedFrom Co-Authored-By: Claude Opus 4.5 --- .../windmill-api-workspaces/src/workspaces.rs | 23 +++++++++++++++++++ backend/windmill-common/src/workspaces.rs | 5 ++++ 2 files changed, 28 insertions(+) diff --git a/backend/windmill-api-workspaces/src/workspaces.rs b/backend/windmill-api-workspaces/src/workspaces.rs index 5a49fd1501..be04cee22b 100644 --- a/backend/windmill-api-workspaces/src/workspaces.rs +++ b/backend/windmill-api-workspaces/src/workspaces.rs @@ -1608,6 +1608,8 @@ async fn fork_datatable( resource_type: DataTableCatalogResourceType::Instance, resource_path: new_dbname.clone(), }, + non_diffable: true, + forked_from: Some(original_dbname.clone()), }; let datatable_value: serde_json::Value = serde_json::to_value(&new_datatable).map_err(|err| Error::internal_err(err.to_string()))?; @@ -1710,6 +1712,27 @@ async fn fork_resource_datatable( .execute(db) .await?; + // Tag the datatable config as non_diffable with forked_from info + let forked_from_value = format!("$res:{}", resource_path); + let tag_json = serde_json::json!({ + "nonDiffable": true, + "forkedFrom": forked_from_value + }); + sqlx::query!( + r#"UPDATE workspace_settings + SET datatable = jsonb_set( + COALESCE(datatable, '{"datatables":{}}'::jsonb), + ARRAY['datatables', $1], + COALESCE(datatable->'datatables'->$1, '{}'::jsonb) || $2 + ) + WHERE workspace_id = $3"#, + datatable_name, + tag_json, + target_workspace_id + ) + .execute(db) + .await?; + tracing::info!( "Forked resource datatable '{}': created database '{}' from '{}'", datatable_name, diff --git a/backend/windmill-common/src/workspaces.rs b/backend/windmill-common/src/workspaces.rs index a1c683d28b..61952fc9ac 100644 --- a/backend/windmill-common/src/workspaces.rs +++ b/backend/windmill-common/src/workspaces.rs @@ -404,8 +404,13 @@ impl Default for DataTableForkBehavior { } #[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "camelCase")] pub struct DataTable { pub database: DataTableDatabase, + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub non_diffable: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub forked_from: Option, } #[derive(Deserialize, Serialize, Debug)]