Skip to content

feat(spa): native Ea::Model pipeline replacing lutaml-uml SPA#20

Merged
ronaldtse merged 2 commits into
mainfrom
spa/native-ea-model-pipeline
Jul 19, 2026
Merged

feat(spa): native Ea::Model pipeline replacing lutaml-uml SPA#20
ronaldtse merged 2 commits into
mainfrom
spa/native-ea-model-pipeline

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Introduces a canonical domain model (Ea::Model) that both QEA and XMI sources harmonize into. The SPA is a one-way projection of that model. Architecture: hexagonal / ports & adapters.

Layers

  • Ea::Model::* — clean domain types (Package, Classifier hierarchy, Property, Operation, Relationship hierarchy, Annotation, TaggedValue, Stereotype, Diagram + DiagramElement + DiagramConnector + Waypoint). Polymorphic JSON round-trip via model_kind and relationship_kind discriminators.
  • Ea::Sources::Qea — Adapter + per-table builders. Validates against plateau-model/20251010_current_plateau_v5.1.qea (6 MB): 58 packages, 602 classifiers, 908 relationships, 205 diagrams with 14k waypoints, harmonized in ~12 s.
  • Ea::Sources::Xmi — Adapter + per-element builders. Same shape as QEA; produces structurally identical model instances.
  • Ea::Spa — projection layer (Projector, Skeleton, Shard, SearchIndex, PackageTree, LazyRef). Two output strategies: SingleFileStrategy and ShardedMultiFileStrategy.

CLI rework

ea spa FILE uses the native pipeline for both .qea and .xmi. Removes the --legacy and --config flags and the lutaml-uml static-site fallback. Single pipeline, single way of doing things.

Performance

Plateau v5.1 (6 MB QEA) end-to-end in ~17 s — was intractable via the QEA → UML transform path.

Release workflow patch

.github/workflows/release.yml: defaults acknowledge_breaking_in_patch to false (was true with a verbose description of an upstream bug). The breaking-change guard now runs by default.

Validation

2115 examples, 0 failures, 37 pre-existing pending. 16 specs in spec/ea/sources/qea/adapter_spec.rb validate against the real plateau v5.1 fixture.

TODO.refactor

12 TODO files written under TODO.refactor/ capturing the full vision; this PR lands #1, #2, #3, #4, #5, #6, #7, #8, #10. Deferred: #9 (frontend data contract), #11 (perf benchmark), #12 (lutaml-uml StaticSite fate).

Introduces a canonical domain model (Ea::Model) that both QEA and XMI
sources harmonize into. The SPA is now a one-way projection of that
model — not a re-modeling. Architecture: hexagonal / ports & adapters.

New layers:
- Ea::Model::* — clean domain types (Package, Classifier hierarchy,
  Property, Operation, Relationship hierarchy, Annotation,
  TaggedValue, Stereotype, Diagram + DiagramElement + DiagramConnector
  + Waypoint). Polymorphic JSON round-trip via model_kind and
  relationship_kind discriminators.
- Ea::Sources::Qea — Adapter + per-table builders, walks
  Ea::Qea::Database once. Validates against plateau v5.1 (6 MB QEA):
  58 packages, 602 classifiers, 908 relationships, 205 diagrams with
  14k waypoints, harmonized in ~12 s.
- Ea::Sources::Xmi — Adapter + per-element builders, walks
  Xmi::Sparx::Root. Same shape as QEA adapter; produces structurally
  identical model instances for the same conceptual source.
- Ea::Spa — projection layer (Projector, Skeleton, Shard, SearchIndex,
  PackageTree, LazyRef). Two output strategies: SingleFileStrategy
  and ShardedMultiFileStrategy.

CLI rework:
- `ea spa FILE` uses the native pipeline for both .qea and .xmi.
- Removes the --legacy and --config flags and the lutaml-uml
  static-site fallback. Single pipeline, single way of doing things.

Performance: plateau v5.1 (6 MB QEA) end-to-end in ~17 s, was
intractable via the QEA -> UML transform path.

