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 source | Stored edge type | Meaning |
|---|---|---|
JSON Schema $ref inside a DataStructure | schema-ref | DataStructure depends on another DataStructure |
XSD xs:import | xsd-import | XSD-backed DataStructure imports another DataStructure namespace |
Mapping source | mapping-source | Mapping reads from a source DataStructure |
Mapping target | mapping-target | Mapping writes to a target DataStructure |
| Pipeline nodes | pipeline-node | Pipeline uses a DataSource, Mapping or DataSink |
DataSet *Refs arrays | dataset-ref, datasource-ref, datasink-ref | DataSet 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=...linkssourceandtargetto 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 relation | Backing edge(s) | Direction | Intended graph meaning |
|---|---|---|---|
depends-on | schema-ref, xsd-import | DataStructure -> DataStructure | The source type structurally depends on the target type |
maps-from | mapping-source | Mapping -> DataStructure | Mapping input DataStructure |
maps-to | mapping-target | Mapping -> DataStructure | Mapping output DataStructure |
transforms-to | derived from mapping-source + mapping-target of the same Mapping | DataStructure -> DataStructure, via Mapping | Source instances can be transformed into target instances by a Mapping |
uses | pipeline-node | Pipeline -> referenced artifact | Pipeline uses a source, mapping or sink node |
contains | dataset-ref, datasource-ref, datasink-ref | DataSet -> member artifact | DataSet groups artifacts into a model package |
binds-to | x-core-ref on DataSource/DataSink schema fields | DataSource/DataSink -> DataStructure | External 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.
Root Links
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
}
}
}
Single Artifact Links
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
sourceandtarget, plusgraph. - Pipeline: existing
datasources,datasinks,mappings, plusgraph. - DataSet: existing member links, plus
graph.
GET /api/v1/artifacts/relations
Returns flat relation rows for one artifact.
Query parameters:
| Parameter | Meaning |
|---|---|
id | Required artifact URN. Versioned, logical and :latest forms are accepted. |
direction | out, in or both; default both. |
types | Optional comma-separated public relations or storage edge types. |
depth | 1 by default. 0 returns only the root node metadata; values > 1 recurse. |
derived | true 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 asvia) - 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:
- Add read methods around
artifact_referencefor outgoing and incoming edges with source artifact metadata and target metadata where resolvable. - Add a relation mapper from storage edge types to public relation names.
- Derive
transforms-toby joiningmapping-sourceandmapping-targetrows from the same Mapping version. - Add DTOs such as
ArtifactRelationDto,ArtifactGraphDto,GraphNodeDtoandGraphEdgeDtoinmodel-forge-api. - Add
ArtifactRelationsControllerunder/api/v1/artifacts. - Extend
HalLinkswithrelations/graphlinks and optional DataStructure-specific mapping rels. - Add Bruno tests for mapping graph traversal:
- Mapping response links
sourceandtarget. - DataStructure relation query returns incoming and outgoing mappings.
graph?derived=truereturnstransforms-toedges.- Existing schema dependency endpoints remain unchanged.
- Mapping response links
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.