Skip to main content
Version: V2-Next

Artifact Relations Graph

Model Management artifacts form a typed graph. The graph is broader than the DataStructure dependency graph: schemas reference other schemas, mappings connect source and target DataStructures, pipelines wire sources, mappings and sinks, and DataSets aggregate all of those artifacts.

This concept separates the current implementation from the target API shape for a complete graph view.

Current State

Model Management already records most relation data durably.

Relation sourceStored edge typeMeaning
JSON Schema $ref inside a DataStructureschema-refDataStructure depends on another DataStructure
XSD xs:importxsd-importXSD-backed DataStructure imports another DataStructure namespace
Mapping sourcemapping-sourceMapping reads from a source DataStructure
Mapping targetmapping-targetMapping writes to a target DataStructure
Pipeline nodespipeline-nodePipeline uses a DataSource, Mapping or DataSink
DataSet *Refs arraysdataset-ref, datasource-ref, datasink-refDataSet contains or references member artifacts

The durable source is artifact_reference, described in PostgreSQL Artifact Registry. The table stores complete per-version edges, including cycles and unresolved targets. It preserves the authored target URN verbatim, including pinned versions and :latest.

HAL links already expose some of these relations:

  • GET /api/v1/datastructures?id=... links to dependency, dependent, impact, transitive dependency and view endpoints.
  • GET /api/v1/mappings?id=... links source and target to their DataStructures.
  • GET /api/v1/pipelines?id=... links referenced DataSources, DataSinks and Mappings.
  • GET /api/v1/datasets?id=... links member DataStructures, DataSources, DataSinks, Mappings and Pipelines.

