intent: the glue's expression keys carry readings, not Java - the mapped values, the Calc guards, the print SDK calls and the ternaries (#7425) - #7487
Open
delchev wants to merge 14 commits into
Conversation
…ped values, the Calc guards, the print SDK calls and the ternaries (#7425) After the literal and builder-chain tiers of #7406 moved to JavaLiterals, the .glue still carried Java SOURCE in every expression key: a mapped value's `expr` (a create-from's fieldAssignments / itemFieldAssignments / itemLines, a schedule's genFieldAssignments / genChildren / genUnique, a posting's headerAssignments / itemRows, a posts: rule's assigns, a prompt: field's conversion), every guard (a row's `guard`, a transition's `guardExpr`, the event axis's `guardExpression`), the print SDK calls (`attachLanguageExpression` / `attachFileNameExpression`, a snapshot's `languageExpression` / `fileNameExpression`), a timer's `dueExpression` and the `conditionalRuleGuards` ternaries - ternaries, Calc.eval invocations, boxed equalities and string concatenations over SDK calls in the process description every template reads. Each is now a reading: a `kind`-tagged map of the authored facts, built through the package-private `Readings` factory and carried under `reading`, `guardReading`, `guardTerms` (the typed terms CheckSupport already produces, or the untyped spelling-inferred ones for a trigger / wait / register lookup), `due`, `attachLanguage` / `attachFileName`, `language` / `fileName`. The Java appears one layer out, in ide-template's new `JavaExpressions` - a closed vocabulary (read, hop, local, string, number, boolean, null, now, calc, text, concat, negate, convert, calcCompare, ruleCase, defaultLanguage, languageFrom, part, first, numberOrId, due) rendering exactly what the generator used to write, so the generated handlers are byte-identical. GlueGenerator renders at bind time and derives `conditionalRuleGuards` from the cells carrying a ruleCase; every binder falls back to the rendered key an older .glue carries, so an unregenerated project renders byte-identically. The now-unused Java renderers (NotificationSupport.guard, CheckSupport.condition/javaCondition, PostSetSupport.expression, FileNameSupport's helper calls) are gone. Verified: engine-intent unit suite (1334) and ide-template (192) green; IntentEngineIT (its glue assertion now pins that none of the rendered keys and no Calc.eval appear), IntentEmissionCoverageIT (compiles and runs the generated handlers) and ModelGenerationIT (regenerates from a pre-split orders.glue, the fallback path) green; formatter:validate clean with the cache wiped; the release-profile javadoc build of both modules clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t/alternative (#7488) (#7489) A notify block's body was always one text/plain part, so an application mailing people outside the organisation had no declared way to send a styled message short of replacing the step with a hand-written delegate. A notify block now takes an optional `html:` beside `body`, at every call site (notifications[], schedules[].notify, transitions[].notify, a serviceTask's args.notify, inside a forEach): - parser: html requires body and may not be blank; its placeholders go through the same escalation / record-scope / cross-model checks body does - generator: an htmlExpression resolved by the same resolver as the body, every interpolated value (deep links included) wrapped in the new SDK org.eclipse.dirigible.sdk.mail.Html.escape; the authored markup literal. Emitted only when declared, so a block without html is byte-identical - templates: Send / Transition / Notification / Job add a text/html part - MailClient: a text/plain and a text/html part are wrapped in one multipart/alternative (plain first) inside the mixed container, in the position of the first text part; a single text part is added as before. An html part without a charset is now sent as UTF-8 Verified: unit suites of api-modules-java, api-mail, ide-template and engine-intent (new HtmlTest, MailClientAlternativeTest, GlueNotifyHtmlTest); IntentEmissionCoverageIT (compiles and runs the generated html parts at all four call sites, incl. a fan-out) and IntentEngineIT; formatter:validate with the cache wiped; release-profile javadoc on the api modules. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…7486) Bumps com.sap.cloud.db.jdbc:ngdbc from 2.30.7 to 2.30.11. --- updated-dependencies: - dependency-name: com.sap.cloud.db.jdbc:ngdbc dependency-version: 2.30.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…7490) Bumps [com.icegreen:greenmail](https://github.com/greenmail-mail-test/greenmail) from 2.1.13 to 2.1.14. - [Release notes](https://github.com/greenmail-mail-test/greenmail/releases) - [Commits](greenmail-mail-test/greenmail@release-2.1.13...release-2.1.14) --- updated-dependencies: - dependency-name: com.icegreen:greenmail dependency-version: 2.1.14 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…7485) Bumps software.amazon.awssdk:bom from 2.55.0 to 2.55.1. --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-version: 2.55.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps `selenide.version` from 7.18.1 to 7.18.2. Updates `com.codeborne:selenide` from 7.18.1 to 7.18.2 - [Release notes](https://github.com/selenide/selenide/releases) - [Changelog](https://github.com/selenide/selenide/blob/main/CHANGELOG.md) - [Commits](selenide/selenide@v7.18.1...v7.18.2) Updates `com.codeborne:selenide-core` from 7.18.1 to 7.18.2 - [Release notes](https://github.com/selenide/selenide/releases) - [Changelog](https://github.com/selenide/selenide/blob/main/CHANGELOG.md) - [Commits](selenide/selenide@v7.18.1...v7.18.2) --- updated-dependencies: - dependency-name: com.codeborne:selenide dependency-version: 7.18.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.codeborne:selenide-core dependency-version: 7.18.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… pattern: and expect the process delete guard (#7411) (#7481) The generated <module>.test manifest describes what the app promises; three of those promises were missing from it, so the generic REST/UI flows reported a correct module as broken. - A `number:` field is the platform's: the DAO stamps it and then PRESERVES the column, so the runner - which picks the first long string field as the value it flips to prove an update landed - wrote "APPTEST-X-UPD" and read "APPTEST-X" back on every document module. The EDM already marks that field `isReadOnlyProperty` (as it does a uuid), and the manifest now reads both attributes back off the `.model` rather than re-deriving them, so a field with no editable input in the generated form has none in the manifest either. The handle additionally skips a `pattern:` field: the flow's own suffix would break the shape the controller enforces. - A `pattern:` field (an authored regex, or the address regex behind `format: email`) travels as the field's `pattern`, and the sample generator trades the marker value for the first candidate that matches it and fits the declared length - an address-shaped value, the alphanumeric token, a numeric code. A pattern nothing matches keeps the marker, so the controller's own 400 names the field and the regex. - An entity whose process declares `whenDeleted: refuse` (#7074) carries `deleteGuardedByProcess`. The REST flow asserts what actually happened - a refused delete leaves the record served, a clean one 404s (the instance may already have finished) - and the UI walk stops before the delete leg, whose only outcome is a toast. Verified: the engine-intent unit suite (1331 tests) including a new case over the exact `.model` attributes the EDM emits for those three; `IntentEngineIT #generate_writes_all_model_files_into_the_workspace_project`, which now asserts the manifest carries the email regex end to end through the real `.model` read-back and that a numeric display format does not. The JS half was exercised under node against the email / numeric / alphanumeric / unsatisfiable / unparsable patterns; there is no JS test harness in this repo to keep that in. Fixes #7411 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…er child (#7448) (#7480) A capacity-bearing roll-up stamps an overdraw guard on its CHILD entity. The entity carried a SINGLE `rollupGuard`, so a junction - both of whose parents are capacities, the case the guard exists for - got only the guard of whichever declaration came first. The other roll-up generated its sum column, balance column and four handlers normally, with nothing in the output saying its guard was missing: the model read as guarded, the runtime was not, and 6.00 could be allocated out of a 5.00 payment. The guard is now a list. `EdmIntentGenerator` collects one guard per capacity-bearing roll-up naming the entity (deduplicating an identical one) and emits `rollupGuards`; `Repository.java.template` renders a block per guard on both write paths - each block scopes its own locals, so the names do not collide - and imports each DISTINCT local parent once. A `.model` written before this carries the singular key; `ModelGenerator` normalizes it into the list, so an application regenerated from an old `.model` keeps the guard it had, and `transform-edm.js` still parses the singular attribute back into an object. Verified: - engine-intent unit suite 1333/1333, including EdmRollupGuardTest's new cases: a junction carries both guards, declaration order decides only their order, two roll-ups over the same relation and capacity share one guard. - RollupGuardCrossModelTemplateIT 6/6: a local and a foreign guard render side by side, and a shared local parent is imported exactly once. - IntentEmissionCoverageIT green: the fixture's PledgePayment now draws on its pledge's total AND a fund's budget, the generated app COMPILES with both guards, and over REST the second capacity refuses the overdraw (400 "PledgeFund capacity exceeded") that used to return 200. - EdmModelRoundTripIT 2/2: rollupGuards survives the .edm save-regenerate cycle. - ide-template unit suite 176/176; formatter:validate green with the cache wiped. Fixes #7448 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…, pinned and documented (#7450) (#7479) #7450 reports a gated refusal crossing an async delegate boundary coming back as 500 instead of the 400 the in-thread path uses. Measured, the boundary is not what decides it - the exception TYPE is, and it decides the same way on both sides: - `ClientValidationFailure` recognises `org.eclipse.dirigible.sdk.db.ValidationException` (and subclasses) anywhere in the cause chain, and `BpmInboxEndpoint` answers 400 with the authored message; the `ControllerInvoker` maps the same type the same way. - Anything else is a server fault by construction and stays a 500 - the platform has nothing else to tell a refusal from a breakage by. The reported shape refuses with an `IllegalStateException` (`base-inventory`'s `NegativeStockGuard`), which is a 500 in the caller's own thread too. The fleet comparisons that answered 400 were `checks:` gates, i.e. `ValidationException`. So there is no status to re-raise differently; what was missing is that the rule is nowhere stated for the one author who has to obey it, and nothing pinned it end to end. - `java-assistant-guide.md` gains the `JavaDelegate` bullet next to the `@Controller`, `JobHandler` and `MessageHandler` ones: a refusal the person can act on must be a `ValidationException`, never an `IllegalStateException` or a bare `RuntimeException`, because the same rule authored as a `checks:` gate already answers 400 and one rule must not change its status code because of where it is written. - `IntentCheckGateAcrossADelegateIT` gains the delegate's OWN refusal on the same synchronous stretch: as a `ValidationException` the completion answers 400 with the delegate's sentence, as an `IllegalStateException` the very same sentence is a 500 - both roll back whole (document DRAFT, task still the poster's), and the next attempt with nothing to refuse posts. Verified: `IntentCheckGateAcrossADelegateIT` 2/2 green (the new method fails on the assertion that names the type, not on the boundary), `engine-intent` unit suite 1330 green. Fixes #7450 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…7483) Bumps [org.apache.groovy:groovy-bom](https://github.com/apache/groovy) from 5.1.2 to 6.0.0. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy-bom dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.microsoft.graph:microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 6.69.0 to 6.70.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/main/CHANGELOG.md) - [Commits](microsoftgraph/msgraph-sdk-java@v6.69.0...v6.70.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-version: 6.70.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… (#7497) * ui: collapsible Projects/Assistant side panels in the Workbench (#7492) The Workbench's left Projects pane and right Assistant pane took a large fixed slice of horizontal width and could not be reclaimed for the editor: the perspective overrode the shell defaults with leftPaneMinSize 355 / rightPaneMinSize 340, and the panel chevrons only collapse the accordion contents, not the pane's width. Change: - perspective-workbench/js/workbench.js: drop the 355/340 minimum-width floors (to the platform default 0). The split library collapses a pane only down to its minSize, so a non-zero floor would keep a "collapsed" panel that wide and reclaim nothing; with no floor the panes can be dragged narrow and collapsed fully. - platform-core layout.js: toggleLeftPane()/toggleRightPane() + isLeftPaneCollapsed()/isRightPaneCollapsed() driving the existing splitPanesState.side COLLAPSED mechanism (collapse to 0 + restore last size, iframes preserved); the collapsed state is persisted in the layout's localStorage key and restored on load. - platform-core layout-hub.js: toggleLeftPane/onToggleLeftPane (+ right) so the shell header (parent frame) can drive the layout in the perspective iframe over the message hub. - platform-core shell.js + header.html: two always-visible header toggle buttons (a collapsed pane has no width to host its own restore control). Verified: full quick-build reactor install; the app boots clean and serves the updated resources; formatter:validate is BUILD SUCCESS (cache wiped); new WorkbenchSidePaneToggleIT (2 methods) is green headless - both panes collapse to ~0 and restore via the header toggles, and a collapsed pane stays collapsed across a reload. Fixes #7492 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ui: collapse the side panels from their header chevron, not header buttons (#7492) Reworks the side-panel collapse UX per review feedback: drop the two shell-header toggle buttons and drive the collapse from the existing chevron on the first panel of each side pane (Projects / Assistant). - The first panel's chevron collapses the whole side pane to a slim rail (min-size 41px) that reclaims the editor width and keeps the chevron visible to expand it again; the sub-section chevrons (Import/Search/ Debugger) keep collapsing their own sections. The chevron points the way it acts and mirrors per side. - split.js: a collapsed pane restores by its stored lastSize (works for a 0 or a rail collapse), an optional expand-size (px) reopens it at a fixed width, and the reopen takes space only from the adjacent center pane so the opposite side pane does not move. - layout: side panes reopen at a fixed 350px (sidePaneExpandSize); the collapsed state still persists in the layout localStorage key. - Removed the header buttons, their shell.js handlers and the LayoutHub toggle methods/listeners (collapse is now driven in-frame). Verified: formatter:validate BUILD SUCCESS; WorkbenchSidePaneToggleIT (2 methods) green headless - each pane collapses to the rail via its chevron and reopens at 350px, the opposite pane's width is unchanged across both toggles, and a collapsed pane survives a reload. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ped values, the Calc guards, the print SDK calls and the ternaries (#7425) After the literal and builder-chain tiers of #7406 moved to JavaLiterals, the .glue still carried Java SOURCE in every expression key: a mapped value's `expr` (a create-from's fieldAssignments / itemFieldAssignments / itemLines, a schedule's genFieldAssignments / genChildren / genUnique, a posting's headerAssignments / itemRows, a posts: rule's assigns, a prompt: field's conversion), every guard (a row's `guard`, a transition's `guardExpr`, the event axis's `guardExpression`), the print SDK calls (`attachLanguageExpression` / `attachFileNameExpression`, a snapshot's `languageExpression` / `fileNameExpression`), a timer's `dueExpression` and the `conditionalRuleGuards` ternaries - ternaries, Calc.eval invocations, boxed equalities and string concatenations over SDK calls in the process description every template reads. Each is now a reading: a `kind`-tagged map of the authored facts, built through the package-private `Readings` factory and carried under `reading`, `guardReading`, `guardTerms` (the typed terms CheckSupport already produces, or the untyped spelling-inferred ones for a trigger / wait / register lookup), `due`, `attachLanguage` / `attachFileName`, `language` / `fileName`. The Java appears one layer out, in ide-template's new `JavaExpressions` - a closed vocabulary (read, hop, local, string, number, boolean, null, now, calc, text, concat, negate, convert, calcCompare, ruleCase, defaultLanguage, languageFrom, part, first, numberOrId, due) rendering exactly what the generator used to write, so the generated handlers are byte-identical. GlueGenerator renders at bind time and derives `conditionalRuleGuards` from the cells carrying a ruleCase; every binder falls back to the rendered key an older .glue carries, so an unregenerated project renders byte-identically. The now-unused Java renderers (NotificationSupport.guard, CheckSupport.condition/javaCondition, PostSetSupport.expression, FileNameSupport's helper calls) are gone. Verified: engine-intent unit suite (1334) and ide-template (192) green; IntentEngineIT (its glue assertion now pins that none of the rendered keys and no Calc.eval appear), IntentEmissionCoverageIT (compiles and runs the generated handlers) and ModelGenerationIT (regenerates from a pre-split orders.glue, the fallback path) green; formatter:validate clean with the cache wiped; the release-profile javadoc build of both modules clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… into issue-7425-glue-expression-keys
This branch has not been deployed
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.
Continues #7406, whose literal and builder-chain tiers shipped in #7426. What was left was the tier that issue named last: the expressions. Across the BusinessIntents fleet the
.gluestill carried Java source in every expression key:The change
The glue now carries each of those as a reading - a
kind-tagged map of the authored facts - and the Java appears one layer out:Readings(engine-intent, package-private) is the one factory every emitting site spells a reading through;JavaExpressions(ide-template, besideJavaLiterals) is the one renderer - a closed vocabulary of 21 kinds, each rendering exactly what the generator used to write, so the generated handlers are byte-identical (qualifiedExpressionspellsCalcfully qualified for the transition controller, which imports none).readingon every assignment (create-from fields / items / computed lines, schedule generate fields / children / natural-key property terms, posting header and item cells,posts:cells,prompt:conversions),guardReadingon a derived row and a transition,guardTermson every event binding (triggers, notifications, integrations, outbound, resolves, waits - the very typed termsCheckSupport.conditionTermsproduces for the model'schecks, or the untyped spelling-inferred terms for the three sites that never had an entity to type against),dueon a timer loader,attachLanguage/attachFileNameon every notify site,language/fileNameon a snapshot.conditionalRuleGuardsis no longer carried at all: the binder derives it from the cells whose reading is aruleCase..gluecarries (expr,guard,guardExpr,guardExpression,dueExpression, the attach / language / file-name expressions), so an unregenerated project renders byte-identically -ModelGenerationIT's pre-splitorders.gluestill exercises that path."scale": "2"- the glue is read back through a parser that types every number as aDouble), and an optional key omitted rather than written asnull(Gson drops a null map entry).NotificationSupport.guard(...)/literalToJava,CheckSupport.condition/javaCondition/comparison/numericComparison/access,PostSetSupport.expression,GlueIntentGenerator'spromptConversion/postSetExpr/conditionalRuleExpression/literalExpression/calcExpression/stringCellExpression/computedCellExpression. The templates are unchanged - they read the rendered keys the binder now writes.Deliberately not changed
The untyped guards of a trigger, a wait and a register lookup stay untyped (a
numberterm type renders the bare spelling), soObjects.equals(entity.Status, 3)is unchanged; typing them against the entity would change a to-one guard's comparison and is a separate decision. Keys outside the issue's inventory that carry no Java package (toExpression/subjectExpression/bodyExpression,urlExpression,matchSourceExpression,statusMatchExpression, an arrival'smapFields) are untouched.Verified
engine-intentunit suite green (1334 tests, of which the ~100 glue assertions that used to readexpr/guard/guardExpressionnow render the reading through the test helperGlueRenderingand still assert the same Java);ide-templategreen (192, incl. the newJavaExpressionsTestover every kind and theGlueGeneratorTestfallbacks).IntentEngineITgreen (81) - its glue assertion now pins that none of the ten rendered keys and noCalc.evalappear anywhere in a generated glue, and that the guards and the snapshot language travel as readings.IntentEmissionCoverageITgreen - it compiles and runs the generated handlers.ModelGenerationITgreen - the backward-compatible path, run rather than only unit-tested.mvn -T 1C formatter:validateclean with the formatter cache wiped; the release-profile javadoc build of both modules clean.Not verified: no run against a deployed instance, and no fleet regen - the fleet's
.gluefiles change shape on their next regen (the keys above), which is the intent.Fixes #7425
🤖 Generated with Claude Code