Intent declarative glue: notifications (event → email @Listener) - #6052
Merged
Conversation
…lue) First increment of the declarative-glue catalog (see engine-intent CLAUDE.md "Planned: declarative glue"). Adds the NotificationIntent model and parses a top-level `notifications:` block; validates, in one pass with the other blocks: unique name, exactly one entity lifecycle event (onCreate/onUpdate/onDelete) referencing a declared entity, a supported channel (email), and a recipient. Parse-only for now (mirrors how triggers/resolvers landed validation-first); the generator that emits the annotated client-Java @Listener + Mail glue is the next increment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lue) Second increment of the notifications pattern: turn a parsed `notifications:` block into an annotated client-Java @Listener that sends mail on an entity event - no hand-written code. - NotificationSupport (pure, unit-tested) translates the author-facing fields into the Java expressions the listener pastes in: recipient (literal address or direct field), {field} subject/body interpolation, and a single-comparison `when` guard. v1 supports direct fields + literals; relation-path recipients are rejected by the parser with a clear message (next increment). - GlueIntentGenerator emits a `notifications` collection into <intent>.glue; Notification.java.template renders gen/events/<Name>Notification.java (@Listener bound to the entity's create / -updated / -deleted topic, sending via sdk.mail.Mail, sender from DIRIGIBLE_MAIL_SENDER); generateUtils.js gets the `notifications` collection case. Honors the .settings override switch. - The event-binding key is `event:`, not `on:` - YAML 1.1 resolves a bare `on` to boolean true, which silently emptied the binding (caught by IntentEngineIT). Restores the "Planned: declarative glue" section to engine-intent/CLAUDE.md (lost in the #6040 squash merge) and marks notifications v1 done. Covered by NotificationSupportTest (expression logic) and IntentEngineIT (the notification renders to @Listener Java end to end). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Completes the notifications recipient/interpolation support: `to`, `subject`
and `body` can now reference a one-hop `relation.field` of a to-one relation of
the event entity (e.g. on an Order event, `{customer.name}` or
`to: customer.email`), not just direct fields and literals.
NotificationSupport.plan() resolves each referenced relation to a RelationLoad
(reusing the decision-resolver one-hop convention: FK property = PascalCase
relation, target entity/perspective); the listener loads the related entity
once by FK id (`new <Target>Repository().findById(entity.<Fk>)`) and the
expressions read its field. An unresolvable recipient relation skips the
notification (logged); the parser now only rejects multi-hop `to`.
Covered by NotificationSupportTest (direct/literal, one-hop relation, and the
unresolvable-recipient cases) and IntentEngineIT (the generated listener loads
the related Customer and the subject reads customer.Name) - green locally.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
Update: added one-hop Remaining gap: multi-hop paths ( |
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.
What
First item of the declarative-glue catalog (see
engine-intent/CLAUDE.md→ "Planned: declarative glue"): anotifications:block in the intent that sends mail on an entity lifecycle event — generated as an annotated client-Java@Listener, no hand-written code.→ generates
gen/events/OrderUpdatedNotification.java: an@Listenerbound to the entity's…-updatedtopic that sends viasdk.mail.Mail(sender fromDIRIGIBLE_MAIL_SENDER).How
NotificationIntent+IntentParser): unique name; exactly one ofonCreate/onUpdate/onDeleteon a declared entity; supported channel; recipient present.NotificationSupport(pure, unit-tested) translates the author fields into the Java the listener pastes in — recipient (literal orentity.<Field>),{field}interpolation, and a single-comparisonwhenguard.GlueIntentGeneratoremits anotificationscollection into<intent>.glue;Notification.java.templaterenders the listener;generateUtils.jsgets thenotificationscollection case. Honors the.settingsoverrides.notifications.<name>.generate=falseswitch.Notes / decisions
event:, noton:— YAML 1.1 resolves a bareon(alsooff/yes/no) to booleantrue, which silently emptied the binding.IntentEngineITcaught it.to/placeholders resolve direct fields or literals;whenis a singlefield ==|!= literal. Relation-path recipients (member.email) are rejected by the parser with a clear message and are the next increment (they reuse the decision-resolver machinery).CLAUDE.md(it was lost in the Intent Editor: AI assistant (Claude chat + patch preview) #6040 squash merge).Testing
NotificationSupportTest— 4 unit tests for the expression translation (green locally).IntentEngineIT.glue_template_generates_…extended to assert the generatedOrderUpdatedNotification.java(topic,Mail.send, recipient, subject interpolation, lowercased-package import) — green locally (Tests run: 1, Failures: 0). CI runs the full suite on H2/PostgreSQL/MSSQL.Depends on / relates to
-updated/-deletedtopics.🤖 Generated with Claude Code