Record
incubatingStatus of this Document
This report was published by the User Journal Graph Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups .
Title: org.openuji.specs.ujg.record.v1
Status: incubating implementation extension for self-contained single-record or detail projections carried in UJG Core extensions.
1. Namespace
Canonical namespace string:
org.openuji.specs.ujg.record.v1Payload location:
extensions["org.openuji.specs.ujg.record.v1"]Published JSON Schema:
https://ujg.specs.openuji.org/ed/ns/record.schema.json
2. Purpose
This extension describes how a node presents one record, entity, or detail view.
It exists so that generators can implement detail projections directly from a self-contained payload that answers:
what record is being projected,
what the read contract posture is,
which sections and properties are visible,
how loading, empty, and error cases should feel,
how refresh behaves,
which local action placeholders should appear,
which appearance roles matter.
It is intentionally separate from org.openuji.specs.ujg.collection.v1 so that record-style detail views stay
small and instantly understandable.
3. Scope
This extension covers:
record identity and source intent,
read timing and blocking posture,
sections and visible properties,
empty, loading, and error posture,
refresh posture,
local action placeholders,
appearance roles needed for generation.
The extension is self-contained. It may refer to UJG node IDs for follow-up transitions, but it does not depend on private IDs from other extensions.
4. Non-goals
This extension does not standardize:
API endpoints,
GraphQL documents,
SQL queries,
ORM relations,
framework detail-view components,
analytics schemas.
5. Primary Attachment Targets
StateTemplateCompositeState
State is the preferred host for effective record views. Template is the preferred reusable host
for shared detail layouts. CompositeState is the preferred host for subflow-wide defaults.
6. Secondary Attachment Targets
Journeyfor broad defaults such as loading posture or common appearance roles
7. Discouraged Or Disallowed Attachment Targets
Transitionis discouraged because transitions normally invoke actions rather than define record projections.OutgoingTransitionGroupis discouraged because it is not a record host.Routeis discouraged because routing metadata belongs in Routing.MessageBundleis disallowed in normal use.UJGDocumentis disallowed because Core extensions are node-scoped.
8. Inheritance Model
For a state-level record projection, generators should apply inheritance in this order:
Journeyeach enclosing
CompositeState, from outermost to innermostresolved
Template, iftemplateRefis presentthe local
State
Template inheritance is the main mechanism for reusable record layouts. State attachment is the main mechanism for effective record specialization.
9. Precedence And Override Rules
Use this precedence order:
StateTemplateinnermost
CompositeStateouter
CompositeStateJourney
Merge and replacement rules:
recordTypeRef,source,loadingPosture,emptyPosture,errorPosture, andrefreshare singular values or objects. The more specific value replaces the inherited one.sectionsmerges byname.within a merged section,
propertiesmerges byname.actionsmerges byname.appearanceRolesmerges by key.a more specific section, property, or action may suppress an inherited one by repeating the same identity and setting
disabled: true.
10. Property Vocabulary
recordTypeRef: identity of the projected record type. Expected shape: string. Allowed categories: published schema IDs, model IDs, or opaque external identifiers. Implementation intent: tells generators what kind of detail view this is.source: read contract posture. Expected shape: object withcontractRefand optionaltiming,blocking, andcacheHint. Allowed categories fortiming:startup,on-enter,on-visible,on-demand. Allowed categories forblocking:required,deferred,non-blocking. Allowed categories forcacheHint:none,request,session,stable,revalidate. Implementation intent: gives generators a transport-neutral read posture.sections: the visible sections of the record. Expected shape: array of section objects withnameand optionaltitleRole,properties,actions, anddisabled. Implementation intent: lets generators produce understandable detail layouts.loadingPosture: posture for loading presentation. Expected shape: string. Allowed categories:skeleton,spinner,placeholder,silent. Implementation intent: gives generators a generic loading presentation posture.emptyPosture: posture when no record can be shown. Expected shape: string. Allowed categories:blank,message,fallback,error. Implementation intent: distinguishes normal absence from failure.errorPosture: posture for read failure. Expected shape: string. Allowed categories:inline,banner,full-state,fallback. Implementation intent: helps generators present errors consistently.refresh: refresh posture. Expected shape: object with optionalmodeandtrigger. Allowed categories formode:none,manual,automatic,manual-and-automatic. Allowed categories fortrigger:pull,button,interval,visible. Implementation intent: describes whether and how the record can be refreshed.actions: local action placeholders. Expected shape: array of objects withnameand optionalkind,transitionRef,appearanceRole, anddisabled. Implementation intent: reserves space for node-local actions without defining their command contracts.appearanceRoles: semantic appearance bindings. Expected shape: object keyed by roles such assurface,header,value,meta, oremptyState. Implementation intent: gives generators stable presentation role names without raw CSS.
11. Recommended Controlled Values
Recommended section property kind values:
textnumbermoneydatestatusbadgelinkmedia
Recommended loadingPosture values:
skeletonspinnerplaceholdersilent
Recommended emptyPosture values:
blankmessagefallbackerror
12. Processing Model
A generator implementing this extension should:
Resolve the effective record payload using the inheritance and precedence rules above.
Resolve the effective
sourceposture and the normalized section and property structure.Apply loading, empty, error, refresh, action, and appearance posture.
Combine the resulting record projection with Templates for shared shells, with Routing for route entry, and with L10n when the node also has
copyRef.Materialize a target-specific detail view without changing graph behavior.
The graph remains the source of truth for navigation. This extension only describes the record projection and its local read posture.
13. Cross-Stack Interpretation Notes
Web: map to account pages, order detail pages, dashboards, or admin detail views.
Native: map to detail screens, cards, or expandable sections.
CMS: map to read-focused content detail or editorial preview surfaces.
Commerce: map to order detail, product detail, customer detail, or return detail views.
CLI or headless or background: map to structured terminal output, detail reports, or job detail projections.
14. Published JSON Schema
The published schema for this extension is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/record.schema.json.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/record.schema.json",
"title": "UJG Record Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"recordTypeRef": { "type": "string" },
"source": { "$ref": "#/$defs/source" },
"sections": {
"type": "array",
"items": { "$ref": "#/$defs/section" }
},
"loadingPosture": {
"type": "string",
"enum": ["skeleton", "spinner", "placeholder", "silent"]
},
"emptyPosture": {
"type": "string",
"enum": ["blank", "message", "fallback", "error"]
},
"errorPosture": {
"type": "string",
"enum": ["inline", "banner", "full-state", "fallback"]
},
"refresh": { "$ref": "#/$defs/refresh" },
"actions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"appearanceRoles": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"$defs": {
"source": {
"type": "object",
"additionalProperties": false,
"properties": {
"contractRef": { "type": "string" },
"timing": {
"type": "string",
"enum": ["startup", "on-enter", "on-visible", "on-demand"]
},
"blocking": {
"type": "string",
"enum": ["required", "deferred", "non-blocking"]
},
"cacheHint": {
"type": "string",
"enum": ["none", "request", "session", "stable", "revalidate"]
}
},
"required": ["contractRef"]
},
"section": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"titleRole": { "type": "string" },
"properties": {
"type": "array",
"items": { "$ref": "#/$defs/property" }
},
"actions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"property": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": {
"type": "string",
"enum": ["text", "number", "money", "date", "status", "badge", "link", "media"]
},
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"action": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": { "type": "string" },
"transitionRef": { "type": "string" },
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"refresh": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["none", "manual", "automatic", "manual-and-automatic"]
},
"trigger": {
"type": "string",
"enum": ["pull", "button", "interval", "visible"]
}
}
}
}
} {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/record.schema.json",
"title": "UJG Record Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"recordTypeRef": { "type": "string" },
"source": { "$ref": "#/$defs/source" },
"sections": {
"type": "array",
"items": { "$ref": "#/$defs/section" }
},
"loadingPosture": {
"type": "string",
"enum": ["skeleton", "spinner", "placeholder", "silent"]
},
"emptyPosture": {
"type": "string",
"enum": ["blank", "message", "fallback", "error"]
},
"errorPosture": {
"type": "string",
"enum": ["inline", "banner", "full-state", "fallback"]
},
"refresh": { "$ref": "#/$defs/refresh" },
"actions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"appearanceRoles": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"$defs": {
"source": {
"type": "object",
"additionalProperties": false,
"properties": {
"contractRef": { "type": "string" },
"timing": {
"type": "string",
"enum": ["startup", "on-enter", "on-visible", "on-demand"]
},
"blocking": {
"type": "string",
"enum": ["required", "deferred", "non-blocking"]
},
"cacheHint": {
"type": "string",
"enum": ["none", "request", "session", "stable", "revalidate"]
}
},
"required": ["contractRef"]
},
"section": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"titleRole": { "type": "string" },
"properties": {
"type": "array",
"items": { "$ref": "#/$defs/property" }
},
"actions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"property": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": {
"type": "string",
"enum": ["text", "number", "money", "date", "status", "badge", "link", "media"]
},
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"action": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": { "type": "string" },
"transitionRef": { "type": "string" },
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"refresh": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["none", "manual", "automatic", "manual-and-automatic"]
},
"trigger": {
"type": "string",
"enum": ["pull", "button", "interval", "visible"]
}
}
}
}
} 15. Minimal Example Payload
{
"@id": "urn:state:order-detail",
"@type": "State",
"extensions": {
"org.openuji.specs.ujg.record.v1": {
"recordTypeRef": "urn:model:order",
"source": {
"contractRef": "urn:contract:order-read",
"timing": "on-enter",
"blocking": "required",
"cacheHint": "revalidate"
},
"sections": [
{
"name": "summary",
"properties": [
{ "name": "orderNumber", "kind": "text" },
{ "name": "total", "kind": "money" },
{ "name": "status", "kind": "status" }
]
}
],
"loadingPosture": "skeleton",
"emptyPosture": "message",
"errorPosture": "banner",
"refresh": { "mode": "manual", "trigger": "button" },
"actions": [
{ "name": "download-receipt", "kind": "secondary", "transitionRef": "urn:transition:receipt-download" }
],
"appearanceRoles": {
"surface": "record-shell",
"header": "record-header"
}
}
}
} {
"@id": "urn:state:order-detail",
"@type": "State",
"extensions": {
"org.openuji.specs.ujg.record.v1": {
"recordTypeRef": "urn:model:order",
"source": {
"contractRef": "urn:contract:order-read",
"timing": "on-enter",
"blocking": "required",
"cacheHint": "revalidate"
},
"sections": [
{
"name": "summary",
"properties": [
{ "name": "orderNumber", "kind": "text" },
{ "name": "total", "kind": "money" },
{ "name": "status", "kind": "status" }
]
}
],
"loadingPosture": "skeleton",
"emptyPosture": "message",
"errorPosture": "banner",
"refresh": { "mode": "manual", "trigger": "button" },
"actions": [
{ "name": "download-receipt", "kind": "secondary", "transitionRef": "urn:transition:receipt-download" }
],
"appearanceRoles": {
"surface": "record-shell",
"header": "record-header"
}
}
}
} 16. Graduation Guidance
Thin parts that may later graduate into optional modules or shared references include:
a record type reference,
a read contract reference,
a refresh-mode reference.
The following should remain extension-only:
section and property projection layout,
empty and error posture,
local action placeholders,
appearance role maps.