Skip to content

Relationships: add field/fieldOn support for parent-side wikilink arrays #50

@mindsocket

Description

@mindsocket

Problem

$metadata.relationships hardcodes 'parent' as the child-side field in both validation (validate-hierarchy.ts) and embedded parsing (parse-embedded.ts). This conflates relationship edges with hierarchy edges — parentNodeProps in _ost_tools_base.json defines parent as the hierarchy wikilink field, and it should remain reserved for that purpose.

Many schemas express relationships via parent-side wikilink arrays (e.g., Activity.tasks, Activity.outcomes). Previously these were silently skipped during relationship validation, and embedded nodes got a spurious parent field instead of populating the correct parent-side array.

The hierarchy edge system already supports field/fieldOn — relationships now have the same.

Solution

Added field (default: "parent") and fieldOn (default: "child") to RELATIONSHIP_SCHEMA.

fieldOn: "parent" (new)

  • parse-embedded: child node gets no parent field; [[Child Title]] is appended to the semantic parent node's rel.field array
  • validateRelationships: filters parent-type nodes; validates each rel.field array entry resolves to a node of rel.type

fieldOn: "child" (default, existing behaviour)

  • parse-embedded: sets schemaData[rel.field ?? 'parent'] on child instead of hardcoded schemaData.parent
  • validateRelationships: same logic, but uses rel.field ?? 'parent' instead of hardcoded 'parent'

Changes

  • src/metadata-contract.ts — Added field and fieldOn to RELATIONSHIP_SCHEMA
  • src/parse-embedded.tsfieldOn: "parent" support for list and table embedded nodes
  • src/validate-hierarchy.tsvalidateRelationships() branches on fieldOn
  • schemas/generated/_ost_tools_schema_meta.json — Regenerated
  • tests/validate-relationships.test.ts — Tests for fieldOn: "parent", custom field name, and missing-field skip behaviour

Example schema usage

{
  "parent": "Activities",
  "type": "Tasks",
  "field": "tasks",
  "fieldOn": "parent",
  "format": "list",
  "matchers": ["Tasks", "Roles"],
  "multi": true
}

With this configuration:

  • Embedded task items under an Activity's "Tasks" heading populate activity.tasks with [[Task Title]] wikilinks
  • Validation checks that each entry in activity.tasks resolves to a node of type Tasks
  • No spurious parent field is set on the task nodes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions