diff --git a/.changeset/description-union-type.md b/.changeset/description-union-type.md new file mode 100644 index 0000000..c191c69 --- /dev/null +++ b/.changeset/description-union-type.md @@ -0,0 +1,7 @@ +--- +"@hypercerts-org/lexicon": minor +--- + +Widen description fields on activity, collection, and attachment from a bare Leaflet ref to a union of inline descriptionString and Leaflet linearDocument, with a shared def in org.hypercerts.defs. + +This is technically a breaking schema change (ref → union), but not breaking for most published records, as they already include a `$type` discriminator on the description object, so existing data validates against the union without modification. diff --git a/ERD.puml b/ERD.puml index 287b2ed..383fcb9 100644 --- a/ERD.puml +++ b/ERD.puml @@ -235,7 +235,7 @@ dataclass collection { type? title shortDescription? - description? (Leaflet ref) + description? items[]? location? createdAt diff --git a/SCHEMAS.md b/SCHEMAS.md index e8a7c0a..3d4a113 100644 --- a/SCHEMAS.md +++ b/SCHEMAS.md @@ -15,20 +15,20 @@ Hypercerts-specific lexicons for tracking impact work and claims. #### Properties -| Property | Type | Required | Description | Comments | -| ------------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | -| `title` | `string` | ✅ | Display title summarizing the impact work (e.g. 'Reforestation in Amazon Basin 2024') | maxLength: 256 | -| `shortDescription` | `string` | ✅ | Short summary of this activity claim, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 | -| `shortDescriptionFacets` | `ref[]` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | | -| `description` | `ref` | ❌ | Rich-text description, represented as a Leaflet linear document. | | -| `image` | `union` | ❌ | The hypercert visual representation as a URI or image blob. | | -| `contributors` | `ref[]` | ❌ | An array of contributor objects, each containing contributor information, weight, and contribution details. | | -| `workScope` | `union` | ❌ | Work scope definition. A CEL expression for structured, machine-evaluable scopes or a free-form string for simple and legacy scopes. | | -| `startDate` | `string` | ❌ | When the work began | | -| `endDate` | `string` | ❌ | When the work ended | | -| `locations` | `ref[]` | ❌ | An array of strong references to the location where activity was performed. The record referenced must conform with the lexicon app.certified.location. | maxLength: 1000 | -| `rights` | `ref` | ❌ | A strong reference to the rights that this hypercert has. The record referenced must conform with the lexicon org.hypercerts.claim.rights. | | -| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | | +| Property | Type | Required | Description | Comments | +| ------------------------ | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | +| `title` | `string` | ✅ | Display title summarizing the impact work (e.g. 'Reforestation in Amazon Basin 2024') | maxLength: 256 | +| `shortDescription` | `string` | ✅ | Short summary of this activity claim, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 | +| `shortDescriptionFacets` | `ref[]` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | | +| `description` | `union` | ❌ | Long-form description of the activity. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record. | | +| `image` | `union` | ❌ | The hypercert visual representation as a URI or image blob. | | +| `contributors` | `ref[]` | ❌ | An array of contributor objects, each containing contributor information, weight, and contribution details. | | +| `workScope` | `union` | ❌ | Work scope definition. A CEL expression for structured, machine-evaluable scopes or a free-form string for simple and legacy scopes. | | +| `startDate` | `string` | ❌ | When the work began | | +| `endDate` | `string` | ❌ | When the work ended | | +| `locations` | `ref[]` | ❌ | An array of strong references to the location where activity was performed. The record referenced must conform with the lexicon app.certified.location. | maxLength: 1000 | +| `rights` | `ref` | ❌ | A strong reference to the rights that this hypercert has. The record referenced must conform with the lexicon org.hypercerts.claim.rights. | | +| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | | #### Defs @@ -129,18 +129,18 @@ A free-form string describing the work scope for simple or legacy scopes. #### Properties -| Property | Type | Required | Description | Comments | -| ------------------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -| `type` | `string` | ❌ | The type of this collection. Values beyond the known set are permitted. | maxLength: 64, Known values: `favorites`, `project`, `portfolio`, `program` | -| `title` | `string` | ✅ | Display name for this collection (e.g. 'Q1 2025 Impact Projects') | maxLength: 800, maxGraphemes: 80 | -| `shortDescription` | `string` | ❌ | Short summary of this collection, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 | -| `shortDescriptionFacets` | `ref[]` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | | -| `description` | `ref` | ❌ | Rich-text description, represented as a Leaflet linear document. | | -| `avatar` | `union` | ❌ | The collection's avatar/profile image as a URI or image blob. | | -| `banner` | `union` | ❌ | Larger horizontal image to display behind the collection view. | | -| `items` | `ref[]` | ❌ | Array of items in this collection with optional weights. | maxLength: 1000 | -| `location` | `ref` | ❌ | A strong reference to the location where this collection's activities were performed. The record referenced must conform with the lexicon app.certified.location. | | -| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | | +| Property | Type | Required | Description | Comments | +| ------------------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| `type` | `string` | ❌ | The type of this collection. Values beyond the known set are permitted. | maxLength: 64, Known values: `favorites`, `project`, `portfolio`, `program` | +| `title` | `string` | ✅ | Display name for this collection (e.g. 'Q1 2025 Impact Projects') | maxLength: 800, maxGraphemes: 80 | +| `shortDescription` | `string` | ❌ | Short summary of this collection, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 | +| `shortDescriptionFacets` | `ref[]` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | | +| `description` | `union` | ❌ | Long-form description of the collection. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record. | | +| `avatar` | `union` | ❌ | The collection's avatar/profile image as a URI or image blob. | | +| `banner` | `union` | ❌ | Larger horizontal image to display behind the collection view. | | +| `items` | `ref[]` | ❌ | Array of items in this collection with optional weights. | maxLength: 1000 | +| `location` | `ref` | ❌ | A strong reference to the location where this collection's activities were performed. The record referenced must conform with the lexicon app.certified.location. | | +| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | | #### Defs @@ -189,7 +189,7 @@ An item in a collection, with an identifier and optional weight. | `title` | `string` | ✅ | Display title for this attachment (e.g. 'Impact Assessment Report', 'Audit Findings') | maxLength: 256 | | `shortDescription` | `string` | ❌ | Short summary of this attachment, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 | | `shortDescriptionFacets` | `ref[]` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | | -| `description` | `ref` | ❌ | Rich-text description, represented as a Leaflet linear document. | | +| `description` | `union` | ❌ | Long-form description of the attachment. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record. | | | `location` | `ref` | ❌ | A strong reference to the location where this attachment's subject matter occurred. The record referenced must conform with the lexicon app.certified.location. | | | `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created. | | @@ -530,6 +530,15 @@ A Decentralized Identifier (DID) string. #### Defs +##### `org.hypercerts.defs#descriptionString` + +An inline long-form description as plain text or markdown, with optional rich-text annotations. + +| Property | Type | Required | Description | +| -------- | -------- | -------- | -------------------------------------------------------------------------- | +| `value` | `string` | ✅ | The description text (plain text or markdown). | +| `facets` | `ref[]` | ❌ | Rich text annotations for the description (mentions, URLs, hashtags, etc). | + ##### `org.hypercerts.defs#uri` Object containing a URI to external data diff --git a/lexicons/org/hypercerts/claim/activity.json b/lexicons/org/hypercerts/claim/activity.json index 693db7d..86c4182 100644 --- a/lexicons/org/hypercerts/claim/activity.json +++ b/lexicons/org/hypercerts/claim/activity.json @@ -30,9 +30,13 @@ } }, "description": { - "type": "ref", - "ref": "pub.leaflet.pages.linearDocument#main", - "description": "Rich-text description, represented as a Leaflet linear document." + "type": "union", + "refs": [ + "org.hypercerts.defs#descriptionString", + "pub.leaflet.pages.linearDocument", + "com.atproto.repo.strongRef" + ], + "description": "Long-form description of the activity. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record." }, "image": { "type": "union", diff --git a/lexicons/org/hypercerts/collection.json b/lexicons/org/hypercerts/collection.json index cc19635..ba974b9 100644 --- a/lexicons/org/hypercerts/collection.json +++ b/lexicons/org/hypercerts/collection.json @@ -37,9 +37,13 @@ } }, "description": { - "type": "ref", - "ref": "pub.leaflet.pages.linearDocument#main", - "description": "Rich-text description, represented as a Leaflet linear document." + "type": "union", + "refs": [ + "org.hypercerts.defs#descriptionString", + "pub.leaflet.pages.linearDocument", + "com.atproto.repo.strongRef" + ], + "description": "Long-form description of the collection. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record." }, "avatar": { "type": "union", diff --git a/lexicons/org/hypercerts/context/attachment.json b/lexicons/org/hypercerts/context/attachment.json index a5ad844..ee18819 100644 --- a/lexicons/org/hypercerts/context/attachment.json +++ b/lexicons/org/hypercerts/context/attachment.json @@ -63,9 +63,13 @@ } }, "description": { - "type": "ref", - "ref": "pub.leaflet.pages.linearDocument#main", - "description": "Rich-text description, represented as a Leaflet linear document." + "type": "union", + "refs": [ + "org.hypercerts.defs#descriptionString", + "pub.leaflet.pages.linearDocument", + "com.atproto.repo.strongRef" + ], + "description": "Long-form description of the attachment. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record." }, "location": { "type": "ref", diff --git a/lexicons/org/hypercerts/defs.json b/lexicons/org/hypercerts/defs.json index 61ae443..92213dc 100644 --- a/lexicons/org/hypercerts/defs.json +++ b/lexicons/org/hypercerts/defs.json @@ -3,6 +3,27 @@ "id": "org.hypercerts.defs", "description": "Common type definitions used across all Hypercerts protocols.", "defs": { + "descriptionString": { + "type": "object", + "description": "An inline long-form description as plain text or markdown, with optional rich-text annotations.", + "required": ["value"], + "properties": { + "value": { + "type": "string", + "description": "The description text (plain text or markdown).", + "maxLength": 250000, + "maxGraphemes": 25000 + }, + "facets": { + "type": "array", + "description": "Rich text annotations for the description (mentions, URLs, hashtags, etc).", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + } + } + }, "uri": { "type": "object", "required": ["uri"],