[{"data":1,"prerenderedAt":932},["ShallowReactive",2],{"navigation_docs":3,"-docs-architecture-overview":493,"-docs-architecture-overview-surround":927},[4,46,135,218,257,292,355,377,420],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":45},"Getting Started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"What is Heximon?","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F01.getting-started\u002F02.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F01.getting-started\u002F03.quick-start","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Core Concepts","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","docs\u002F01.getting-started\u002F04.core-concepts","i-lucide-shapes",{"title":31,"path":32,"stem":33,"icon":34},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F01.getting-started\u002F05.examples","i-lucide-library",{"title":36,"path":37,"stem":38,"icon":39},"Where Next?","\u002Fdocs\u002Fgetting-started\u002Fwhere-next","docs\u002F01.getting-started\u002F06.where-next","i-lucide-signpost",{"title":41,"path":42,"stem":43,"icon":44},"Troubleshooting","\u002Fdocs\u002Fgetting-started\u002Ftroubleshooting","docs\u002F01.getting-started\u002F07.troubleshooting","i-lucide-life-buoy",false,{"title":47,"icon":48,"path":49,"stem":50,"children":51,"page":45},"Essentials","i-lucide-boxes","\u002Fdocs\u002Fessentials","docs\u002F02.essentials",[52,56,61,66,71,76,81,86,91,96,101,105,110,115,120,125,130],{"title":53,"path":54,"stem":55,"icon":48},"Modules & DI","\u002Fdocs\u002Fessentials\u002Fmodules-and-di","docs\u002F02.essentials\u002F01.modules-and-di",{"title":57,"path":58,"stem":59,"icon":60},"Controllers","\u002Fdocs\u002Fessentials\u002Fcontrollers","docs\u002F02.essentials\u002F02.controllers","i-lucide-route",{"title":62,"path":63,"stem":64,"icon":65},"Validation & DTOs","\u002Fdocs\u002Fessentials\u002Fvalidation","docs\u002F02.essentials\u002F03.validation","i-lucide-shield-check",{"title":67,"path":68,"stem":69,"icon":70},"Contracts","\u002Fdocs\u002Fessentials\u002Fcontracts","docs\u002F02.essentials\u002F04.contracts","i-lucide-file-signature",{"title":72,"path":73,"stem":74,"icon":75},"REST Client","\u002Fdocs\u002Fessentials\u002Fclient","docs\u002F02.essentials\u002F05.client","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":80},"Database","\u002Fdocs\u002Fessentials\u002Fdatabase","docs\u002F02.essentials\u002F06.database","i-lucide-database",{"title":82,"path":83,"stem":84,"icon":85},"Drizzle ORM","\u002Fdocs\u002Fessentials\u002Fdrizzle","docs\u002F02.essentials\u002F07.drizzle","i-lucide-database-zap",{"title":87,"path":88,"stem":89,"icon":90},"Persistence & Transactions","\u002Fdocs\u002Fessentials\u002Fpersistence","docs\u002F02.essentials\u002F08.persistence","i-lucide-database-backup",{"title":92,"path":93,"stem":94,"icon":95},"Migrations","\u002Fdocs\u002Fessentials\u002Fmigrations","docs\u002F02.essentials\u002F09.migrations","i-lucide-git-branch",{"title":97,"path":98,"stem":99,"icon":100},"Authentication","\u002Fdocs\u002Fessentials\u002Fauthentication","docs\u002F02.essentials\u002F10.authentication","i-lucide-key-round",{"title":102,"path":103,"stem":104,"icon":65},"Permissions & scopes","\u002Fdocs\u002Fessentials\u002Fpermissions","docs\u002F02.essentials\u002F11.permissions",{"title":106,"path":107,"stem":108,"icon":109},"Error Handling","\u002Fdocs\u002Fessentials\u002Ferrors","docs\u002F02.essentials\u002F12.errors","i-lucide-triangle-alert",{"title":111,"path":112,"stem":113,"icon":114},"Testing a Heximon App","\u002Fdocs\u002Fessentials\u002Ftesting","docs\u002F02.essentials\u002F13.testing","i-lucide-flask-conical",{"title":116,"path":117,"stem":118,"icon":119},"Test app harness","\u002Fdocs\u002Fessentials\u002Fcreatetestapp","docs\u002F02.essentials\u002F14.createtestapp","i-lucide-test-tube",{"title":121,"path":122,"stem":123,"icon":124},"Logging & Observability","\u002Fdocs\u002Fessentials\u002Flogging","docs\u002F02.essentials\u002F17.logging","i-lucide-scroll-text",{"title":126,"path":127,"stem":128,"icon":129},"Context & Lifecycle","\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle","docs\u002F02.essentials\u002F18.context-and-lifecycle","i-lucide-radio",{"title":131,"path":132,"stem":133,"icon":134},"Project Structure","\u002Fdocs\u002Fessentials\u002Fproject-structure","docs\u002F02.essentials\u002F19.project-structure","i-lucide-folder-tree",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":45},"Capabilities","i-lucide-sparkles","\u002Fdocs\u002Fcapabilities","docs\u002F03.capabilities",[141,145,150,155,160,164,169,174,179,184,188,193,198,203,208,213],{"title":142,"path":143,"stem":144,"icon":137},"Overview","\u002Fdocs\u002Fcapabilities\u002Foverview","docs\u002F03.capabilities\u002F01.overview",{"title":146,"path":147,"stem":148,"icon":149},"Events","\u002Fdocs\u002Fcapabilities\u002Fevents","docs\u002F03.capabilities\u002F02.events","i-lucide-radio-tower",{"title":151,"path":152,"stem":153,"icon":154},"Queue","\u002Fdocs\u002Fcapabilities\u002Fbackground-jobs","docs\u002F03.capabilities\u002F03.background-jobs","i-lucide-list-ordered",{"title":156,"path":157,"stem":158,"icon":159},"Scheduled Work","\u002Fdocs\u002Fcapabilities\u002Fscheduled-jobs","docs\u002F03.capabilities\u002F04.scheduled-jobs","i-lucide-clock",{"title":161,"path":162,"stem":163,"icon":85},"Caching","\u002Fdocs\u002Fcapabilities\u002Fcaching","docs\u002F03.capabilities\u002F05.caching",{"title":165,"path":166,"stem":167,"icon":168},"Key\u002FValue Storage","\u002Fdocs\u002Fcapabilities\u002Fkey-value","docs\u002F03.capabilities\u002F06.key-value","i-lucide-hard-drive",{"title":170,"path":171,"stem":172,"icon":173},"Blob Storage","\u002Fdocs\u002Fcapabilities\u002Fblob","docs\u002F03.capabilities\u002F07.blob","i-lucide-folder-open",{"title":175,"path":176,"stem":177,"icon":178},"Health & Readiness","\u002Fdocs\u002Fcapabilities\u002Fhealth","docs\u002F03.capabilities\u002F08.health","i-lucide-heart-pulse",{"title":180,"path":181,"stem":182,"icon":183},"Notifications","\u002Fdocs\u002Fcapabilities\u002Fnotifications","docs\u002F03.capabilities\u002F09.notifications","i-lucide-mail",{"title":185,"path":186,"stem":187,"icon":65},"Idempotency","\u002Fdocs\u002Fcapabilities\u002Fidempotency","docs\u002F03.capabilities\u002F10.idempotency",{"title":189,"path":190,"stem":191,"icon":192},"Security Hardening","\u002Fdocs\u002Fcapabilities\u002Fsecurity","docs\u002F03.capabilities\u002F11.security","i-lucide-shield",{"title":194,"path":195,"stem":196,"icon":197},"Observability & Tracing","\u002Fdocs\u002Fcapabilities\u002Fobservability","docs\u002F03.capabilities\u002F12.observability","i-lucide-activity",{"title":199,"path":200,"stem":201,"icon":202},"OpenAPI","\u002Fdocs\u002Fcapabilities\u002Fopenapi","docs\u002F03.capabilities\u002F13.openapi","i-lucide-book-marked",{"title":204,"path":205,"stem":206,"icon":207},"MCP Server","\u002Fdocs\u002Fcapabilities\u002Fmcp","docs\u002F03.capabilities\u002F14.mcp","i-lucide-bot",{"title":209,"path":210,"stem":211,"icon":212},"Schema DTOs","\u002Fdocs\u002Fcapabilities\u002Fschema","docs\u002F03.capabilities\u002F15.schema","i-lucide-file-json",{"title":214,"path":215,"stem":216,"icon":217},"Branded IDs","\u002Fdocs\u002Fcapabilities\u002Fbranded-ids","docs\u002F03.capabilities\u002F16.branded-ids","i-lucide-tag",{"title":219,"icon":220,"path":221,"stem":222,"children":223,"page":45},"Architecture","i-lucide-building","\u002Fdocs\u002Farchitecture","docs\u002F04.architecture",[224,227,232,237,242,247,252],{"title":142,"path":225,"stem":226,"icon":220},"\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F04.architecture\u002F01.overview",{"title":228,"path":229,"stem":230,"icon":231},"Domain-Driven Design","\u002Fdocs\u002Farchitecture\u002Fddd","docs\u002F04.architecture\u002F02.ddd","i-lucide-hexagon",{"title":233,"path":234,"stem":235,"icon":236},"CQRS","\u002Fdocs\u002Farchitecture\u002Fcqrs","docs\u002F04.architecture\u002F03.cqrs","i-lucide-split",{"title":238,"path":239,"stem":240,"icon":241},"Repository Pattern","\u002Fdocs\u002Farchitecture\u002Frepository-pattern","docs\u002F04.architecture\u002F04.repository-pattern","i-lucide-archive",{"title":243,"path":244,"stem":245,"icon":246},"Integration Events","\u002Fdocs\u002Farchitecture\u002Fintegration-events","docs\u002F04.architecture\u002F05.integration-events","i-lucide-send-horizontal",{"title":248,"path":249,"stem":250,"icon":251},"Saga Orchestration","\u002Fdocs\u002Farchitecture\u002Fsagas","docs\u002F04.architecture\u002F06.sagas","i-lucide-hourglass",{"title":253,"path":254,"stem":255,"icon":256},"Durable Workflows","\u002Fdocs\u002Farchitecture\u002Fworkflows","docs\u002F04.architecture\u002F07.workflows","i-lucide-workflow",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":45},"Realtime","i-lucide-cable","\u002Fdocs\u002Frealtime","docs\u002F05.realtime",[263,266,270,274,279,284,288],{"title":142,"path":264,"stem":265,"icon":259},"\u002Fdocs\u002Frealtime\u002Foverview","docs\u002F05.realtime\u002F01.overview",{"title":267,"path":268,"stem":269,"icon":129},"WebSockets","\u002Fdocs\u002Frealtime\u002Fwebsockets","docs\u002F05.realtime\u002F02.websockets",{"title":271,"path":272,"stem":273,"icon":70},"WebSocket Contracts","\u002Fdocs\u002Frealtime\u002Fwebsocket-contracts","docs\u002F05.realtime\u002F03.websocket-contracts",{"title":275,"path":276,"stem":277,"icon":278},"Server-Sent Events","\u002Fdocs\u002Frealtime\u002Fserver-sent-events","docs\u002F05.realtime\u002F04.server-sent-events","i-lucide-rss",{"title":280,"path":281,"stem":282,"icon":283},"Typed Clients","\u002Fdocs\u002Frealtime\u002Ftyped-clients","docs\u002F05.realtime\u002F05.typed-clients","i-lucide-plug-zap",{"title":285,"path":286,"stem":287,"icon":259},"AsyncAPI","\u002Fdocs\u002Frealtime\u002Fasyncapi","docs\u002F05.realtime\u002F06.asyncapi",{"title":289,"path":290,"stem":291,"icon":80},"Durable Objects","\u002Fdocs\u002Frealtime\u002Fdurable-objects","docs\u002F05.realtime\u002F07.durable-objects",{"title":293,"icon":294,"path":295,"stem":296,"children":297,"page":45},"Deploy","i-lucide-cloud-upload","\u002Fdocs\u002Fdeploy","docs\u002F06.deploy",[298,301,306,311,316,321,326,331,336,341,345,350],{"title":142,"path":299,"stem":300,"icon":6},"\u002Fdocs\u002Fdeploy\u002Foverview","docs\u002F06.deploy\u002F01.overview",{"title":302,"path":303,"stem":304,"icon":305},"Node","\u002Fdocs\u002Fdeploy\u002Fnode","docs\u002F06.deploy\u002F02.node","la:node-js",{"title":307,"path":308,"stem":309,"icon":310},"Cloudflare","\u002Fdocs\u002Fdeploy\u002Fcloudflare","docs\u002F06.deploy\u002F03.cloudflare","simple-icons:cloudflare",{"title":312,"path":313,"stem":314,"icon":315},"Vercel","\u002Fdocs\u002Fdeploy\u002Fvercel","docs\u002F06.deploy\u002F04.vercel","ri:vercel-fill",{"title":317,"path":318,"stem":319,"icon":320},"Netlify","\u002Fdocs\u002Fdeploy\u002Fnetlify","docs\u002F06.deploy\u002F05.netlify","i-simple-icons-netlify",{"title":322,"path":323,"stem":324,"icon":325},"AWS Lambda","\u002Fdocs\u002Fdeploy\u002Faws-lambda","docs\u002F06.deploy\u002F06.aws-lambda","hugeicons:aws-lambda",{"title":327,"path":328,"stem":329,"icon":330},"Deno Deploy","\u002Fdocs\u002Fdeploy\u002Fdeno-deploy","docs\u002F06.deploy\u002F07.deno-deploy","simple-icons:denodeploy",{"title":332,"path":333,"stem":334,"icon":335},"Nitro","\u002Fdocs\u002Fdeploy\u002Fnitro","docs\u002F06.deploy\u002F08.nitro","i-unjs-nitro",{"title":337,"path":338,"stem":339,"icon":340},"Nuxt","\u002Fdocs\u002Fdeploy\u002Fnuxt","docs\u002F06.deploy\u002F09.nuxt","i-devicon-nuxt",{"title":342,"path":343,"stem":344,"icon":236},"Mixed-runtime split","\u002Fdocs\u002Fdeploy\u002Fmixed-runtime-split","docs\u002F06.deploy\u002F10.mixed-runtime-split",{"title":346,"path":347,"stem":348,"icon":349},"Hosts","\u002Fdocs\u002Fdeploy\u002Fhosts","docs\u002F06.deploy\u002F11.hosts","i-lucide-map",{"title":351,"path":352,"stem":353,"icon":354},"Cross-service events","\u002Fdocs\u002Fdeploy\u002Fcross-service-events","docs\u002F06.deploy\u002F12.cross-service-events","i-lucide-network",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":45},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F07.cli",[361,365,369,373],{"title":362,"path":363,"stem":364,"icon":357},"The heximon CLI","\u002Fdocs\u002Fcli\u002Foverview","docs\u002F07.cli\u002F01.overview",{"title":366,"path":367,"stem":368,"icon":137},"Create a New App","\u002Fdocs\u002Fcli\u002Fcreate","docs\u002F07.cli\u002F02.create",{"title":370,"path":371,"stem":372,"icon":95},"Migrations from the CLI","\u002Fdocs\u002Fcli\u002Fmigrations","docs\u002F07.cli\u002F03.migrations",{"title":374,"path":375,"stem":376,"icon":6},"Deploying a Heximon app","\u002Fdocs\u002Fcli\u002Fdeploy","docs\u002F07.cli\u002F04.deploy",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":45},"Under the Hood","i-lucide-wrench","\u002Fdocs\u002Funder-the-hood","docs\u002F08.under-the-hood",[383,388,393,397,402,407,411,415],{"title":384,"path":385,"stem":386,"icon":387},"How the Compiler Works","\u002Fdocs\u002Funder-the-hood\u002Fhow-the-compiler-works","docs\u002F08.under-the-hood\u002F01.how-the-compiler-works","i-lucide-cog",{"title":389,"path":390,"stem":391,"icon":392},"Compiler","\u002Fdocs\u002Funder-the-hood\u002Fextending-the-compiler","docs\u002F08.under-the-hood\u002F02.extending-the-compiler","i-lucide-cpu",{"title":394,"path":395,"stem":396,"icon":357},"Compiler Diagnostics","\u002Fdocs\u002Funder-the-hood\u002Fcompiler-diagnostics","docs\u002F08.under-the-hood\u002F03.compiler-diagnostics",{"title":398,"path":399,"stem":400,"icon":401},"Library Mode","\u002Fdocs\u002Funder-the-hood\u002Flibrary-mode","docs\u002F08.under-the-hood\u002F04.library-mode","i-lucide-package",{"title":403,"path":404,"stem":405,"icon":406},"Other bundlers","\u002Fdocs\u002Funder-the-hood\u002Falternate-bundlers","docs\u002F08.under-the-hood\u002F05.alternate-bundlers","i-lucide-blocks",{"title":408,"path":409,"stem":410,"icon":401},"Packages","\u002Fdocs\u002Funder-the-hood\u002Fpackages","docs\u002F08.under-the-hood\u002F06.packages",{"title":412,"path":413,"stem":414,"icon":207},"AI Skills","\u002Fdocs\u002Funder-the-hood\u002Fai-and-agents","docs\u002F08.under-the-hood\u002F07.ai-and-agents",{"title":416,"path":417,"stem":418,"icon":419},"Advanced DI","\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di","docs\u002F08.under-the-hood\u002F08.advanced-di","i-lucide-git-fork",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":45},"Recipes","i-lucide-book-open-check","\u002Fdocs\u002Frecipes","docs\u002F09.recipes",[426,431,436,440,444,448,452,456,460,465,469,474,479,484,488],{"title":427,"path":428,"stem":429,"icon":430},"Send an Email","\u002Fdocs\u002Frecipes\u002Fsend-an-email","docs\u002F09.recipes\u002F01.send-an-email","i-lucide-send",{"title":432,"path":433,"stem":434,"icon":435},"Upload a File","\u002Fdocs\u002Frecipes\u002Fupload-a-file","docs\u002F09.recipes\u002F02.upload-a-file","i-lucide-upload",{"title":437,"path":438,"stem":439,"icon":24},"Cache an Expensive Call","\u002Fdocs\u002Frecipes\u002Fcache-an-expensive-call","docs\u002F09.recipes\u002F03.cache-an-expensive-call",{"title":441,"path":442,"stem":443,"icon":154},"Paginate a List","\u002Fdocs\u002Frecipes\u002Fpaginate-a-list","docs\u002F09.recipes\u002F04.paginate-a-list",{"title":445,"path":446,"stem":447,"icon":65},"Protect Admin Routes","\u002Fdocs\u002Frecipes\u002Fprotect-admin-routes","docs\u002F09.recipes\u002F05.protect-admin-routes",{"title":449,"path":450,"stem":451,"icon":178},"Health Probes and a Nightly Job","\u002Fdocs\u002Frecipes\u002Fhealth-probes-and-a-nightly-job","docs\u002F09.recipes\u002F06.health-probes-and-a-nightly-job",{"title":453,"path":454,"stem":455,"icon":80},"Build a CRUD API","\u002Fdocs\u002Frecipes\u002Fcrud-api","docs\u002F09.recipes\u002F07.crud-api",{"title":457,"path":458,"stem":459,"icon":100},"Add Authentication","\u002Fdocs\u002Frecipes\u002Fadd-authentication","docs\u002F09.recipes\u002F08.add-authentication",{"title":461,"path":462,"stem":463,"icon":464},"Background Jobs","\u002Fdocs\u002Frecipes\u002Fbackground-jobs","docs\u002F09.recipes\u002F09.background-jobs","i-lucide-timer",{"title":466,"path":467,"stem":468,"icon":149},"Decouple Features with Events","\u002Fdocs\u002Frecipes\u002Fevent-driven-module","docs\u002F09.recipes\u002F10.event-driven-module",{"title":470,"path":471,"stem":472,"icon":473},"Build a DDD Aggregate","\u002Fdocs\u002Frecipes\u002Fddd-aggregate","docs\u002F09.recipes\u002F11.ddd-aggregate","i-lucide-box",{"title":475,"path":476,"stem":477,"icon":478},"Publish a Feature Package","\u002Fdocs\u002Frecipes\u002Ffeature-package","docs\u002F09.recipes\u002F12.feature-package","i-lucide-package-open",{"title":480,"path":481,"stem":482,"icon":483},"Reliable Integration Events","\u002Fdocs\u002Frecipes\u002Freliable-integration-events","docs\u002F09.recipes\u002F13.reliable-integration-events","i-lucide-inbox",{"title":485,"path":486,"stem":487,"icon":95},"Reactive Choreography","\u002Fdocs\u002Frecipes\u002Freactive-choreography","docs\u002F09.recipes\u002F14.reactive-choreography",{"title":489,"path":490,"stem":491,"icon":492},"Build a Production CRUD API","\u002Fdocs\u002Frecipes\u002Fproduction-crud-api","docs\u002F09.recipes\u002F15.production-crud-api","i-lucide-layers",{"id":494,"title":219,"body":495,"description":920,"extension":921,"links":922,"meta":923,"navigation":924,"path":225,"seo":925,"stem":226,"__hash__":926},"docs\u002Fdocs\u002F04.architecture\u002F01.overview.md",{"type":496,"value":497,"toc":910},"minimark",[498,502,507,510,539,542,546,552,629,647,651,659,721,724,728,756,775,797,813,821,836,840,860,863,867],[499,500,501],"p",{},"Most apps never need this section, and that's not a gap in Heximon — it's the point. A controller with a\nprovider or two, a database table, a handful of events, is a complete, production-shipped app. Nothing here\nreplaces that shape; it extends it for the moment your domain actually pushes back.",[503,504,506],"h2",{"id":505},"the-signals-that-youve-earned-it","The signals that you've earned it",[499,508,509],{},"Reach for something in this section when you recognize one of these, not before:",[511,512,513,521,527,533],"ul",{},[514,515,516,520],"li",{},[517,518,519],"strong",{},"Multiple writers converge on one concept."," Two features both mutate \"an order\" and you keep\nre-deriving the same validity rules in each place — that logic wants one home.",[514,522,523,526],{},[517,524,525],{},"An invariant spans fields, not just one."," \"Can't ship before payment confirms\" isn't a column\nconstraint; it's a rule about the relationship between two pieces of state.",[514,528,529,532],{},[517,530,531],{},"Consistency has to cross a service boundary."," Two independently deployed services both need to\nreact to the same fact, and a direct call would couple their deploys together.",[514,534,535,538],{},[517,536,537],{},"A process outlives a request."," \"Wait 30 seconds for payment, then cancel\" or \"sleep two days,\nthen follow up\" can't hold a request thread open — it needs a durable clock.",[499,540,541],{},"None of these are architectural taste. Each maps to exactly one page below, and each is adoptable on its\nown — you don't buy the whole section to get one of them.",[503,543,545],{"id":544},"events-promoted","Events, promoted",[499,547,548,551],{},[549,550,146],"a",{"href":147}," already introduced three tiers for decoupling features. Restated here\nbecause the top two are where this section actually starts:",[553,554,555,575],"table",{},[556,557,558],"thead",{},[559,560,561,566,569,572],"tr",{},[562,563,565],"th",{"align":564},"left","Tier",[562,567,568],{"align":564},"Reach",[562,570,571],{"align":564},"Delivery",[562,573,574],{"align":564},"When to use",[576,577,578,596,613],"tbody",{},[559,579,580,587,590,593],{},[581,582,583],"td",{"align":564},[549,584,586],{"href":585},"\u002Fdocs\u002Fcapabilities\u002Fevents#in-process-events","In-process",[581,588,589],{"align":564},"Same app",[581,591,592],{"align":564},"Synchronous, awaited",[581,594,595],{"align":564},"Decouple features in one app — notifications, logging, side effects",[559,597,598,604,607,610],{},[581,599,600],{"align":564},[549,601,603],{"href":602},"\u002Fdocs\u002Fcapabilities\u002Fevents#domain-events","Domain",[581,605,606],{"align":564},"Same app, after a save",[581,608,609],{"align":564},"Synchronous, flushed on demand",[581,611,612],{"align":564},"React to state changes an aggregate recorded, within one bounded context",[559,614,615,620,623,626],{},[581,616,617],{"align":564},[549,618,619],{"href":244},"Integration",[581,621,622],{"align":564},"Across services",[581,624,625],{"align":564},"Async, queue-backed",[581,627,628],{"align":564},"Communicate between bounded contexts or separate services",[499,630,631,632,635,636,638,639,642,643,646],{},"Domain events are the reason ",[549,633,634],{"href":229},"DDD"," and ",[549,637,233],{"href":234}," show up\ntogether below — an aggregate records what happened, a command handler saves it and flushes the buffer.\nIntegration events are the reason ",[549,640,641],{"href":249},"sagas"," and\n",[549,644,645],{"href":254},"workflows"," can coordinate across a deploy boundary at all.",[503,648,650],{"id":649},"choreography-saga-or-workflow","Choreography, saga, or workflow",[499,652,653,654,658],{},"Once state changes are events, the next question is ",[655,656,657],"em",{},"how do several steps stay coordinated",". Three answers,\neach buying more machinery than the last:",[553,660,661,674],{},[556,662,663],{},[559,664,665,668,671],{},[562,666,667],{"align":564},"Pattern",[562,669,670],{"align":564},"When",[562,672,673],{"align":564},"Trade-offs",[576,675,676,691,706],{},[559,677,678,683,686],{},[581,679,680],{"align":564},[517,681,682],{},"Reactive choreography",[581,684,685],{"align":564},"Each context reacts to an event and emits the next; no central coordinator",[581,687,688,689],{"align":564},"Simple; hard to add deadlines or visibility — see ",[549,690,243],{"href":244},[559,692,693,700,703],{},[581,694,695],{"align":564},[517,696,697],{},[549,698,699],{"href":249},"Saga",[581,701,702],{"align":564},"You need a deadline (\"pay in 30 s or cancel\") and want a process-state aggregate",[581,704,705],{"align":564},"Adds a durable-timer table + poller; compensation driven by timeout handlers",[559,707,708,715,718],{},[581,709,710],{"align":564},[517,711,712],{},[549,713,714],{"href":254},"Workflow",[581,716,717],{"align":564},"The flow is a linear procedure with real sleeps (minutes, hours, days) or cross-cutting retry\u002Ftimeout policy per step",[581,719,720],{"align":564},"Adds step-memoization + instance tables; the run body reads like synchronous code",[499,722,723],{},"Start with plain integration events and choreography. Add a saga only when a deadline enters the picture.\nReach for a workflow only when the procedure itself is linear and needs to sleep past a request's lifetime.",[503,725,727],{"id":726},"what-each-page-solves","What each page solves",[499,729,730,734,735,739,740,743,744,747,748,751,752,755],{},[517,731,732],{},[549,733,228],{"href":229}," gives multi-field invariants and business rules a home\nthat isn't scattered across controllers — ",[736,737,738],"code",{},"ValueObject",", ",[736,741,742],{},"Entity",", and ",[736,745,746],{},"AggregateRoot"," are plain classes\nwith equality, dirty tracking, and recorded domain events built in. Prerequisite: ",[549,749,750],{"href":88},"persistence","\nand the ",[549,753,754],{"href":239},"repository pattern"," to persist what you model.",[499,757,758,762,763,766,767,770,771,774],{},[517,759,760],{},[549,761,233],{"href":234}," gives every write and every read an explicit, individually testable\nunit — a typed ",[736,764,765],{},"CommandBus","\u002F",[736,768,769],{},"QueryBus"," instead of controller methods that quietly do both. It's the layer\nthat saves an aggregate and flushes its domain events in one place. Prerequisite: ",[549,772,773],{"href":58},"controllers","\nand, once state gets real invariants, DDD.",[499,776,777,782,783,739,786,789,790,793,794,796],{},[517,778,779],{},[549,780,781],{"href":239},"Repository pattern"," gives your domain a collection-like\npersistence boundary — ",[736,784,785],{},"save",[736,787,788],{},"getById",", a zero-codegen query — so handlers never touch SQL and the\nstorage engine stays swappable behind one abstract token. Prerequisite: ",[549,791,792],{"href":83},"Drizzle","\nor another ",[549,795,750],{"href":88}," adapter.",[499,798,799,804,805,808,809,812],{},[517,800,801],{},[549,802,803],{"href":244},"Integration events"," carry a fact across a bounded context or a\ndeployed service without blocking the request that produced it — a typed producer, a typed consumer, and a\ntransactional outbox so the publish can't outrun the save. Prerequisite: ",[549,806,807],{"href":147},"events","\nand ",[549,810,811],{"href":152},"background jobs"," (the queue transport integration events ride).",[499,814,815,820],{},[517,816,817],{},[549,818,819],{"href":249},"Sagas"," give a multi-step process a deadline that survives a restart — a\ndurable timer commits atomically with the saga's state, and a timeout handler compensates if it fires.\nPrerequisite: DDD (the process-state aggregate) and integration events (the channel a timeout is delivered\non).",[499,822,823,828,829,832,833,835],{},[517,824,825],{},[549,826,827],{"href":254},"Workflows"," give a linear procedure — ",[736,830,831],{},"charge → sleep 2 days → ship"," — a\nway to persist each step's result and resume after a sleep, automatically, across process restarts.\nPrerequisite: ",[549,834,811],{"href":152}," (the resume wakeup rides the same\ndispatch substrate) — no DDD or CQRS required, a workflow's steps can be as plain as any provider method.",[503,837,839],{"id":838},"none-of-this-is-a-rewrite","None of this is a rewrite",[499,841,842,843,846,847,739,850,739,853,739,856,859],{},"Every concept in this section ships as one package and one line in the plugins list — ",[736,844,845],{},"CqrsPlugin",",\n",[736,848,849],{},"DomainEventsPlugin",[736,851,852],{},"IntegrationEventsPlugin",[736,854,855],{},"SagaPlugin",[736,857,858],{},"WorkflowPlugin",". You adopt them per module,\nnot per app: one bounded context can run full DDD and CQRS while the rest of the app stays plain\ncontrollers and providers, side by side in the same build.",[499,861,862],{},"Nothing you write today has to be restructured to add one of these later — the plain controller you already\nhave keeps working; you're choosing where to add a command bus or an aggregate, not migrating off what's\nthere.",[503,864,866],{"id":865},"next-steps","Next steps",[511,868,869,881,890,895,900,905],{},[514,870,871,873,874,739,876,739,878,880],{},[549,872,228],{"href":229}," — model invariants with ",[736,875,738],{},[736,877,742],{},[736,879,746],{},".",[514,882,883,885,886,766,888,880],{},[549,884,233],{"href":234}," — split writes from reads with a typed ",[736,887,765],{},[736,889,769],{},[514,891,892,894],{},[549,893,781],{"href":239}," — a collection-like persistence boundary.",[514,896,897,899],{},[549,898,803],{"href":244}," — cross-context and cross-service events, plus the transactional outbox.",[514,901,902,904],{},[549,903,819],{"href":249}," — durable deadlines and process-state aggregates.",[514,906,907,909],{},[549,908,827],{"href":254}," — linear durable procedures that sleep across restarts.",{"title":911,"searchDepth":912,"depth":912,"links":913},"",2,[914,915,916,917,918,919],{"id":505,"depth":912,"text":506},{"id":544,"depth":912,"text":545},{"id":649,"depth":912,"text":650},{"id":726,"depth":912,"text":727},{"id":838,"depth":912,"text":839},{"id":865,"depth":912,"text":866},"When to reach for CQRS, Domain-Driven Design, the repository pattern, integration events, sagas, and workflows — and when a plain controller and a plain provider are still the right call.","md",null,{},{"icon":220,"title":142},{"title":219,"description":920},"64g8KHAqDevRlPqdpfr_lPKBsAC2qjzWUz_atoEbeLw",[928,930],{"title":214,"path":215,"stem":216,"description":929,"icon":217,"children":-1},"Nominal entity identifiers with the zero-runtime Branded type and the DI-free Id helper — generate, from, uuid.v7, uuid.v4, $type, and end-to-end id safety.",{"title":228,"path":229,"stem":230,"description":931,"icon":231,"children":-1},"Model your domain with the Entity, ValueObject, and AggregateRoot bases — value equality, dirty tracking, optimistic concurrency, and domain events.",1783300761903]