diff --git a/public/contracts/artifacts/contracts/mdbase.contact/1.0.0.md b/public/contracts/artifacts/contracts/mdbase.contact/1.0.0.md new file mode 100644 index 0000000..eca51e4 --- /dev/null +++ b/public/contracts/artifacts/contracts/mdbase.contact/1.0.0.md @@ -0,0 +1,22 @@ +--- +kind: mdbase.contract +contract_type: record +id: mdbase.contact +version: 1.0.0 +name: Contact +description: A compact application-facing view of a person or organisation. +record_schema: + dialect: json-schema-2020-12 + ref: ../../schemas/mdbase.contact/1.0.0.schema.json +--- + +# Contact + +This contract exposes the small set of contact semantics commonly shared by +address books, relationship tools, and other applications. A collection keeps +its own field names and may store richer local data; the implementing type maps +only the fields it wants applications to see. + +The contract is deliberately not an interchange format. Exporters can convert +this view to JSContact, vCard, or another wire representation without requiring +Markdown records to store that representation directly. diff --git a/public/contracts/artifacts/schemas/mdbase.contact/1.0.0.schema.json b/public/contracts/artifacts/schemas/mdbase.contact/1.0.0.schema.json new file mode 100644 index 0000000..51570d0 --- /dev/null +++ b/public/contracts/artifacts/schemas/mdbase.contact/1.0.0.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/contracts/schemas/mdbase.contact/1.0.0.schema.json", + "title": "Contact", + "description": "A compact application-facing contact view.", + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "The name applications should use when presenting this contact." + }, + "kind": { + "type": "string", + "enum": ["individual", "organisation", "group"], + "description": "The broad kind of contact when the collection distinguishes it." + }, + "primary_email": { + "type": "string", + "format": "email", + "description": "The preferred email address for this contact." + }, + "primary_phone": { + "type": "string", + "minLength": 1, + "description": "The preferred telephone number for this contact." + }, + "organisation": { + "type": "string", + "minLength": 1, + "description": "The organisation most closely associated with this contact." + }, + "birthday": { + "type": "string", + "format": "date", + "description": "The contact's birthday when known." + } + }, + "additionalProperties": false +} diff --git a/public/contracts/artifacts/types/contact/2.md b/public/contracts/artifacts/types/contact/2.md new file mode 100644 index 0000000..38a862e --- /dev/null +++ b/public/contracts/artifacts/types/contact/2.md @@ -0,0 +1,76 @@ +--- +kind: mdbase.type +name: contact +version: 1 +description: A person or organisation you want to stay in touch with +match: + where: + type: contact +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + title: Contact + description: A friendly local contact with room for collection-specific fields. + type: object + required: + - type + - name + properties: + type: + const: contact + name: + type: string + minLength: 1 + description: The name shown in contact lists. + kind: + type: string + enum: + - individual + - organisation + - group + default: individual + description: The broad kind of contact. + email: + type: string + format: email + description: The preferred email address. + phone: + type: string + minLength: 1 + description: The preferred telephone number. + organisation: + type: string + minLength: 1 + description: The contact's main organisation. + birthday: + type: string + format: date + description: The contact's birthday. + additionalProperties: true +collection: + display: + name_field: name + description_field: organisation + icon: address-book +implements: + - contract: mdbase.contact + version: 1.0.0 + fields: + name: name + kind: kind + primary_email: email + primary_phone: phone + organisation: organisation + birthday: birthday +--- + +# Contact + +Contact notes use familiar frontmatter fields and leave the Markdown body free +for history, context, and anything else worth remembering. Applications using +the `mdbase.contact` contract see only the mapped contact fields. + +You can rename or extend the local fields in mdbase-editor. Keep the contract +mapping aligned so other contact-aware applications continue to understand +the type. diff --git a/public/contracts/catalog.json b/public/contracts/catalog.json index 9fec696..bfdec6d 100644 --- a/public/contracts/catalog.json +++ b/public/contracts/catalog.json @@ -10,24 +10,14 @@ }, "contracts": [ { - "id": "mdbase.jscontact.card", - "version": "2.0.0", - "name": "JSContact Card 2.0 core", - "description": "A strict, portable core profile of an IETF JSContact 2.0 Card.", + "id": "mdbase.contact", + "version": "1.0.0", + "name": "Contact", + "description": "A compact application-facing view of a person or organisation.", "contract_type": "record", - "digest": "sha256:c56c5acbf7992155d6890294842a261fe80a933ec75a226ea875b97ba57dcaa2", - "artifact": "./artifacts/contracts/mdbase.jscontact.card/2.0.0.md", - "standards": [ - { - "name": "JSContact", - "version": "2.0", - "scope": "Strict core profile covering the Card envelope, names, email addresses, phones, organizations, and notes.", - "references": [ - "https://www.rfc-editor.org/rfc/rfc9553.html", - "https://www.rfc-editor.org/rfc/rfc9982.html" - ] - } - ] + "digest": "sha256:e3634a35737ada5eb62e3e15f1c0c9d2e27c55a3f98dfab94bbc14c40404903d", + "artifact": "./artifacts/contracts/mdbase.contact/1.0.0.md", + "standards": [] }, { "id": "mdbase.record.created", @@ -192,27 +182,27 @@ ], "packs": [ { - "id": "mdbase.jscontact", - "version": "2.0.3", + "id": "mdbase.contact", + "version": "1.0.0", "name": "Contact type pack", - "description": "The mdbase JSContact Card core contract and a fully expanded, editable Contact type.", - "digest": "sha256:e89693733a9d3d98bdd05fc040a08d7fb6f5eaea22089ed4ef8e0f1392e9c269", - "provision": "./packs/mdbase.jscontact/2.0.3.json", + "description": "A compact contact contract and a friendly, editable Contact type.", + "digest": "sha256:f5be1e7ea7b8dacda628d0cd809eb02cbad965505dc44c98bbd709ffb4847330", + "provision": "./packs/mdbase.contact/1.0.0.json", "provides": [ { - "id": "mdbase.jscontact.card", - "version": "2.0.0" + "id": "mdbase.contact", + "version": "1.0.0" } ], "resource_count": 3, "display": { "name": "Contact", - "summary": "Store people and organisations with names, email addresses, phone numbers, and notes.", + "summary": "Keep people and organisations with familiar names, email addresses, phone numbers, and birthdays.", "category": "people", "audience": "general", "icon": "address-book", "badges": [ - "JSContact 2.0" + "Portable contact semantics" ] }, "installation": { diff --git a/public/contracts/packs/mdbase.contact/1.0.0.json b/public/contracts/packs/mdbase.contact/1.0.0.json new file mode 100644 index 0000000..498a528 --- /dev/null +++ b/public/contracts/packs/mdbase.contact/1.0.0.json @@ -0,0 +1,49 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "mdbase.contact", + "version": "1.0.0", + "name": "Contact type pack", + "description": "A compact contact contract and a friendly, editable Contact type.", + "resources": [ + { + "kind": "schema", + "source": "schemas/mdbase.contact/1.0.0.schema.json", + "target": "schemas/mdbase.contact/1.0.0.schema.json", + "digest": "sha256:bd8a011d18c71164b633f4e82cb33faa5b658cdba4f89312a34c13bf46a350d2" + }, + { + "kind": "contract", + "source": "contracts/mdbase.contact/1.0.0.md", + "target": "_contracts/mdbase.contact/1.0.0.md", + "digest": "sha256:e3634a35737ada5eb62e3e15f1c0c9d2e27c55a3f98dfab94bbc14c40404903d" + }, + { + "kind": "type", + "source": "types/contact/2.md", + "target": "_types/contact.md", + "digest": "sha256:c925ac22674b5fa9b1a7b8b3af827e5ce3ba15e423b64487f626f5ab4cc1c80a" + } + ] + }, + "resources": [ + { + "source": "schemas/mdbase.contact/1.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.contact/1.0.0.schema.json\",\n \"title\": \"Contact\",\n \"description\": \"A compact application-facing contact view.\",\n \"type\": \"object\",\n \"required\": [\"name\"],\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The name applications should use when presenting this contact.\"\n },\n \"kind\": {\n \"type\": \"string\",\n \"enum\": [\"individual\", \"organisation\", \"group\"],\n \"description\": \"The broad kind of contact when the collection distinguishes it.\"\n },\n \"primary_email\": {\n \"type\": \"string\",\n \"format\": \"email\",\n \"description\": \"The preferred email address for this contact.\"\n },\n \"primary_phone\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The preferred telephone number for this contact.\"\n },\n \"organisation\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The organisation most closely associated with this contact.\"\n },\n \"birthday\": {\n \"type\": \"string\",\n \"format\": \"date\",\n \"description\": \"The contact's birthday when known.\"\n }\n },\n \"additionalProperties\": false\n}\n" + }, + { + "source": "contracts/mdbase.contact/1.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.contact\nversion: 1.0.0\nname: Contact\ndescription: A compact application-facing view of a person or organisation.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.contact/1.0.0.schema.json\n---\n\n# Contact\n\nThis contract exposes the small set of contact semantics commonly shared by\naddress books, relationship tools, and other applications. A collection keeps\nits own field names and may store richer local data; the implementing type maps\nonly the fields it wants applications to see.\n\nThe contract is deliberately not an interchange format. Exporters can convert\nthis view to JSContact, vCard, or another wire representation without requiring\nMarkdown records to store that representation directly.\n" + }, + { + "source": "types/contact/2.md", + "document": "---\nkind: mdbase.type\nname: contact\nversion: 1\ndescription: A person or organisation you want to stay in touch with\nmatch:\n where:\n type: contact\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n title: Contact\n description: A friendly local contact with room for collection-specific fields.\n type: object\n required:\n - type\n - name\n properties:\n type:\n const: contact\n name:\n type: string\n minLength: 1\n description: The name shown in contact lists.\n kind:\n type: string\n enum:\n - individual\n - organisation\n - group\n default: individual\n description: The broad kind of contact.\n email:\n type: string\n format: email\n description: The preferred email address.\n phone:\n type: string\n minLength: 1\n description: The preferred telephone number.\n organisation:\n type: string\n minLength: 1\n description: The contact's main organisation.\n birthday:\n type: string\n format: date\n description: The contact's birthday.\n additionalProperties: true\ncollection:\n display:\n name_field: name\n description_field: organisation\n icon: address-book\nimplements:\n - contract: mdbase.contact\n version: 1.0.0\n fields:\n name: name\n kind: kind\n primary_email: email\n primary_phone: phone\n organisation: organisation\n birthday: birthday\n---\n\n# Contact\n\nContact notes use familiar frontmatter fields and leave the Markdown body free\nfor history, context, and anything else worth remembering. Applications using\nthe `mdbase.contact` contract see only the mapped contact fields.\n\nYou can rename or extend the local fields in mdbase-editor. Keep the contract\nmapping aligned so other contact-aware applications continue to understand\nthe type.\n" + } + ], + "provides": [ + { + "id": "mdbase.contact", + "version": "1.0.0" + } + ] +} diff --git a/public/contracts/schemas/mdbase.contact/1.0.0.schema.json b/public/contracts/schemas/mdbase.contact/1.0.0.schema.json new file mode 100644 index 0000000..51570d0 --- /dev/null +++ b/public/contracts/schemas/mdbase.contact/1.0.0.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/contracts/schemas/mdbase.contact/1.0.0.schema.json", + "title": "Contact", + "description": "A compact application-facing contact view.", + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "The name applications should use when presenting this contact." + }, + "kind": { + "type": "string", + "enum": ["individual", "organisation", "group"], + "description": "The broad kind of contact when the collection distinguishes it." + }, + "primary_email": { + "type": "string", + "format": "email", + "description": "The preferred email address for this contact." + }, + "primary_phone": { + "type": "string", + "minLength": 1, + "description": "The preferred telephone number for this contact." + }, + "organisation": { + "type": "string", + "minLength": 1, + "description": "The organisation most closely associated with this contact." + }, + "birthday": { + "type": "string", + "format": "date", + "description": "The contact's birthday when known." + } + }, + "additionalProperties": false +} diff --git a/public/testbed/v0.1/fixtures/catalog.json b/public/testbed/v0.1/fixtures/catalog.json index 7d5507f..2b7747c 100644 --- a/public/testbed/v0.1/fixtures/catalog.json +++ b/public/testbed/v0.1/fixtures/catalog.json @@ -23,6 +23,28 @@ } } }, + "contract.example-summary": { + "kind": "contract", + "value": { + "kind": "mdbase.contract", + "contract_type": "record", + "id": "example.summary", + "version": "1.0.0", + "name": "Portable example summary", + "record_schema": { + "dialect": "json-schema-2020-12", + "value": { + "type": "object", + "required": ["label"], + "additionalProperties": false, + "properties": { + "label": { "type": "string", "minLength": 1 }, + "category": { "type": "string", "minLength": 1 } + } + } + } + } + }, "type.shared-note": { "kind": "type", "value": { @@ -51,11 +73,49 @@ ] } }, + "type.multi-contract-note": { + "kind": "type", + "value": { + "kind": "mdbase.type", + "name": "shared_note", + "version": 1, + "schema": { + "dialect": "json-schema-2020-12", + "value": { + "type": "object", + "required": ["type", "headline", "category"], + "properties": { + "type": { "const": "shared_note" }, + "headline": { "type": "string", "minLength": 1 }, + "category": { "type": "string", "minLength": 1 } + } + } + }, + "implements": [ + { + "contract": "example.note", + "version": "1.0.0", + "fields": { + "title": "headline" + } + }, + { + "contract": "example.summary", + "version": "1.0.0", + "fields": { + "label": "headline", + "category": "category" + } + } + ] + } + }, "record.shared-note": { "kind": "record", "value": { "type": "shared_note", - "headline": "One record, two consumers" + "headline": "One record, two consumers", + "category": "reference" } }, "contract.record-changed": { diff --git a/public/testbed/v0.1/scenarios/core.shared-type-contracts.json b/public/testbed/v0.1/scenarios/core.shared-type-contracts.json new file mode 100644 index 0000000..5a66017 --- /dev/null +++ b/public/testbed/v0.1/scenarios/core.shared-type-contracts.json @@ -0,0 +1,87 @@ +{ + "kind": "mdbase.testbed.scenario", + "protocol_version": "0.1", + "id": "core.shared-type-contracts", + "name": "One type exposes two independent contract views", + "description": "One local type implements two record contracts and each consumer observes only the normalized view it selected.", + "ring": "contract", + "profile": "core_read", + "roles": ["contract_store", "record_consumer"], + "operation": "contract.multiple-views", + "fixtures": [ + "contract.example-note", + "contract.example-summary", + "type.multi-contract-note", + "record.shared-note" + ], + "parameters": { + "consumers": ["note-consumer", "summary-consumer"] + }, + "covers": [ + "core_read.data_contract_discovery", + "core_read.data_contract_implementation_validation", + "core_read.data_contract_projection" + ], + "expect": { + "entries": [ + { + "sequence": 1, + "phase": "arrange", + "actor": "contract-store", + "operation": "contract.load", + "outcome": "succeeded", + "facts": { + "contracts": ["example.note", "example.summary"] + } + }, + { + "sequence": 2, + "phase": "arrange", + "actor": "contract-store", + "operation": "type.load", + "outcome": "succeeded", + "facts": { + "type": "shared_note", + "implements": ["example.note", "example.summary"] + } + }, + { + "sequence": 3, + "phase": "act", + "actor": "note-consumer", + "operation": "contract-view.read", + "outcome": "succeeded", + "facts": { + "contract": "example.note", + "view": { + "title": "One record, two consumers" + } + } + }, + { + "sequence": 4, + "phase": "act", + "actor": "summary-consumer", + "operation": "contract-view.read", + "outcome": "succeeded", + "facts": { + "contract": "example.summary", + "view": { + "label": "One record, two consumers" + } + } + }, + { + "sequence": 5, + "phase": "observe", + "actor": "testbed", + "operation": "contract-view.compare", + "outcome": "succeeded", + "facts": { + "same_record": true, + "views_are_distinct": true + } + } + ] + } +} diff --git a/site-sources.json b/site-sources.json index d6ec212..9321a00 100644 --- a/site-sources.json +++ b/site-sources.json @@ -1,7 +1,7 @@ { "specification": { "repository": "mdbase-dev/mdbase-spec", - "ref": "fe1f0c854a58565a2dc6499505f95d3294ce314a" + "ref": "b5cb86bfdbd8fb5f78901661f3f8ad68fe9f690e" }, "connect": { "repository": "mdbase-dev/mdbase-connect", @@ -9,13 +9,13 @@ }, "contracts": { "repository": "mdbase-dev/mdbase-contracts", - "ref": "2870400a023ecbab21ca64bad4f6367dc5316433" + "ref": "78bc62dc1111e33c14dcd72b5efe35d4fb8a91ea" }, "implementations": [ { "id": "rust", "repository": "callumalpass/mdbase-rs", - "ref": "281629ef0a54ed5f7868366c5a8a7f69f41eb479" + "ref": "3156d481e7950139b2e83dd76cfa4a7db1b19678" }, { "id": "typescript", diff --git a/src/data/contracts.json b/src/data/contracts.json index 9fec696..bfdec6d 100644 --- a/src/data/contracts.json +++ b/src/data/contracts.json @@ -10,24 +10,14 @@ }, "contracts": [ { - "id": "mdbase.jscontact.card", - "version": "2.0.0", - "name": "JSContact Card 2.0 core", - "description": "A strict, portable core profile of an IETF JSContact 2.0 Card.", + "id": "mdbase.contact", + "version": "1.0.0", + "name": "Contact", + "description": "A compact application-facing view of a person or organisation.", "contract_type": "record", - "digest": "sha256:c56c5acbf7992155d6890294842a261fe80a933ec75a226ea875b97ba57dcaa2", - "artifact": "./artifacts/contracts/mdbase.jscontact.card/2.0.0.md", - "standards": [ - { - "name": "JSContact", - "version": "2.0", - "scope": "Strict core profile covering the Card envelope, names, email addresses, phones, organizations, and notes.", - "references": [ - "https://www.rfc-editor.org/rfc/rfc9553.html", - "https://www.rfc-editor.org/rfc/rfc9982.html" - ] - } - ] + "digest": "sha256:e3634a35737ada5eb62e3e15f1c0c9d2e27c55a3f98dfab94bbc14c40404903d", + "artifact": "./artifacts/contracts/mdbase.contact/1.0.0.md", + "standards": [] }, { "id": "mdbase.record.created", @@ -192,27 +182,27 @@ ], "packs": [ { - "id": "mdbase.jscontact", - "version": "2.0.3", + "id": "mdbase.contact", + "version": "1.0.0", "name": "Contact type pack", - "description": "The mdbase JSContact Card core contract and a fully expanded, editable Contact type.", - "digest": "sha256:e89693733a9d3d98bdd05fc040a08d7fb6f5eaea22089ed4ef8e0f1392e9c269", - "provision": "./packs/mdbase.jscontact/2.0.3.json", + "description": "A compact contact contract and a friendly, editable Contact type.", + "digest": "sha256:f5be1e7ea7b8dacda628d0cd809eb02cbad965505dc44c98bbd709ffb4847330", + "provision": "./packs/mdbase.contact/1.0.0.json", "provides": [ { - "id": "mdbase.jscontact.card", - "version": "2.0.0" + "id": "mdbase.contact", + "version": "1.0.0" } ], "resource_count": 3, "display": { "name": "Contact", - "summary": "Store people and organisations with names, email addresses, phone numbers, and notes.", + "summary": "Keep people and organisations with familiar names, email addresses, phone numbers, and birthdays.", "category": "people", "audience": "general", "icon": "address-book", "badges": [ - "JSContact 2.0" + "Portable contact semantics" ] }, "installation": { diff --git a/src/pages/contracts/index.astro b/src/pages/contracts/index.astro index 3bb383f..35d39c5 100644 --- a/src/pages/contracts/index.astro +++ b/src/pages/contracts/index.astro @@ -3,6 +3,14 @@ import BaseLayout from "../../layouts/BaseLayout.astro"; import catalog from "../../data/contracts.json"; const artifactHref = (path: string) => `/contracts/${path.replace(/^\.\//, "")}`; +const publishedContracts = catalog.contracts as Array<{ + id: string; + version: string; + name: string; + description: string; + artifact: string; + standards: Array<{ name: string; version: string; scope: string }>; +}>; const readyMadePacks = catalog.packs.filter((pack) => pack.installation.visibility === "default"); const advancedPacks = catalog.packs.filter((pack) => pack.installation.visibility === "advanced"); --- @@ -20,9 +28,10 @@ const advancedPacks = catalog.packs.filter((pack) => pack.installation.visibilit
- Contracts describe portable record shapes. Type packs install a - contract, its referenced schemas, and a usable default implementation - as one digest-pinned transaction. + Contracts give applications a small, shared vocabulary without + forcing every collection to use the same field names or storage + format. Type packs install a contract and a friendly editable type + together.
+
+ A type remains the source of truth for what your Markdown records store.
+ Its implements entries explain how compatible applications
+ should read those fields.
+
Uses familiar local names such as email or stage.
Connects local fields to a compact contract vocabulary such as primary_email or status.
Optionally describe behavior, such as which status values mean complete, using another JSON Schema.
+ One type can implement several contracts, and any number of applications + can consume the same contract. Interchange formats such as JSContact and + vCard belong in import and export adapters unless a collection + intentionally stores that wire format. +
+| Contract | Version | -Profile | +Shared semantics | Artifact |
|---|---|---|---|---|
|
{contract.name} @@ -77,7 +115,8 @@ const advancedPacks = catalog.packs.filter((pack) => pack.installation.visibilit Add these from Types → Add a type in mdbase-editor. Each pack creates a local, editable type with its portable contract and - initial field mapping. + initial field mapping. You can rename fields later; the editor keeps the + mapping visible and aligned.
{
@@ -155,6 +194,48 @@ const advancedPacks = catalog.packs.filter((pack) => pack.installation.visibilit
color: var(--color-text-soft);
}
+ .contract-explainer ol {
+ display: grid;
+ gap: 1px;
+ margin: 1.5rem 0 0;
+ padding: 0;
+ border-block: 1px solid var(--color-border);
+ background: var(--color-border);
+ list-style: none;
+ }
+
+ .contract-explainer li {
+ width: 100%;
+ max-width: none;
+ display: grid;
+ grid-template-columns: 2rem minmax(0, 1fr);
+ gap: 1rem;
+ align-items: start;
+ padding: 1rem 0;
+ background: var(--color-canvas);
+ }
+
+ .contract-explainer li > span {
+ color: var(--color-text-muted);
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ }
+
+ .contract-explainer li strong {
+ font-size: 0.9rem;
+ }
+
+ .contract-explainer li p,
+ .contract-explainer__note {
+ max-width: 48rem;
+ margin: 0.25rem 0 0;
+ color: var(--color-text-soft);
+ }
+
+ .contract-explainer__note {
+ margin-top: 1rem;
+ }
+
.pack-grid {
display: grid;
gap: 1px;
diff --git a/src/pages/sdk/contracts/index.astro b/src/pages/sdk/contracts/index.astro
index a2b6a92..9ce3b2d 100644
--- a/src/pages/sdk/contracts/index.astro
+++ b/src/pages/sdk/contracts/index.astro
@@ -21,6 +21,27 @@ for (const implementation of workItemContract.implementations) {
);
}`;
+const typeImplementation = `kind: mdbase.type
+name: project_item
+version: 1
+schema:
+ dialect: json-schema-2020-12
+ value:
+ type: object
+ required: [heading, stage]
+ properties:
+ heading: { type: string, minLength: 1 }
+ stage: { type: string }
+implements:
+ - contract: example.work-item
+ version: 1.0.0
+ fields:
+ title: heading
+ status: stage
+ binding:
+ status:
+ completed_values: [done, cancelled]`;
+
const domainFunction = `import type { MdbaseCollectionClient } from "@mdbase/connect";
export class WorklogCollection {
@@ -45,6 +66,7 @@ export class WorklogCollection {
description="Build domain behavior on declared contracts across different frontmatter fields and path conventions."
active="contracts"
headings={[
+ { href: "#type-file", label: "Implement in a type" },
{ href: "#contract", label: "Read a contract" },
{ href: "#own-adapter", label: "Your own adapter" },
{ href: "#ownership", label: "Adapter ownership" },
@@ -60,11 +82,29 @@ export class WorklogCollection {
Only record contracts are implemented by type files. A type opts in through{" "}
Implement a contract in the type file+
+ The type schema above governs stored frontmatter. The
+ General-purpose editors can safely expose both objects because their shapes
+ come from the contract's JSON Schemas. Domain applications may offer more
+ tailored controls and write the same Read the approved collection description@@ -110,4 +150,9 @@ export class WorklogCollection { whole-record or collection-level behavior such as body-aware task tools, arbitrary saved views, schema editors, or general-purpose collection tools. ++ Event sources and action providers declare executable implementations + through the interoperability bridge, not through a + type file. + |