feat: deferred end-of-mutation calculation hook#500
Open
smartive-nicolai[bot] wants to merge 1 commit into
Open
feat: deferred end-of-mutation calculation hook#500smartive-nicolai[bot] wants to merge 1 commit into
smartive-nicolai[bot] wants to merge 1 commit into
Conversation
Add a request-scoped mutation scratch bag (`mutationState`) and an
`afterMutations(ctx)` lifecycle callback so consumers can defer work to a
single pass at the end of each top-level mutation instead of running it
eagerly inside individual mutation hooks.
- `Context`/`MutationContext` gain `mutationState?` (shared by reference
across all nested `withTransaction` levels) and `afterMutations?`.
- `mutationResolver` initializes `mutationState` to `{}` per top-level
mutation field and invokes `afterMutations` after the write (including all
cascade/reentrant writes) but before the result is read back, still inside
the mutation transaction. Skipped for dry-run deletes.
This lets a consumer accumulate dirty entity ids across cascades/reentrancy
and run each derived calculation exactly once, in dependency order, on a
consistent post-mutation state.
Co-Authored-By: Claude Opus 4.8 <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.
What
Adds a request-scoped mutation scratch bag (
mutationState) and anafterMutations(ctx)lifecycle callback, so consumers can defer work to a single pass at the end of each top-level mutation instead of running it eagerly inside individual mutation hooks.Why
In zwei-wealth-platform, entity calculations (Portfolio → Goal → Relation, etc.) currently run eagerly inside each
afterMutate*hook. When one request mutates several related entities — via mutation reentrancy, delete-cascade or restore-cascade — the same entity is recalculated many times, in the wrong order, and on inconsistent mid-mutation state. This hook lets the consumer accumulate dirty entity ids across the whole mutation and run each calculation exactly once, in dependency order, on a consistent post-write state.Changes
Context/MutationContextgain two optional fields:mutationState?: Record<string, unknown>— a scratch bag, initialized to{}bymutationResolverat the start of every top-level mutation and shared by reference across all nestedwithTransactionlevels (so a mark made deep inside a cascade is visible at the top).afterMutations?: (ctx) => Promise<void> | void— run once at the end of the mutation.mutationResolversetsmutationState = {}per top-level field and callsafterMutationsafter the write (including all cascade/reentrant writes) but before the result is read back, still inside the mutation transaction. Skipped for dry-run deletes.Fully backwards compatible: both fields are optional; when
afterMutationsis unset the behaviour is unchanged.Consumer
Pairs with the zwei-wealth-platform MR that moves Portfolio/Goal/Relation/PAR/RelationCost calculations to a single deferred flush (link to follow).
🤖 Generated with Claude Code