The current public graph API is still narrower: the dependency endpoints under /api/v1/datastructures/* are DataStructure-centric and primarily serve schema-ref / xsd-import relationships. There is no single public endpoint yet that returns the full typed artifact graph including mapping, pipeline and dataset edges.

Relation Vocabulary

The public graph should expose relation semantics, not just storage row names. Storage names such as mapping-source remain useful internally, but clients need stable relation names that can be rendered as an ontology-like graph.

Public relationBacking edge(s)DirectionIntended graph meaning
depends-onschema-ref, xsd-importDataStructure -> DataStructureThe source type structurally depends on the target type
maps-frommapping-sourceMapping -> DataStructureMapping input DataStructure
maps-tomapping-targetMapping -> DataStructureMapping output DataStructure
transforms-toderived from mapping-source + mapping-target of the same MappingDataStructure -> DataStructure, via MappingSource instances can be transformed into target instances by a Mapping
usespipeline-nodePipeline -> referenced artifactPipeline uses a source, mapping or sink node
containsdataset-ref, datasource-ref, datasink-refDataSet -> member artifactDataSet groups artifacts into a model package
binds-tox-core-ref on DataSource/DataSink schema fieldsDataSource/DataSink -> DataStructureExternal endpoint is bound to a data shape

x-core-ref is an annotation used by CORE schemas to mark fields as artifact references. It is not a graph edge by itself until a concrete document is stored and the referenced field is extracted into artifact_reference.

Graph Shape

A graph response should keep artifacts as nodes and relations as typed edges. Mappings should remain first-class nodes; the derived transforms-to edge is a convenience edge for visualisation.

{
"root": "urn:core:platform:civitas:datastructure:common:RawReading:1.0.0",
"nodes": [
{
"id": "urn:core:platform:civitas:datastructure:common:RawReading:1.0.0",
"type": "datastructure",
"title": "RawReading",
"version": "1.0.0"
},
{
"id": "urn:core:platform:civitas:mapping:common:raw-to-observation:1.0.0",
"type": "mapping",
"title": "Raw to Observation",
"version": "1.0.0"
},
{
"id": "urn:core:platform:civitas:datastructure:common:Observation:1.0.0",
"type": "datastructure",
"title": "Observation",
"version": "1.0.0"
}
],
"edges": [
{
"from": "urn:core:platform:civitas:mapping:common:raw-to-observation:1.0.0",
"to": "urn:core:platform:civitas:datastructure:common:RawReading:1.0.0",
"rel": "maps-from",
"sourceType": "mapping-source"
},
{
"from": "urn:core:platform:civitas:mapping:common:raw-to-observation:1.0.0",
"to": "urn:core:platform:civitas:datastructure:common:Observation:1.0.0",
"rel": "maps-to",
"sourceType": "mapping-target"
},
{
"from": "urn:core:platform:civitas:datastructure:common:RawReading:1.0.0",
"to": "urn:core:platform:civitas:datastructure:common:Observation:1.0.0",
"rel": "transforms-to",
"via": "urn:core:platform:civitas:mapping:common:raw-to-observation:1.0.0",
"derived": true
}
]
}

API Target

The existing DataStructure graph endpoints should remain for focused schema workflows. A new artifact-level graph API should expose all relation types.

GET /api/v1 should advertise:

{
"_links": {
"relations": {
"href": "/api/v1/artifacts/relations{?id,direction,types,depth,derived}",
"templated": true
},
"graph": {
"href": "/api/v1/artifacts/graph{?id,direction,types,depth,derived}",
"templated": true
}
}
}

Every artifact response should include graph navigation:

{
"_links": {
"relations": { "href": "/api/v1/artifacts/relations?id=..." },
"graph": { "href": "/api/v1/artifacts/graph?id=...&depth=1" }
}
}

Resource-specific links can remain more readable:

  • DataStructure: dependencies, dependents, mappings-in, mappings-out, transforms-to, transformed-from.
  • Mapping: existing source and target, plus graph.
  • Pipeline: existing datasources, datasinks, mappings, plus graph.
  • DataSet: existing member links, plus graph.

GET /api/v1/artifacts/relations

Returns flat relation rows for one artifact.

Query parameters:

ParameterMeaning
idRequired artifact URN. Versioned, logical and :latest forms are accepted.
directionout, in or both; default both.
typesOptional comma-separated public relations or storage edge types.
depth1 by default. 0 returns only the root node metadata; values > 1 recurse.
derivedtrue by default. Include derived edges such as transforms-to.

Example row:

{
"from": "urn:core:platform:civitas:mapping:common:raw-to-observation:1.0.0",
"to": "urn:core:platform:civitas:datastructure:common:Observation:1.0.0",
"rel": "maps-to",
"sourceType": "mapping-target",
"referenceName": null,
"targetExists": true
}

GET /api/v1/artifacts/graph

Returns a node/edge graph for visualisation. It should use the same filters as /relations, but expand artifact metadata for each reached node.

This endpoint is the preferred basis for a frontend graph view. It can render:

  • structural DataStructure dependencies (depends-on)
  • mapping transformations (transforms-to, with the mapping as via)
  • pipeline wiring (uses)
  • DataSet packaging (contains)
  • source/sink data-shape bindings (binds-to)

Implementation Notes

The current database schema is sufficient for the base edges. The missing pieces are query and presentation layers:

  1. Add read methods around artifact_reference for outgoing and incoming edges with source artifact metadata and target metadata where resolvable.
  2. Add a relation mapper from storage edge types to public relation names.
  3. Derive transforms-to by joining mapping-source and mapping-target rows from the same Mapping version.
  4. Add DTOs such as ArtifactRelationDto, ArtifactGraphDto, GraphNodeDto and GraphEdgeDto in model-forge-api.
  5. Add ArtifactRelationsController under /api/v1/artifacts.
  6. Extend HalLinks with relations / graph links and optional DataStructure-specific mapping rels.
  7. Add Bruno tests for mapping graph traversal:
    • Mapping response links source and target.
    • DataStructure relation query returns incoming and outgoing mappings.
    • graph?derived=true returns transforms-to edges.
    • Existing schema dependency endpoints remain unchanged.

Compatibility

This is additive. Existing endpoint shapes and existing HAL rels remain valid. Clients that ignore _links are unaffected. Clients that already use DataStructure dependency endpoints can continue to do so; the new artifact graph API serves broader visualisation and ontology-style navigation.