fix(templates): the rekey pair and the transition announce commit with their writes - #6869
Merged
Conversation
…h their writes (#6867) #6854 established the contract - announce an entity change by handing the topic to the WRITE, never by publishing beside it - and converted the generated repository's main paths. Two write+publish pairs survived it, each a live instance of #6816's failure class (row committed, event lost for good when the broker is briefly down, downstream reactions silently never run): - The DAO's targeted "-rekeyed" pair (#6845): one mutation had to record TWO bodies - the row as it stood, naming the group it left, and the row as written, naming the one it joined - and the targeted write could carry only one topic. The store and JavaRepository gain the event-carrying overloads (save and updateProperties with additionalEvents, mirroring update's trio), recorded only when the row actually existed to be written; the template hands both notices to the base write. A model without grouping keys regenerates byte-identically. - The transition controller (Transition.java.template): updateProperty + post-commit re-read + bare publish becomes one targeted write carrying the "-transitioned" topic, so the flip and its announcement commit together and the event payload is the row exactly as the statement left it - never a re-read a concurrent write could have moved on. The reload stays only for the HTTP response and the notify block. Deliberately NOT converted here, with the reasoning on #6867: the five deferred/ordered announces (SetField, Writer, Numbering, StepEvent via Process.executeAfterCommit - deferred so consumers observe the whole synchronous Flowable chain's writes, which write-attachment would regress - and Generate's completion announce, ordered after the target and its items across several transactions). Those need a durable-enqueue primitive, a follow-up of its own. Resolve.java.template follows once #6841, which rewrites that exact region, lands. JavaEventOutboxIT gains the retarget phase - one targeted mutation, two notices, both delivered and both cleared - and IntentEmissionCoverageIT pins the new contract, including that no bare Producer.sendToTopic remains in a generated repository or transition. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…6867) With #6841 merged, the lookup's routing status was a targeted updateProperty followed by a post-commit re-read and a bare publish of "-transitioned" - the same write-beside-publish pair the rest of this branch removes. The topic now rides the routing write into the outbox: the flip and its announcement commit together, the payload is the row exactly as the statement left it, and a rejected move (the ValidationException the routing write catches) records no event at all - a status the record could not take is not a transition. The emission oracles pin the new contract: IntentEngineIT's two-writes ordering assertion anchors on the topic-carrying updateProperties, and IntentEmissionCoverageIT's resolve block asserts the topic on the write and refuses any bare Producer.sendToTopic in the generated lookup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Part one of #6867 — the single-transaction write+publish pairs that contradicted #6854's contract ("announce an entity change through its repository, not by publishing next to it") and remained live instances of #6816's failure class: row committed, event lost for good when the broker is briefly down, downstream reactions silently never run.
What changes
data-store-java):JavaEntityStore/JavaRepositorygain the event-carrying overloadssave(entity, topic, additionalEvents)andupdateProperties(id, values, topic, additionalEvents)— mirroring the trioupdatealready has. Additional events are recorded in the outbox inside the write's own transaction, and only when the row actually existed to be written.-rekeyedpair (fix(intent): re-parenting repairs both sides, from every write path #6845) no longer publishes beside the write. One mutation records two bodies — the row as it stood (naming the group it left) and the row as written (naming the one it joined) — through the base write. The only reason it was a bare publish was the single-topic limitation the overload removes; the template's own comment said so. A model without grouping keys regenerates byte-identically.updateProperty+ post-commit re-read + bare publish becomes one targeted write carrying the-transitionedtopic — flip and announcement commit together, and the payload is the row exactly as the statement left it. The reload stays only for the HTTP response and the notify block.Deliberately not here (reasoning on #6867)
Resolve.java.template— Fix discarding identification and audit #6841 rewrites that exact region; it converts in a follow-up the moment Fix discarding identification and audit #6841 lands, to avoid crossing an open PR.SetField,Writer,Numbering,StepEventviaProcess.executeAfterCommit, andGenerate's after-items completion announce) — write-attachment would regress the Flowable chain-visibility ordering fixes; they need a durable-enqueue primitive, designed as its own PR.Verification
JavaEventOutboxITgains a retarget phase: one targeted mutation, two notices, both delivered and both cleared from the outbox.IntentEmissionCoverageITpins the new contract, includingassertFalseon any bareProducer.sendToTopicin a generated repository or transition controller.ModelGenerationITgreen (Velocity renders, the fix(templates): EntityController.java no longer gains a stray blank line without unique constraints (#6823) #6835 consecutive-blank-lines guard holds).data-store-javaunit tests and the release-profile javadoc gate green; formatter validated.Refs #6867, follows #6854/#6816, touches the outputs of #6845.
🤖 Generated with Claude Code