This repository was archived by the owner on Oct 7, 2026. It is now read-only.
Repository navigation
docs: model invoice commands that refuse transitions and return events - #155
Merged
Merged
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 17 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (11)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Split the example's invoice into DraftInvoice and Invoice variants of the billing root, moved by named commands (addLine, issue, void) that return typed TaggedError refusals and, where something is announced, explicit domain events beside the new entity. update() is unchanged; the spec pins the bypass it leaves open. Add a how-to (Write commands and events) and an explanation (Invariants and transitions) separating state invariants, transition rules and external preconditions, and covering the outbox seam and integration contracts. Closes #136 Closes #40 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
btravers
force-pushed
the
docs/136-40-commands-and-events
branch
from
October 6, 2026 08:37
ac9dc82 to
50fabe8
Compare
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Closes #136
Closes #40
Summary
Docs and example only.
packages/entityis untouched: no newEntity.*member, andupdate()keeps its return type. No changeset, because the example packages areprivate.Example (
examples/billing-domain)BillingDocumentBase.DraftInvoicehas editable lines and no number.Invoicehas anumber,linesmarkedimmutable, and a status of ISSUED, PAID, VOID or UNCOLLECTIBLE.BillingDocumentdispatches over draft, invoice and credit note.addLinereturnsResult<DraftInvoice, CurrencyMismatch | InvalidEntity>and announces nothing.issue({ number, at })returnsResult<{ entity: Invoice; events: [InvoiceIssued] }, InvalidEntity>. The number and the instant are external preconditions the caller passes in.void()returnsResult<{ entity; events: [InvoiceVoided] }, InvoiceNotVoidable | InvalidEntity>and refuses PAID → VOID, though both states are valid.events.tsholds the internal domain events and a separate, strict, versioned integration contract (InvoiceIssuedV1) that is mapped by hand and leaves out the lines.Docs
make/update, the outbox transaction seam, integration contracts, and the module boundary.update()permits, why lifecycles become variants, and why events come from commands rather than diffs.Test plan
pnpm format --check && pnpm lint && pnpm typecheck && pnpm test && pnpm knip && pnpm buildpasses.typecheckincludes the two-compiler declaration emit (7.0.2 and 5.9.3) and the emitted-.d.tscheck.examples/billing-domain/src/index.spec.tscover:InvoiceNotVoidable, with the source unchangedupdate()bypass of that same transition succeedingimmutablelines on the issued variant@ts-expect-error)vitepress buildwith--force: no dead links, and the cross-page anchor resolves.Not covered here: a runnable outbox transaction. That belongs to the persistence work in #37, and the how-to only shows the seam.
🤖 Generated with Claude Code