Repository navigation
Align interoperability and role docs with the implementation - #48
Merged
Merged
Conversation
Spatial geometry now honours rotationZ. A shared oriented-box module (shared/spatial-geometry.ts, mirrored in frontend/src/services/spatial) builds each placed element's rotated footprint extruded over its vertical interval. The JS/OCL spatial helpers keep their names and signatures but use separating-axis overlap tests and exact convex-polygon clearance, so rotated elements no longer get axis-aligned answers. Metamodels gain spatialRules: noOverlap, minClearance, maxDistance, within, and adjacentTo over placed instances of a source and a target metaclass (subclasses included), in plan or volume mode. A pure evaluator (shared/spatial-rules.ts plus the frontend mirror) runs in browser validation, which marks both elements of an offending pair in 2D and 3D, and in the backend validation engine used by the headless pipeline. A parity test keeps the two copies identical and checks that they report the same issues. Rules are persisted in a new metamodels.spatialRules column, validated on create and update, carried through checkpoints and metamodel evolution (a rule on a removed class blocks the evolution), removed with a deleted class, and exported to Ecore as the EPackage annotation spatialdsl/spatialRules. The metamodel editor gains a Spatial Rules section with an add/edit dialog. The Smart Warehouse example declares a FixedEquipment supertype and four rules that its bundled model satisfies, and its unbounded controller references now use '*'.
The README still said .aird export was not implemented, while the code and the Sirius reference docs support exporting views to the .aird subset and a complete single-model Sirius project ZIP. The README now matches them. The Sirius file compatibility reference gains a construct-by-construct table of what Ecore and XMI import and export support, report, or ignore (packages, classes, inheritance, datatypes, enums, bounds, opposites, operations, generics, feature flags, annotations including spatial rules, xmi:id handling, cross-resource references, many-valued attribute values, and presentation data), derived from the import and export services. The metamodel guide links to it.
A newly registered account has the platform role VIEWER, which the roles guide described as unable to create or edit anything. Under project workspaces any signed-in user can create a project, becomes its OWNER, and holds every project capability there. Both guides now say so.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Several update, evolution, and Ecore-import paths can persist or accept invalid spatial rules.
3 open findings
What changed in this PR
Adds spatial-rule infrastructure from dependency #45 and aligns interoperability, role, lifecycle, and API documentation with implemented behavior.
Changes:
- Adds yaw-aware spatial geometry and declarative rule evaluation across frontend and backend.
- Persists, edits, validates, checkpoints, and exports spatial rules.
- Updates Sirius compatibility and project-role documentation.
| File | Description |
|---|---|
shared/types/index.ts |
Adds shared spatial-rule types. |
shared/spatial-rules.ts |
Implements shared rule validation and evaluation. |
shared/spatial-geometry.ts |
Implements oriented spatial geometry. |
README.md |
Updates spatial and Sirius capabilities. |
frontend/src/services/spatial/spatial-rules.ts |
Adds frontend rule evaluator mirror. |
frontend/src/services/spatial/spatial-geometry.ts |
Adds frontend geometry mirror. |
frontend/src/services/spatial/index.ts |
Exports spatial modules. |
frontend/src/services/model/model-validation.service.ts |
Integrates spatial-rule validation. |
frontend/src/services/metamodel/metamodel.service.ts |
Validates imported spatial rules. |
frontend/src/services/metamodel/metamodel-api-sync.service.ts |
Synchronizes spatial rules. |
frontend/src/services/metamodel/metaclass-crud.service.ts |
Removes rules for deleted classes. |
frontend/src/services/metamodel/ecore.service.ts |
Imports and exports rule annotations. |
frontend/src/services/diagram/view-validation.service.ts |
Marks all elements involved in issues. |
frontend/src/services/constraint/spatial.helpers.ts |
Makes constraint geometry rotation-aware. |
frontend/src/models/types.ts |
Adds frontend spatial-rule types. |
frontend/src/examples/data/smart-warehouse-metamodel.json |
Adds example hierarchy and rules. |
frontend/src/components/metamodel/SpatialRulesEditor.tsx |
Adds spatial-rule editor UI. |
frontend/src/components/metamodel/components/sidebar/MetamodelSidebar.tsx |
Exposes the editor in Constraints. |
frontend/src/__tests__/services/view-validation.test.ts |
Tests related-element markers. |
frontend/src/__tests__/services/spatial-rules.test.ts |
Tests rule semantics and configuration. |
frontend/src/__tests__/services/spatial-helpers.test.ts |
Tests rotation-aware helpers. |
frontend/src/__tests__/services/ecore-xmi-interop.test.ts |
Tests rule annotation interoperability. |
frontend/src/__tests__/components/SpatialRulesEditor.test.tsx |
Tests rule editor behavior. |
docs/user-guide/spatial-rules.md |
Documents spatial rules comprehensively. |
docs/user-guide/roles-and-sharing.md |
Clarifies new-account project rights. |
docs/user-guide/project-lifecycle.md |
Clarifies platform and project roles. |
docs/user-guide/metamodels.md |
Links spatial and compatibility guidance. |
docs/reference/sirius-file-compatibility.md |
Adds Ecore/XMI compatibility matrix. |
docs/reference/data-model.md |
Documents persisted rules. |
docs/reference/api.md |
Documents spatial-rule API fields. |
docs/README.md |
Adds spatial rules to documentation navigation. |
backend/src/services/sirius-interop.service.ts |
Exports rules in Sirius project Ecore. |
backend/src/services/pipeline/model-validation.engine.ts |
Evaluates rules headlessly. |
backend/src/services/pipeline/headless-pipeline.service.ts |
Maps persisted rules into pipelines. |
backend/src/services/metamodel.service.ts |
Persists and validates spatial rules. |
backend/src/services/lifecycle/project-checkpoint.service.ts |
Checkpoints and restores rules. |
backend/src/services/lifecycle/metamodel-evolution.service.ts |
Includes rules in evolution handling. |
backend/src/__tests__/services/spatial-rules-parity.test.ts |
Verifies frontend/backend parity. |
backend/src/__tests__/services/sirius-interop.service.test.ts |
Tests Sirius rule export. |
backend/src/__tests__/services/sharing.service.test.ts |
Updates metamodel fixtures. |
backend/src/__tests__/services/project-checkpoint.service.test.ts |
Tests rule checkpoint compatibility. |
backend/src/__tests__/services/pipeline-engines.test.ts |
Tests pipeline rule evaluation. |
backend/src/__tests__/services/metamodel.service.test.ts |
Tests persistence and validation. |
backend/src/__tests__/services/metamodel-evolution.service.test.ts |
Tests evolution impacts and hashes. |
backend/prisma/schema.prisma |
Adds the spatial-rules column. |
backend/prisma/migrations/20261011000000_add_metamodel_spatial_rules/migration.sql |
Migrates existing databases. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+378
to
+385
| asArray<SpatialRule>(next.spatialRules).forEach(rule => { | ||
| [rule?.sourceClassId, rule?.targetClassId].forEach(classId => { | ||
| if (typeof classId !== 'string' || nextClassNames.has(classId)) return; | ||
| const removedName = currentClassNames.get(classId); | ||
| blockers.push(removedName | ||
| ? `Spatial rule ${rule.name} references removed class ${removedName}; update or delete the rule before applying this evolution` | ||
| : `Spatial rule ${rule?.name || rule?.id} references unknown class ${classId}`); | ||
| }); |
Comment on lines
213
to
+221
| if (data.classes !== undefined) { | ||
| this.assertValidClassesVerticalPlacement(data.classes); | ||
| } | ||
| if (data.spatialRules !== undefined) { | ||
| const classes = data.classes !== undefined | ||
| ? data.classes | ||
| : (await prisma.metamodel.findUnique({ where: { id }, select: { classes: true } }))?.classes; | ||
| this.assertValidSpatialRules(data.spatialRules, classes); | ||
| } |
Comment on lines
+154
to
+165
| rules.push({ | ||
| id: uuidv4(), | ||
| name, | ||
| kind: parsed.kind, | ||
| sourceClassId, | ||
| targetClassId, | ||
| ...(parsed.distanceMm !== undefined && { distanceMm: parsed.distanceMm }), | ||
| ...(parsed.mode !== undefined && { mode: parsed.mode }), | ||
| severity: parsed.severity || 'error', | ||
| ...(parsed.message !== undefined && { message: parsed.message }), | ||
| ...(parsed.enabled !== undefined && { enabled: parsed.enabled }), | ||
| }); |
The warehouse example said a violation could be provoked in the 2D view, but 2D moves only change the 3D pose that rules check when an element's 2D and 3D plan positions coincide, which is not the case for the bundled examples. Say so, and point to the 3D view and its Position & Rotation fields instead.
The backend Dockerfile compiles src/, tests included, with only backend/ and shared/ in the image. The spatial rules parity test imported the frontend mirror and the warehouse fixtures statically, so the image build failed. Load those files at run time instead, as the Sirius fixture test does.
Metamodel evolution now runs the full rule validation (kind, distance, mode, severity, duplicate IDs) before a preview can be applied, a classes-only update checks the stored rules against the new classes, and Ecore import skips annotation rules that are not valid rules with a warning instead of importing them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Depends on #45 (its construct table lists the spatial rules annotation); this branch contains that commit. Review the commits after "Add declarative spatial rules and yaw-aware spatial geometry". Documentation only.
.airdexport was not implemented. The code (exportAird, project ZIP export) and both Sirius reference docs say otherwise; the README now matches them.docs/reference/sirius-file-compatibility.mdgains a construct-by-construct table of what import and export support, report, or ignore (packages and sub-packages, interfaces, inheritance, datatypes, enums, bounds, defaults, opposites, cross-resource references, operations, generics, feature flags, annotations includingspatialdsl/spatialRules,xmi:idhandling, many-valued attribute values, presentation data). It was derived fromecore.service.ts, the model XMI import/export services, and the Sirius project export, and checked against them. The metamodel guide links to it.VIEWER, which the roles guide described as unable to create anything. I verified on a local stack that aVIEWERcan create a project, becomes itsOWNERwith all 26 project capabilities, and can create metamodels (with spatial rules), models, and checkpoints there; only artifacts outside a project are refused (403). The roles guide and the project lifecycle guide now say so. No code change is needed for the "reviewers can do very little" complaint.