Workflow patch: release.yml defaults
acknowledge_breaking_in_patch to false (was true) so the
breaking-change guard isn't bypassed by default.

Validation: 2115 examples, 0 failures, 37 pre-existing pending.
The sharded-mode default-output-path test copied the fixture into a
tmpdir before invoking the SPA command. On Windows GitHub runners
that path lives under D:/a/_temp and FileUtils.cp from the bundle-
installed fixture path fails with Errno::EACCES.

Pass the fixture directly and only vary the output path, which is
what the test was actually verifying.
@ronaldtse
ronaldtse merged commit b1f5a62 into main Jul 19, 2026
11 checks passed
@ronaldtse
ronaldtse deleted the spa/native-ea-model-pipeline branch July 19, 2026 15:25
ronaldtse added a commit that referenced this pull request Jul 19, 2026
Adds Ea::Svg::Renderer that consumes the umldi content (placed
element bounds + connector waypoints) captured in Ea::Model::Diagram
and emits standalone SVG. Coordinates are taken straight from the
source pixel space.

Architecture:
- Ea::Svg::BoundsCalculator — unions element rects and waypoint
  positions; normalizes EA's inverted rects (rectbottom < recttop)
- Ea::Svg::StyleResolver — translates EA packed style (BGR integer
  colors, line widths) to CSS-friendly SVG attributes
- Ea::Svg::ElementBox — renders one DiagramElement as a labeled box
- Ea::Svg::ConnectorPath — renders one DiagramConnector as a
  polyline through waypoints
- Ea::Svg::Renderer — orchestrates; emits standalone XML SVG

CLI: new `ea svg NAME FILE [--output=PATH]` command renders a
named diagram to disk.

Distinct from Ea::Diagram::SvgRenderer which operates on the legacy
Lutaml::Uml::Document pipeline. This module consumes the canonical
Ea::Model types only.

Also fixes the stale `does not expose --config` spec from PR #20
(we just reintroduced --config).
ronaldtse added a commit that referenced this pull request Jul 19, 2026
PR #20 removed the legacy --config flag because the lutaml-uml
static-site pipeline (which is what consumed it) was being dropped.
That also removed legitimate metadata customization for downstream
users like plateau-model.

This adds a native --config that:
- overrides Ea::Model::Metadata fields (title, description, version, ...)
- surfaces ui/appearance sections to the SPA skeleton as viewExtras
- works with both SingleFile and ShardedMultiFile output strategies

The SingleFileStrategy <title> tag now prefers ui.title (browser-tab
text) over metadata.title (model title), matching the prior UX.

Bumps version to 0.3.0 because the native pipeline + this flag are
incompatible with the 0.2.x lutaml-uml-based SPA default.
ronaldtse added a commit that referenced this pull request Jul 19, 2026
Adds Ea::Svg::Renderer that consumes the umldi content (placed
element bounds + connector waypoints) captured in Ea::Model::Diagram
and emits standalone SVG. Coordinates are taken straight from the
source pixel space.

Architecture:
- Ea::Svg::BoundsCalculator — unions element rects and waypoint
  positions; normalizes EA's inverted rects (rectbottom < recttop)
- Ea::Svg::StyleResolver — translates EA packed style (BGR integer
  colors, line widths) to CSS-friendly SVG attributes
- Ea::Svg::ElementBox — renders one DiagramElement as a labeled box
- Ea::Svg::ConnectorPath — renders one DiagramConnector as a
  polyline through waypoints
- Ea::Svg::Renderer — orchestrates; emits standalone XML SVG

CLI: new `ea svg NAME FILE [--output=PATH]` command renders a
named diagram to disk.

Distinct from Ea::Diagram::SvgRenderer which operates on the legacy
Lutaml::Uml::Document pipeline. This module consumes the canonical
Ea::Model types only.

Also fixes the stale `does not expose --config` spec from PR #20
(we just reintroduced --config).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant