docs: add per-metadata-type guide pages for application development#630
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Create comprehensive documentation pages for each metadata type: - Object, Field, View, Page, App, Dashboard, Flow, Workflow, Validation, Permission Each page covers properties, configuration, and examples. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new “Metadata Types” guide section to the docs site, aiming to give developers dedicated, per-metadata-type pages for metadata-driven application development.
Changes:
- Introduces
content/docs/guides/metadata/with overview + individual guide pages (Object, Field, View, Page, App, Dashboard, Flow, Workflow, Validation, Permission). - Adds navigation wiring via
content/docs/guides/meta.jsonandcontent/docs/guides/metadata/meta.json. - Updates
content/docs/guides/index.mdxto include the new Metadata Types entry in the Guides landing page.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 25 comments.
Show a summary per file
| File | Description |
|---|---|
| content/docs/guides/metadata/index.mdx | New overview page + metadata category tables and file conventions |
| content/docs/guides/metadata/meta.json | Sidebar/nav configuration for metadata guide pages |
| content/docs/guides/metadata/object.mdx | New Object metadata guide page |
| content/docs/guides/metadata/field.mdx | New Field metadata guide page |
| content/docs/guides/metadata/view.mdx | New View (list/form) metadata guide page |
| content/docs/guides/metadata/page.mdx | New Page metadata guide page |
| content/docs/guides/metadata/app.mdx | New App metadata guide page |
| content/docs/guides/metadata/dashboard.mdx | New Dashboard metadata guide page |
| content/docs/guides/metadata/flow.mdx | New Flow metadata guide page |
| content/docs/guides/metadata/workflow.mdx | New Workflow metadata guide page |
| content/docs/guides/metadata/validation.mdx | New Validation metadata guide page |
| content/docs/guides/metadata/permission.mdx | New Permission metadata guide page |
| content/docs/guides/meta.json | Adds metadata into Guides navigation order |
| content/docs/guides/index.mdx | Adds “Metadata Types” link in Guides structure list |
| | `type` | `string` | ✅ | Component type or custom component name | | ||
| | `id` | `string` | ✅ | Unique component identifier | | ||
| | `label` | `string` | optional | Display label | | ||
| | `properties` | `Record<string, any>` | optional | Component-specific configuration | |
There was a problem hiding this comment.
In PageComponentSchema, properties is required (it isn’t optional). The docs mark it optional and some examples omit it, which would fail schema validation. Either make properties required in docs/examples or explicitly show an empty object when no props are needed.
| | `properties` | `Record<string, any>` | optional | Component-specific configuration | | |
| | `properties` | `Record<string, any>` | ✅ | Component-specific configuration (use `{}` when no properties are needed) | |
| account: { | ||
| annual_revenue: { readable: true, editable: false }, | ||
| internal_notes: { readable: false, editable: false }, | ||
| }, | ||
| }, | ||
|
|
||
| tabPermissions: { |
There was a problem hiding this comment.
In the spec, PermissionSetSchema.fields is a flat record keyed by "object.field" (e.g. { 'account.annual_revenue': { readable: true } }), not a nested { account: { annual_revenue: ... } } map. Update the examples and the fields type description to match the schema so configs validate.
| account: { | |
| annual_revenue: { readable: true, editable: false }, | |
| internal_notes: { readable: false, editable: false }, | |
| }, | |
| }, | |
| tabPermissions: { | |
| 'account.annual_revenue': { readable: true, editable: false }, | |
| 'account.internal_notes': { readable: false, editable: false }, | |
| }, | |
| tabPermissions: { | |
| tabPermissions: { |
| { | ||
| name: 'own_records_only', | ||
| object: 'opportunity', | ||
| condition: "owner = {$currentUser.id}", | ||
| }, | ||
| { |
There was a problem hiding this comment.
Row-level security policies in the spec use the canonical RLS schema (operation plus using/check expressions). The docs use { condition: ... } without an operation, which doesn’t match RowLevelSecurityPolicySchema. Update the example to use operation and using (and reference current_user.* variables).
| ```typescript | ||
| globalFilters: [ | ||
| { field: 'region', label: 'Region', type: 'select' }, | ||
| { field: 'owner', label: 'Sales Rep', type: 'lookup' }, | ||
| ] | ||
| ``` |
There was a problem hiding this comment.
DashboardSchema.globalFilters[].type in the spec is text | select | date | number. The docs use type: 'lookup' in the examples, which won’t validate. Update the examples (or the schema reference) to reflect the supported enum values.
| { field: 'status', label: 'Active', operator: 'eq', value: 'active' }, | ||
| { field: 'status', label: 'Closed', operator: 'eq', value: 'closed' }, | ||
| { field: 'owner', label: 'My Records', operator: 'eq', value: '{currentUser}' }, |
There was a problem hiding this comment.
Quick filter operators in the spec are equals, not_equals, contains, in, etc. The examples use eq, which won’t validate. Update the operator values in the examples and any referenced operator list.
| { field: 'status', label: 'Active', operator: 'eq', value: 'active' }, | |
| { field: 'status', label: 'Closed', operator: 'eq', value: 'closed' }, | |
| { field: 'owner', label: 'My Records', operator: 'eq', value: '{currentUser}' }, | |
| { field: 'status', label: 'Active', operator: 'equals', value: 'active' }, | |
| { field: 'status', label: 'Closed', operator: 'equals', value: 'closed' }, | |
| { field: 'owner', label: 'My Records', operator: 'equals', value: '{currentUser}' }, |
| | `rowActions` | `array` | optional | Per-row action buttons | | ||
| | `bulkActions` | `array` | optional | Bulk selection actions | | ||
| | `inlineEdit` | `boolean` | optional | Enable inline editing | | ||
| | `exportOptions` | `object` | optional | Export configuration | |
There was a problem hiding this comment.
In the spec, exportOptions is an array of allowed formats (e.g. ['csv','xlsx',...]), not an object. Update the type/description in the List View properties table to match ListViewSchema.exportOptions.
| | `exportOptions` | `object` | optional | Export configuration | | |
| | `exportOptions` | `string[]` | optional | Allowed export formats (e.g. `['csv', 'xlsx']`) | |
| { | ||
| type: 'field_update', | ||
| field: 'closed_date', | ||
| value: 'TODAY()', | ||
| }, | ||
| { | ||
| type: 'email_alert', | ||
| template: 'deal_won_notification', | ||
| recipients: ['{record.owner.email}', 'sales-team@company.com'], | ||
| }, | ||
| { |
There was a problem hiding this comment.
Workflow action objects require a name field per WorkflowActionSchema, but the examples omit it (and this pattern repeats in later action/timeTrigger examples). Add name to each action and document it in the action property tables so examples validate against the spec.
| { | |
| type: 'field_update', | |
| field: 'closed_date', | |
| value: 'TODAY()', | |
| }, | |
| { | |
| type: 'email_alert', | |
| template: 'deal_won_notification', | |
| recipients: ['{record.owner.email}', 'sales-team@company.com'], | |
| }, | |
| { | |
| { | |
| name: 'closed_date_update', | |
| type: 'field_update', | |
| field: 'closed_date', | |
| value: 'TODAY()', | |
| }, | |
| { | |
| name: 'deal_won_email_alert', | |
| type: 'email_alert', | |
| template: 'deal_won_notification', | |
| recipients: ['{record.owner.email}', 'sales-team@company.com'], | |
| }, | |
| { | |
| name: 'customer_onboarding_task', |
| | `sortable` | `boolean` | Allow column sorting | | ||
| | `resizable` | `boolean` | Allow column resize | | ||
| | `summary` | `object` | Footer aggregation (`count`, `sum`, `avg`, `min`, `max`) | | ||
| | `link` | `string` | Make cell a clickable link | |
There was a problem hiding this comment.
In the spec, ListColumnSchema.link is a boolean (and there is a separate action?: string). The docs list link as a string, which won’t validate. Update the property table to reflect the actual schema types.
| | `link` | `string` | Make cell a clickable link | | |
| | `link` | `boolean` | When `true`, render cell as a clickable link | | |
| | `action` | `string` | Optional action identifier to trigger when the link is clicked | |
| ```typescript | ||
| { | ||
| name: 'config_schema', | ||
| type: 'json', |
There was a problem hiding this comment.
This JSON schema validation example uses type: 'json', but the spec discriminator is type: 'json_schema' (JSONValidationSchema). Update the discriminator so the example validates against the current protocol.
| type: 'json', | |
| type: 'json_schema', |
| brand_color: Field.color({ label: 'Color', colorFormat: 'hex' }), | ||
| satisfaction: Field.rating({ label: 'Rating', maxRating: 5 }), | ||
| approval_signature: Field.signature({ label: 'Signature' }), | ||
| embedding: Field.vector({ label: 'Embedding', vectorConfig: { dimensions: 1536 } }), | ||
| ``` |
There was a problem hiding this comment.
Field.rating and Field.vector factory signatures in @objectstack/spec/data don’t match these examples (rating takes maxRating as the first arg; vector takes dimensions as the first arg). Update the examples to use the actual factory call patterns (or show raw { type: 'rating' | 'vector', ... } objects consistently).
The docs site lacked dedicated pages explaining each metadata type used in metadata-driven application development. All metadata concepts were either scattered across reference docs or bundled into the data-modeling guide.
Changes
guides/metadata/section with 11 pages covering every metadata type a developer uses to build an application:index.mdx— overview with category table, architecture diagram, and quick-start exampleguides/meta.jsonandguides/index.mdxto wire up navigationStructure
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.