Preserve editable routes across source projects and REST
This commit is contained in:
+53
-1
@@ -622,7 +622,8 @@ Studio profile; no running history state is persisted or synthesized.
|
||||
----------------------------------------------------
|
||||
|
||||
``diagram`` has name, identity, alias, description, ``layer`` (Oa by default),
|
||||
and ``projection`` (Overview by default). Other projections are Decomposition,
|
||||
``projection`` (Overview by default), and ``routes`` (empty list by default).
|
||||
Other projections are Decomposition,
|
||||
Allocation, FunctionalDataflow, Capabilities, and Traceability. Traceability diagrams can show both layers;
|
||||
other diagrams show their chosen layer.
|
||||
|
||||
@@ -653,6 +654,57 @@ Changing a node's diagram preserves the placement identity, alias, coordinates,
|
||||
size, collapse state, and attached artifacts. The destination must accept the
|
||||
element's layer and must not already contain another placement of that element.
|
||||
|
||||
Each ``routes`` entry is an EdgeRoute record with a required ``edge`` reference
|
||||
to an existing Relation or Trace, ``waypoints`` (default ``[]``), and ``label``
|
||||
(default ``none``). Route records have no separate UUID or alias. An edge occurs
|
||||
at most once in a diagram's route list; different diagrams MAY store independent
|
||||
routes for the same edge. List order and explicit empty entries are retained by
|
||||
source and JSON round trips, although list order has no routing meaning. Edges
|
||||
need not currently be visible in their diagram.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
routes [
|
||||
{ edge @report_exchange;
|
||||
waypoints [{ x 420; y 260; }, { x 690; y 260; }];
|
||||
label { fraction 0.55; offset { x 0; y -16; }; };
|
||||
}
|
||||
];
|
||||
|
||||
Waypoints are pinned absolute diagram positions in source-to-target traversal
|
||||
order; at most 128 are allowed per edge. Computed endpoints and automatic elbows
|
||||
MUST NOT be persisted as authored waypoints. A label record requires both
|
||||
``fraction`` (finite binary32 from 0 through 1, measured along the computed
|
||||
polyline's arc length) and ``offset`` (a relative x/y diagram displacement).
|
||||
All position/displacement components obey the coordinate bounds in section 2.
|
||||
An absent label uses automatic placement. Unknown fields, missing required
|
||||
nested fields, duplicate route edges, non-edge references and invalid numbers
|
||||
are structural errors. A pinned point that obstructs routing remains stored;
|
||||
geometric routing difficulty is reported separately from structural validity.
|
||||
Each EdgeRoute counts as one record against ``ParseLimits.max_records``; pinned
|
||||
points are bounded by the per-route limit and aggregate input byte limits.
|
||||
|
||||
``SetEdgeRoute { diagram, route }`` upserts an entry by edge identity, retaining
|
||||
the order and contents of unrelated entries. ``RemoveEdgeRoute { diagram, edge }``
|
||||
removes it; removing an absent entry is a no-op for an existing diagram and edge.
|
||||
The latter is the Reset routing operation. Either command participates in the
|
||||
same atomic transactions, validation and undo as other model edits. Deleting a
|
||||
relation or trace removes its routes in every diagram; reidentifying it updates
|
||||
route references without changing geometry. Folding, hiding, changing projection
|
||||
or relocating placements MUST NOT erase routing metadata. Group movement
|
||||
translates pins when both actual endpoint owners move by the same delta; label
|
||||
offsets remain relative. Raw ``EditNode`` and source position edits are exact
|
||||
record edits and do not implicitly translate pins.
|
||||
|
||||
This is an additive schema-3 field. Earlier schema-3 JSON/source that omits
|
||||
``routes`` loads as an empty list. Frozen schema-1 and schema-2 readers do not
|
||||
accept this new field; migration creates empty route lists. Source projects keep
|
||||
routes in their owning diagram declaration/file, resolve ``edge @alias`` across
|
||||
files, and retain route-entry comments by referenced edge identity when entries
|
||||
are reordered. The existing REST transaction endpoint accepts the same externally
|
||||
tagged command records with UUID references and conditional ETags; no separate
|
||||
routing endpoint or UI-only routing model exists.
|
||||
|
||||
``artifact`` has name, identity, alias, description, required ``owner`` ref,
|
||||
``relation`` (References, Satisfies, Verifies, Implements, DerivedFrom;
|
||||
default References), ``uri`` (default empty), ``revision`` (optional string),
|
||||
|
||||
@@ -1735,6 +1735,51 @@
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"EdgeLabel": {
|
||||
"type": "object",
|
||||
"description": "Authored label placement relative to the computed polyline. Both fields are required.",
|
||||
"properties": {
|
||||
"fraction": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"description": "Fraction of source-to-target polyline arc length."
|
||||
},
|
||||
"offset": {
|
||||
"$ref": "#/components/schemas/Position",
|
||||
"description": "Relative diagram-space displacement."
|
||||
}
|
||||
},
|
||||
"required": ["fraction", "offset"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"EdgeRoute": {
|
||||
"type": "object",
|
||||
"description": "One diagram's authored route for an existing Relation or Trace, including currently hidden edges. No separate identity. Only pinned points are stored; explicit empty routes are retained.",
|
||||
"properties": {
|
||||
"edge": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Existing Relation or Trace identity, never a node placement."
|
||||
},
|
||||
"waypoints": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/components/schemas/Position" },
|
||||
"maxItems": 128,
|
||||
"default": [],
|
||||
"description": "Absolute diagram positions in traversal order."
|
||||
},
|
||||
"label": {
|
||||
"oneOf": [
|
||||
{ "$ref": "#/components/schemas/EdgeLabel" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"required": ["edge"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Size": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -3445,6 +3490,12 @@
|
||||
"additionalProperties": {
|
||||
"$ref": "#/components/schemas/NodePlacement"
|
||||
}
|
||||
},
|
||||
"routes": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/components/schemas/EdgeRoute" },
|
||||
"default": [],
|
||||
"description": "Unique by edge identity within this diagram. Stored order is retained. Each entry counts against the total model record admission limit. Missing routes in earlier schema-3 models default to empty."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -4406,6 +4457,40 @@
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"SetEdgeRoute": {
|
||||
"type": "object",
|
||||
"description": "Upsert by edge identity; preserves unrelated route entries and order. Uses existing transaction validation and ETag checks.",
|
||||
"properties": {
|
||||
"diagram": { "type": "string", "format": "uuid" },
|
||||
"route": { "$ref": "#/components/schemas/EdgeRoute" }
|
||||
},
|
||||
"required": ["diagram", "route"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["SetEdgeRoute"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"RemoveEdgeRoute": {
|
||||
"type": "object",
|
||||
"description": "Reset to automatic routing. No-op if this existing diagram has no route for the existing edge.",
|
||||
"properties": {
|
||||
"diagram": { "type": "string", "format": "uuid" },
|
||||
"edge": { "type": "string", "format": "uuid" }
|
||||
},
|
||||
"required": ["diagram", "edge"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["RemoveEdgeRoute"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user