Skip to content

release: v7.6.0 — OCL pre/post end-to-end (metamodel + WME) and Full Project templates#129

Merged
ArmenSl merged 21 commits into
mainfrom
develop
May 7, 2026
Merged

release: v7.6.0 — OCL pre/post end-to-end (metamodel + WME) and Full Project templates#129
ArmenSl merged 21 commits into
mainfrom
develop

Conversation

@ArmenSl
Copy link
Copy Markdown
Collaborator

@ArmenSl ArmenSl commented May 7, 2026

Sync developmain for BESSER v7.6.0.

Summary

This frontend release ships the editor side of OCL preconditions and postconditions end-to-end, plus a Full Project template tab, modeling-perspective selection on project creation, and a new modifier that lets the modeling assistant author OCL constraints from natural language.

  • OCL constraint box now renders an italic stereotype badge above the body — «inv», «pre» <method-name>, «post» <method-name> — derived from the BOCL header text. The textbox carries the full BOCL block (context X (inv|pre|post) [name]: body); the backend parses the header tokens to route invariants onto domain_model.constraints and pre/post onto Method.pre / Method.post. No frontend metadata churn, no body-vs-header drift.
  • Optional description field on the constraint popup. The validator surfaces this as the violation reason in /validate-diagram output instead of the raw OCL.
  • "Library with OCL" structural-pattern template — eleven canonical OCL constraints (inv + pre + post on Book / Library / Author) so users get a working pre/post example one click away.
  • Full Project tab in the template library carrying multi-diagram bundles. Two starter bundles ship: Library Full Stack (class + GUI + REST API) and Personalized Gym Agent (full agent project with class + GUI + agent diagram).
  • Modeling-perspective selector on project create — workspace starts filtered to the diagram families the user intends to model.
  • Object diagram: generate objects + links from a referenced class so the user doesn't have to hand-construct every instance.
  • Workspace: diagram bridge wired up during project load (fixes a class of "diagram opens but feels frozen" bugs).
  • Perspectives: "Full Application" preset relabelled to "Full Web Application" so the label matches what the perspective selects.
  • Import refactor: project-import logic moved to shared/services for reuse across project hub and GitHub-import paths.
  • i18n: drop incomplete German locale.
  • Modeling assistant — NL→OCL (closes From NL to OCL B-OCL-Interpreter#5): ClassDiagramModifier gains an add_ocl_constraint case that consumes the new action emitted by the modeling-agent and spawns a ClassOCLConstraint element on the canvas linked to the target class via a ClassOCLLink. Requires the matching modeling-agent commit (BESSER-PEARL/modeling-agent@c0e47e8) deployed alongside.
  • Package: bump to 2.5.0.

Test plan

  • Unit tests pass.
  • Relevant Playwright E2E suite green.
  • Open the "Library with OCL" template — every constraint box renders with its «inv» / «pre» / «post» badge; description field round-trips.
  • Project hub: create a fresh project, perspective selector controls which diagram families are visible afterwards.
  • Templates: Full Project tab shows Library Full Stack and Personalized Gym Agent; loading either produces a multi-diagram workspace.
  • Object diagram: link a class element, "generate from class" produces matching object instances.
  • Project load: open a saved project — workspace is responsive, no diagram-bridge timing bug.
  • Modeling assistant: with a class diagram open, type "add a constraint that a Library always has at least one Book" — a constraint box appears linked to Library with the «inv» badge and the BOCL text.
  • Modeling assistant: NO constraint box appears when the user asks for non-OCL changes (e.g., "add a Book class with title and pages").

Related

Backend release PR: BESSER-PEARL/BESSER#531

Modeling-agent commit (deploy alongside): BESSER-PEARL/modeling-agent@c0e47e8

The frontend does not get its own tag or gh release — it rides along with the BESSER v7.6.0 version.

ArmenSl and others added 21 commits May 5, 2026 12:55
Extend ClassOCLConstraint with three new fields so the editor can
distinguish invariants, preconditions, and postconditions on the same
visual element:

- kind: 'invariant' | 'precondition' | 'postcondition' (default invariant)
- targetMethodId: element id of the method a pre/post is anchored on
- constraintName: optional user-supplied name (auto-generated otherwise)

The constraint textbox now stores the OCL body only (e.g. "self.pages > 0").
The header (context X inv name: / context X::m(p:T) pre:) is reconstructed
by the backend at parse time using the linked class and the picked method,
so renaming/rerouting the link automatically follows.

Popup gains:
- Kind dropdown.
- Method picker (when kind != invariant), populated from the linked class's
  ownedElements filtered to ClassMethod, via mapStateToProps.
- Optional Name field.
- Inline notice when no class is linked or the linked class has no methods.
- Orphan warning when the previously selected method element no longer
  exists.

Canvas component renders a stereotype badge ("inv" / "pre" / "post") and
the target method name above the body, plus a red border + warning glyph
when the box is orphaned.

Default-and-omit on serialize keeps legacy diagrams (no kind set) byte-stable
on round-trip until they are explicitly edited.
Drop the kind dropdown, method picker, name field, and stereotype badge
introduced in the previous commit. Revert the ClassOCLConstraint element
to its pre-iteration shape: a single ``constraint: string`` field holding
the full OCL block.

Driver: Jordi's downstream metamodel work consumes the full OCL source
text to extract the constraint name and check duplication. Splitting
that text into body + metadata fields hid the name from his parser, so
the pivot puts the canonical form back into the user's hands:

  context Book inv book_pages_positive: self.pages > 0
  context Book::decrease_stock(qty: int) pre: qty > 0
  context Book::decrease_stock(qty: int) post: self.stock >= 0

The popup is now a plain textarea + color + delete (matching the shape
that existed before this branch). Routing into ``Method.pre`` /
``Method.post`` happens entirely on the backend by parsing the OCL
header tokens; no frontend metadata is needed.

Files reverted:

* ``uml-class-ocl-constraint.ts`` — IUMLClassOCLConstraint goes back to
  ``constraint: string`` only. ``kind`` / ``targetMethodId`` /
  ``constraintName`` / ``OCLConstraintKind`` are removed.
* ``uml-class-ocl-constraint-update.tsx`` — drop the kind dropdown,
  method picker, name field, ``mapStateToProps`` connection, and orphan
  notice rendering. Restore the simple textarea-based popup.
* ``uml-class-ocl-constraint-component.tsx`` — drop the stereotype badge
  and orphan-glyph rendering. Canvas just shows the OCL text.
Parse the constraint text in the canvas component and render a small
italic badge above the body to give a visual cue of the OCL kind:

  «inv»                 — invariant
  «pre» <method-name>   — precondition on a method
  «post» <method-name>  — postcondition on a method

Read-only and derived from the text — the constraint string itself
remains the only source of truth, so there's no popup metadata, no
round-trip churn, and no risk of badge/text drift. When the text
doesn't match the BOCL header regex (empty or malformed), no badge
renders.
Drop a structural-pattern template that ships pre-populated with eleven
canonical full-text OCL constraints — seven invariants on Book / Library
/ Author, plus preconditions and a postcondition on
Book::decrease_stock(qty: int) and a precondition on
Library::cheapest_book_by(author: Author). The constraints exercise:

* simple comparisons (``self.pages > 0``),
* string size (``self.title.size() > 0``),
* collection size via the arrow form (``self.books->size() > 0``),
* method-parameter references inside pre/post (``self.stock >= qty``).

Every constraint validates cleanly through the backend's
``process_class_diagram`` path, so loading the template into the editor
yields zero OCL warnings out of the box. Useful both as a learning
example for new users and as smoke-test fodder for OCL-related changes.

Files:
* ``packages/webapp/src/main/templates/pattern/structural/Library_OCL.json``
  — the template model JSON.
* ``software-pattern-types.ts`` — adds ``LIBRARY_OCL = 'Library with OCL'``
  to the enum.
* ``template-factory.ts`` — imports the JSON and wires the new case
  into ``createSoftwarePattern``, reusing ``SoftwarePatternCategory.STRUCTURAL``.
…eate

Surface the modeling-perspective choice in ProjectHubDialog (Create and
From-Spreadsheet flows) instead of only in Settings. Plumbs an optional
PerspectiveSettings through createDefaultProject → createNewProject →
createProjectThunk → useProject.createProject. Defaults to 'all' so
existing behavior is preserved when no preset is picked.

UI cleanup on the Create step: drop the side Recent Projects card,
move Back to the bottom, and tighten paddings/gaps so the Create
button is visible without scrolling.

Closes #125
Introduce a 'Full Project' category in the Template Library alongside the
existing per-diagram pattern categories. A Full Project template carries an
entire V2 project export envelope and, on load, materializes a brand-new
project via the same JSON import path the user-facing Import flow uses.

Wiring:
- New SoftwarePatternCategory.FULL_PROJECT and FULL_PROJECT_DIAGRAM_TYPE
  sentinel.
- TemplateDiagramType widened to allow the sentinel.
- TemplateFactory exposes LIBRARY_FULL_STACK, the first bundled project.
- TemplateLibraryDialog adds the new tab, branches doLoadTemplate through
  importProjectFromJson + loadProjectThunk, and skips the per-diagram
  replace/new-tab confirm (always a fresh project).

Card UI for Full Project tiles summarizes which diagrams the bundle contains
(e.g. 'Class · Agent · GUI') instead of a single diagram-type label.

Ships templates/pattern/project/library_full_stack.json — a Library
management system with class diagram, agent, and GUI no-code page (with
the agent component) wired together as the seed full-project template.
Pairs with the backend ``Constraint.description`` field added in
BESSER#499 — surfaces a plain-language explanation alongside the raw
OCL expression in the validator output.

- Editor: ``ClassOCLConstraint`` now carries ``description`` (serialized
  to/from JSON, default empty), so projects round-trip the field
  through BUML→JSON→BUML.
- Popup: small textarea labelled "Description (shown to end-users when
  validation fails)" sitting below the OCL textarea. Updates write
  through the same ``UMLElementRepository.update`` path as the
  constraint text.

