UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

167 lines (144 loc) 8.04 kB
# JOE Schema Summary — Rules and Prompts Purpose: Provide a consistent, agent‑friendly summary for each schema (including instance‑specific ones) so tools and UIs can reason without parsing full runtime schema files. These summaries are served by MCP hydrate and by GET `/API/schema/:name?summaryOnly=true`. ## What to include in every summary - description: One‑sentence explanation of what the schema represents - purpose: When/why to use it; context among related schemas - wip: true if the schema is under active development - source: 'core' | 'instance' (filled automatically; you can override) - labelField: Primary human label (prefer name title label) - defaultSort: { field, dir } sensible default (prefer joeUpdated desc; pages often path asc; posts often post_date desc) - searchableFields: Array of string field names that are good for text queries - allowedSorts: Whitelist of sortable fields agents should use - relationships: - outbound: Array of { field, targetSchema, cardinality } where cardinality is 'one' | 'many' (auto-generated from fields; see Relationships section below) - inbound: { graphRef: 'server/relationships.graph.json' } (do not hand‑maintain inbound; it's computed from the graph later) - joeManagedFields: ["created","joeUpdated"] (always include) - fields: Array of normalized field descriptors: - Required: name, type - Optional: isArray, isReference, targetSchema, enumValues, display, comment, tooltip, format Notes - display/comment/tooltip are enriched automatically at runtime from the schema’s field definitions; include them in the summary when they clarify usage. - For select fields, add enumValues when known (e.g., role, priority, content_type). ## Relationships (outbound) **Auto-generation**: The `relationships.outbound` array is automatically generated from fields in your schema definition that have `isReference: true` and a `targetSchema` value. Cardinality is determined automatically: - `isArray: true` or `type: 'objectList'` `cardinality: 'many'` - Single reference field `cardinality: 'one'` **How it works**: In your schema file, mark reference fields like this: ```javascript fields: [ { name: 'project', type: 'string', isReference: true, targetSchema: 'project' }, { name: 'members', type: 'string', isArray: true, isReference: true, targetSchema: 'user' } ] ``` The system will automatically generate: ```javascript relationships: { outbound: [ { field: 'project', targetSchema: 'project', cardinality: 'one' }, { field: 'members', targetSchema: 'user', cardinality: 'many' } ] } ``` **Manual override**: You can manually specify `relationships.outbound` in the `summary` block if you need to: - Add relationships not detected by field analysis (e.g., implicit relationships) - Correct incorrectly inferred relationships - Provide clearer field names or target schemas **Best practice**: Let automatic generation handle most cases. Ensure your schema fields are properly marked with `isReference: true` and `targetSchema`, and relationships will be generated automatically. Only manually specify if you need to override or add relationships not captured by field definitions. ## Cardinality guidance - A single reference (select/goto a single item) 'one' - Arrays, objectList, or multi‑select references 'many' ## Heuristics (when unsure) - labelField: name title label - defaultSort: joeUpdated desc; pages: path asc; posts: post_date desc - searchableFields: name, info, description, plus any user‑visible identifiers (code, slug, email) - allowedSorts: include dates (joeUpdated, created, due_date), labelField, and common categoricals ## Authoring prompt (for new instance‑specific schemas) Use this prompt to draft a `summary` block to paste into the schema file. ``` You are defining a curated summary for a JOE schema named <SCHEMA_NAME>. Return strictly a JSON object with these keys: { "description": "…", "purpose": "…", "labelField": "…", "defaultSort": { "field": "…", "dir": "asc|desc" }, "searchableFields": ["…"], "allowedSorts": ["…"], "relationships": { "outbound": [ { "field": "<field>", "targetSchema": "<schema>", "cardinality": "one|many" } ], "inbound": { "graphRef": "server/relationships.graph.json" } }, "joeManagedFields": ["created","joeUpdated"], "fields": [ { "name": "…", "type": "string|number|boolean|date-time|object|objectList|select|…", "isArray": false, "isReference": false, "targetSchema": null, "enumValues": [ ], "display": "…", "comment": "…", "tooltip": "…", "format": "date|date-time|…" } ] } Rules: - Only include fields that materially help an agent construct/validate objects or reason about references. - Prefer concise, high‑signal text for description and purpose. - Do NOT populate inbound manually; leave graphRef as is. - Include enumValues for selects where known; omit when unknown. - For relationships.outbound: Only specify manually if you need to override automatic detection. Otherwise, ensure your schema fields have `isReference: true` and `targetSchema` set, and relationships will be auto-generated. ``` ## Example (task) ``` summary: { description: "Scheduled unit of work tracked for users and projects.", purpose: "Use to plan and execute work; references status, project, members, tags.", labelField: "name", defaultSort: { field: "joeUpdated", dir: "desc" }, searchableFields: ["name","info","description","_id"], allowedSorts: ["joeUpdated","created","due_date","priority","name"], relationships: { outbound: [ { field: "status", targetSchema: "status", cardinality: "one" }, { field: "project", targetSchema: "project", cardinality: "one" }, { field: "members", targetSchema: "user", cardinality: "many" }, { field: "tags", targetSchema: "tag", cardinality: "many" } ], inbound: { graphRef: "server/relationships.graph.json" } }, joeManagedFields: ["created","joeUpdated"], fields: [ { name: "_id", type: "string" }, { name: "itemtype", type: "string" }, { name: "name", type: "string" }, { name: "status", type: "string", isReference: true, targetSchema: "status" }, { name: "project", type: "string", isReference: true, targetSchema: "project" }, { name: "members", type: "string", isArray: true, isReference: true, targetSchema: "user" }, { name: "tags", type: "string", isArray: true, isReference: true, targetSchema: "tag" }, { name: "priority", type: "number", enumValues: [1,2,3,1000] }, { name: "joeUpdated", type: "date-time" }, { name: "created", type: "date-time" } ] } ``` ## How to validate quickly - Open: `/API/schema/<name>?summaryOnly=true` - Check: - description/purpose read well - labelField exists in fields - allowedSorts are valid - **relationships.outbound entries match fields with `isReference: true`** (or are intentional overrides) - outbound list references real schemas - no inbound entries besides graphRef - joeManagedFields present ## Notes for maintainers - Runtime will enrich fields with display/comment/tooltip from the schema when available. - Inbound relationships are not hand‑maintained; a graph builder will populate the shared graph later. - For core vs instance: `source` is inferred automatically but can be overridden inside `summary` if needed. - **Relationships are auto-generated**: Ensure your schema fields are marked with `isReference: true` and `targetSchema` in the schema definition (not just in the summary). The system will automatically build `relationships.outbound` from these fields. Only manually specify `relationships.outbound` in the summary if you need to override or add relationships not captured by field definitions.