From 1314450f6e22cb74175dc4387bd50d15ae70b4b2 Mon Sep 17 00:00:00 2001
From: "hotdata-automation[bot]"
<267177015+hotdata-automation[bot]@users.noreply.github.com>
Date: Wed, 23 Sep 2026 10:39:49 +0000
Subject: [PATCH] feat(databases): add description field to fork lineage
---
CHANGELOG.md | 1 +
docs/DatabasesApi.md | 2 +-
docs/ForkDatabaseRequest.md | 1 +
docs/ForkedFromInfo.md | 1 +
docs/LineageAncestorInfo.md | 1 +
docs/LineageForkInfo.md | 1 +
src/apis/databases_api.rs | 2 +-
src/models/fork_database_request.rs | 9 +++++++++
src/models/forked_from_info.rs | 9 +++++++++
src/models/lineage_ancestor_info.rs | 9 +++++++++
src/models/lineage_fork_info.rs | 9 +++++++++
11 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e8e3ce..ff3c922 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
+- feat(databases): add description field to fork lineage
- chore(databases): simplify fork error description
## [0.18.1] - 2026-09-18
diff --git a/docs/DatabasesApi.md b/docs/DatabasesApi.md
index cd3148a..8efd84e 100644
--- a/docs/DatabasesApi.md
+++ b/docs/DatabasesApi.md
@@ -303,7 +303,7 @@ Name | Type | Description | Required | Notes
> models::CreateDatabaseResponse fork_database(database_id, fork_database_request)
Fork database
-Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
+Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `description` records why the fork is being taken; it is returned with the fork's `forked_from` and in the lineage of both databases. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
### Parameters
diff --git a/docs/ForkDatabaseRequest.md b/docs/ForkDatabaseRequest.md
index 0b1b556..0446708 100644
--- a/docs/ForkDatabaseRequest.md
+++ b/docs/ForkDatabaseRequest.md
@@ -4,6 +4,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
+**description** | Option<**String**> | Optional note saying why the fork is being taken — for example \"backfill test before the March migration\". It is kept with the record of the fork and returned wherever that record appears: `forked_from` on the fork, and the fork's entry in both databases' lineage. Surrounding whitespace is trimmed, and an empty value is treated as absent. At most 4096 bytes; line breaks and tabs are allowed, other control characters are not. | [optional]
**expires_at** | Option<**String**> | When the fork expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"` or `\"7d\"`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. | [optional]
**name** | Option<**String**> | Optional display label for the fork. When omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. A source with no usable label of its own gives a fork named from that ID alone. | [optional]
diff --git a/docs/ForkedFromInfo.md b/docs/ForkedFromInfo.md
index 7f7bbd1..918dd85 100644
--- a/docs/ForkedFromInfo.md
+++ b/docs/ForkedFromInfo.md
@@ -5,6 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**database_id** | **String** | ID of the database that was forked. The database may since have been deleted — the record outlives it — so this is not guaranteed to resolve. |
+**description** | Option<**String**> | Why the fork was taken, as given when it was created. Absent when none was given. | [optional]
**forked_at** | Option<**String**> | When the fork was taken. | [optional]
**name** | Option<**String**> | Display label the source carried when the fork was taken, kept so a deleted source still reads as more than an ID. | [optional]
**snapshot_id** | Option<**i64**> | Marks the version of the source that this fork copied — its table set and their contents as of that moment. It is a point in time rather than a per-database revision count, so two forks of a source that did not change still report different values, and the numbers are not a way to tell whether a source has changed. Absent only on forks taken before the version was recorded. | [optional]
diff --git a/docs/LineageAncestorInfo.md b/docs/LineageAncestorInfo.md
index 969f3ac..37aff93 100644
--- a/docs/LineageAncestorInfo.md
+++ b/docs/LineageAncestorInfo.md
@@ -5,6 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**database_id** | **String** | |
+**description** | Option<**String**> | Why the next database down the chain was forked from it, as given at the time. Absent when none was given. | [optional]
**exists** | **bool** | False once the ancestor has been deleted. Its place in the chain is kept either way, and the ancestry continues past it. |
**forked_at** | Option<**String**> | When the next database down the chain was forked from it. | [optional]
**name** | Option<**String**> | The ancestor's current label, or the one captured at fork time when it no longer exists. | [optional]
diff --git a/docs/LineageForkInfo.md b/docs/LineageForkInfo.md
index 94d47a3..28128f0 100644
--- a/docs/LineageForkInfo.md
+++ b/docs/LineageForkInfo.md
@@ -5,6 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**database_id** | **String** | |
+**description** | Option<**String**> | Why the fork was taken, as given when it was created. Absent when none was given. | [optional]
**exists** | **bool** | False once the fork has been deleted. The record of it is kept either way, so a source can still account for everything taken from it. |
**forked_at** | Option<**String**> | When the fork was taken. | [optional]
**name** | Option<**String**> | Absent once the fork has been deleted — only the record of it remains. | [optional]
diff --git a/src/apis/databases_api.rs b/src/apis/databases_api.rs
index 75c8d7b..6c7e8ff 100644
--- a/src/apis/databases_api.rs
+++ b/src/apis/databases_api.rs
@@ -754,7 +754,7 @@ pub async fn detach_database_catalog(
}
}
-/// Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
+/// Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `description` records why the fork is being taken; it is returned with the fork's `forked_from` and in the lineage of both databases. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
pub async fn fork_database(
configuration: &configuration::Configuration,
database_id: &str,
diff --git a/src/models/fork_database_request.rs b/src/models/fork_database_request.rs
index 6e39b0e..5e9742c 100644
--- a/src/models/fork_database_request.rs
+++ b/src/models/fork_database_request.rs
@@ -14,6 +14,14 @@ use serde::{Deserialize, Serialize};
/// ForkDatabaseRequest : Request body for POST /databases/{database_id}/fork
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct ForkDatabaseRequest {
+ /// Optional note saying why the fork is being taken — for example \"backfill test before the March migration\". It is kept with the record of the fork and returned wherever that record appears: `forked_from` on the fork, and the fork's entry in both databases' lineage. Surrounding whitespace is trimmed, and an empty value is treated as absent. At most 4096 bytes; line breaks and tabs are allowed, other control characters are not.
+ #[serde(
+ rename = "description",
+ default,
+ with = "::serde_with::rust::double_option",
+ skip_serializing_if = "Option::is_none"
+ )]
+ pub description: Option