Inline ``--`` comments inside the OCL block still take precedence over
this field at the backend (per-constraint comment beats per-element
default), so users who prefer the inline shape keep working.
Adds a "Generate" button beside the Class Diagram reference picker
visible only when the active diagram is an Object Diagram. Clicking
it scaffolds:

- One ObjectName instance per concrete Class in the referenced class
  diagram (skips AbstractClass and Enumeration).
- One ObjectAttribute per ClassAttribute, with realistic placeholder
  values: source ``defaultValue`` first, then a name- and type-aware
  default ('25' for ``age``, ``'alice@example.com'`` for ``email``,
  enum-literal lookup for custom types like ``genre = Poetry``,
  ``2026-01-01`` for ``date`` etc.). Strings are unquoted so the
  validator's date type-check accepts them.
- One ObjectLink per class-level association (Bidirectional /
  Unidirectional / Aggregation / Composition). Inheritance and
  realization are skipped — they have no runtime instance.

Additive by design: existing canvas objects keyed by ``classId`` are
preserved (skipped for re-instantiation) and existing
``ObjectLink``s keyed by ``associationId`` aren't duplicated, so
re-clicking after manual edits is safe.

Pairs with the OCL pre/post backend work (BESSER#529): users can now
populate an Object Diagram in one click to syntax-check + evaluate
class invariants against real instances without hand-typing each
slot.
Bundles an agent diagram + two user diagrams as a ready-to-load
multi-diagram project under the Full Project category.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UserDiagram and ObjectDiagram both render against a model the editor reads
from a shared diagramBridge — the user metamodel for User, the referenced
ClassDiagram for Object. That setup only happened inside switchDiagramTypeThunk,
so projects loaded via loadProjectThunk (JSON import, full-project template,
recent project switch) opened with an empty palette when the active diagram
was a UserDiagram or ObjectDiagram.

Extract the bridge-setup into a helper and call it from both thunks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TemplateLibraryDialog imported from features/import, violating the
feature-isolation rule. Move the project-import functions from
features/import/useImportProject.ts to shared/services/project-import/
projectImport.ts, drop the unused loadJSZip helper, and repoint all
three consumers (TemplateLibraryDialog, ProjectHubDialog,
useGitHubBumlImport).
…ical thunk

The create-project flow can't reuse applyPerspectivePresetThunk because
the project doesn't exist yet at that point. Document this so future
contributors keep the two paths in lockstep when the preset-to-settings
mapping changes.
The German translation file was never used end-to-end and the editor
ships only English UI. Drop de.json, the de member of the Locale enum,
and its dictionary entry; update CLAUDE.md accordingly.
…te-project

feat(project-hub): allow selecting modeling perspective on project cr…
feat(templates): add Full Project tab with multi-diagram bundles
Raw <text> with element.textColor bypasses the styled-components theme
when textColor is unset. Provide 'currentColor' as fallback per the
custom-SVG rendering guidance in CLAUDE.md so the badge stays visible
in both light and dark themes.
feat(wme): show OCL kind badge + add 'Library with OCL' template
The modeling-agent (BESSER-PEARL/modeling-agent@c0e47e8) now emits a new
'add_ocl_constraint' action in its modifications array when a user asks
the assistant for an OCL invariant, precondition, or postcondition.
ClassDiagramModifier consumes the action by spawning a
ClassOCLConstraint element on the canvas linked to the target class
via a ClassOCLLink relationship.

Shape:
  {
    "action": "add_ocl_constraint",
    "target": { "className": "Library" },
    "changes": {
      "constraint": "context Library inv at_least_one_book: self.books->size() > 0",
      "text": "A library always has at least one book"
    }
  }

Changes:

- ModelModification.action union gains 'add_ocl_constraint'.
- ModificationChanges gains an optional 'constraint' string carrying the
  full BOCL block. The existing 'text' field doubles as the plain-
  language description surfaced when validation fails.
- ClassDiagramModifier.canHandle and the switch in applyModification
  pick up the new action; addOclConstraint() builds the constraint
  element + link, positioning the box to the right of the anchor class.
- The constraint and link element shapes match what
  uml-class-ocl-constraint.ts and uml-class-ocl-link.ts expect, so the
  rendered box gets the canonical stereotype-badge treatment introduced
  in v7.6.0.

Implements BESSER-PEARL/B-OCL-Interpreter#5. Pre-flight backend
validation (call /validate-diagram before writing) is a known follow-up;
malformed BOCL still surfaces via the post-hoc validator path
(PR #529 backend).
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.

From NL to OCL

2 participants