[{"data":1,"prerenderedAt":6572},["ShallowReactive",2],{"navigation_docs":3,"-docs-recipes-production-crud-api":493,"-docs-recipes-production-crud-api-surround":6569},[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":489,"body":495,"description":6562,"extension":6563,"links":6564,"meta":6565,"navigation":6566,"path":490,"seo":6567,"stem":491,"__hash__":6568},"docs\u002Fdocs\u002F09.recipes\u002F15.production-crud-api.md",{"type":496,"value":497,"toc":6551},"minimark",[498,535,540,548,935,938,1162,1165,1169,1190,1830,1859,1872,1876,1895,2503,2518,2546,3130,3148,3226,3434,3468,3472,3505,3862,3868,4434,4458,4462,4469,4822,4826,4840,5543,5556,5560,5578,5915,5918,6035,6047,6051,6076,6440,6470,6474,6547],[499,500,501,502,506,507,511,512,514,515,518,519,522,523,534],"p",{},"The ",[503,504,505],"a",{"href":454},"simple CRUD recipe"," is a thin controller over a plain repository — exactly\nright until the feature earns more. This one is the production shape: a resource served behind a shared\n",[508,509,510],"strong",{},"contract"," (so the frontend calls it with zero hand-written types), reads split from writes with ",[508,513,233],{},",\nvalidated ",[508,516,517],{},"pagination",", and an ",[508,520,521],{},"aggregate"," persisted through a Drizzle repository. Every block below is\nlifted from the runnable ",[503,524,528,529,533],{"href":525,"rel":526},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fflagship\u002Fpackages\u002Fcatalog",[527],"nofollow","flagship ",[530,531,532],"code",{},"catalog"," context",".",[536,537,539],"h2",{"id":538},"what-you-get","What you get",[499,541,542,543,547],{},"The end state is one class — the contract — that the backend serves and the frontend ",[544,545,546],"em",{},"is",". Here is the\nwhole API surface:",[549,550,556],"pre",{"className":551,"code":552,"filename":553,"language":554,"meta":555,"style":555},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { Contract, Route } from \"@heximon\u002Fcontract\";\nimport {\n  BrowseEventsQuerySchema,\n  EventCreatedResponse,\n  EventIdParam,\n  EventPageResponse,\n  EventResponse,\n  PublishEventBody,\n} from \".\u002Fcatalog.dto\";\n\n\u002F\u002F The shared, type-safe route table. The backend controller binds to it and the frontend client IS it\n\u002F\u002F (`new CatalogApi(transport)`), so request and response types cross the wire exactly once.\nexport class CatalogApi extends Contract({\n  prefix: \"\u002Fcatalog\",\n  routes: {\n    browse: Route.get(\"\u002Fevents\").query(BrowseEventsQuerySchema).responses({ 200: EventPageResponse }),\n    publish: Route.post(\"\u002Fevents\").body(PublishEventBody).responses({ 201: EventCreatedResponse }),\n    get: Route.get(\"\u002Fevents\u002F:id\").pathParams(EventIdParam).responses({ 200: EventResponse }),\n  },\n}) {}\n","src\u002Fcatalog\u002Fcontract\u002Fcatalog.api.ts","ts","",[530,557,558,600,608,617,625,633,641,649,657,674,681,688,694,720,739,749,809,864,918,924],{"__ignoreMap":555},[559,560,563,567,571,575,578,581,584,587,590,594,597],"span",{"class":561,"line":562},"line",1,[559,564,566],{"class":565},"s7zQu","import",[559,568,570],{"class":569},"sMK4o"," {",[559,572,574],{"class":573},"sTEyZ"," Contract",[559,576,577],{"class":569},",",[559,579,580],{"class":573}," Route",[559,582,583],{"class":569}," }",[559,585,586],{"class":565}," from",[559,588,589],{"class":569}," \"",[559,591,593],{"class":592},"sfazB","@heximon\u002Fcontract",[559,595,596],{"class":569},"\"",[559,598,599],{"class":569},";\n",[559,601,603,605],{"class":561,"line":602},2,[559,604,566],{"class":565},[559,606,607],{"class":569}," {\n",[559,609,611,614],{"class":561,"line":610},3,[559,612,613],{"class":573},"  BrowseEventsQuerySchema",[559,615,616],{"class":569},",\n",[559,618,620,623],{"class":561,"line":619},4,[559,621,622],{"class":573},"  EventCreatedResponse",[559,624,616],{"class":569},[559,626,628,631],{"class":561,"line":627},5,[559,629,630],{"class":573},"  EventIdParam",[559,632,616],{"class":569},[559,634,636,639],{"class":561,"line":635},6,[559,637,638],{"class":573},"  EventPageResponse",[559,640,616],{"class":569},[559,642,644,647],{"class":561,"line":643},7,[559,645,646],{"class":573},"  EventResponse",[559,648,616],{"class":569},[559,650,652,655],{"class":561,"line":651},8,[559,653,654],{"class":573},"  PublishEventBody",[559,656,616],{"class":569},[559,658,660,663,665,667,670,672],{"class":561,"line":659},9,[559,661,662],{"class":569},"}",[559,664,586],{"class":565},[559,666,589],{"class":569},[559,668,669],{"class":592},".\u002Fcatalog.dto",[559,671,596],{"class":569},[559,673,599],{"class":569},[559,675,677],{"class":561,"line":676},10,[559,678,680],{"emptyLinePlaceholder":679},true,"\n",[559,682,684],{"class":561,"line":683},11,[559,685,687],{"class":686},"sHwdD","\u002F\u002F The shared, type-safe route table. The backend controller binds to it and the frontend client IS it\n",[559,689,691],{"class":561,"line":690},12,[559,692,693],{"class":686},"\u002F\u002F (`new CatalogApi(transport)`), so request and response types cross the wire exactly once.\n",[559,695,697,700,704,708,711,714,717],{"class":561,"line":696},13,[559,698,699],{"class":565},"export",[559,701,703],{"class":702},"spNyl"," class",[559,705,707],{"class":706},"sBMFI"," CatalogApi",[559,709,710],{"class":702}," extends",[559,712,574],{"class":713},"s2Zo4",[559,715,716],{"class":573},"(",[559,718,719],{"class":569},"{\n",[559,721,723,727,730,732,735,737],{"class":561,"line":722},14,[559,724,726],{"class":725},"swJcz","  prefix",[559,728,729],{"class":569},":",[559,731,589],{"class":569},[559,733,734],{"class":592},"\u002Fcatalog",[559,736,596],{"class":569},[559,738,616],{"class":569},[559,740,742,745,747],{"class":561,"line":741},15,[559,743,744],{"class":725},"  routes",[559,746,729],{"class":569},[559,748,607],{"class":569},[559,750,752,755,757,759,761,764,766,768,771,773,776,778,781,784,786,789,791,794,798,800,803,805,807],{"class":561,"line":751},16,[559,753,754],{"class":725},"    browse",[559,756,729],{"class":569},[559,758,580],{"class":573},[559,760,534],{"class":569},[559,762,763],{"class":713},"get",[559,765,716],{"class":573},[559,767,596],{"class":569},[559,769,770],{"class":592},"\u002Fevents",[559,772,596],{"class":569},[559,774,775],{"class":573},")",[559,777,534],{"class":569},[559,779,780],{"class":713},"query",[559,782,783],{"class":573},"(BrowseEventsQuerySchema)",[559,785,534],{"class":569},[559,787,788],{"class":713},"responses",[559,790,716],{"class":573},[559,792,793],{"class":569},"{",[559,795,797],{"class":796},"sbssI"," 200",[559,799,729],{"class":569},[559,801,802],{"class":573}," EventPageResponse ",[559,804,662],{"class":569},[559,806,775],{"class":573},[559,808,616],{"class":569},[559,810,812,815,817,819,821,824,826,828,830,832,834,836,839,842,844,846,848,850,853,855,858,860,862],{"class":561,"line":811},17,[559,813,814],{"class":725},"    publish",[559,816,729],{"class":569},[559,818,580],{"class":573},[559,820,534],{"class":569},[559,822,823],{"class":713},"post",[559,825,716],{"class":573},[559,827,596],{"class":569},[559,829,770],{"class":592},[559,831,596],{"class":569},[559,833,775],{"class":573},[559,835,534],{"class":569},[559,837,838],{"class":713},"body",[559,840,841],{"class":573},"(PublishEventBody)",[559,843,534],{"class":569},[559,845,788],{"class":713},[559,847,716],{"class":573},[559,849,793],{"class":569},[559,851,852],{"class":796}," 201",[559,854,729],{"class":569},[559,856,857],{"class":573}," EventCreatedResponse ",[559,859,662],{"class":569},[559,861,775],{"class":573},[559,863,616],{"class":569},[559,865,867,870,872,874,876,878,880,882,885,887,889,891,894,897,899,901,903,905,907,909,912,914,916],{"class":561,"line":866},18,[559,868,869],{"class":725},"    get",[559,871,729],{"class":569},[559,873,580],{"class":573},[559,875,534],{"class":569},[559,877,763],{"class":713},[559,879,716],{"class":573},[559,881,596],{"class":569},[559,883,884],{"class":592},"\u002Fevents\u002F:id",[559,886,596],{"class":569},[559,888,775],{"class":573},[559,890,534],{"class":569},[559,892,893],{"class":713},"pathParams",[559,895,896],{"class":573},"(EventIdParam)",[559,898,534],{"class":569},[559,900,788],{"class":713},[559,902,716],{"class":573},[559,904,793],{"class":569},[559,906,797],{"class":796},[559,908,729],{"class":569},[559,910,911],{"class":573}," EventResponse ",[559,913,662],{"class":569},[559,915,775],{"class":573},[559,917,616],{"class":569},[559,919,921],{"class":561,"line":920},19,[559,922,923],{"class":569},"  },\n",[559,925,927,929,932],{"class":561,"line":926},20,[559,928,662],{"class":569},[559,930,931],{"class":573},") ",[559,933,934],{"class":569},"{}\n",[499,936,937],{},"A frontend imports that same class, hands it a transport, and calls it — the argument and the returned\nbody are inferred from the route schemas, with no request\u002Fresponse types written by hand:",[549,939,942],{"className":551,"code":940,"filename":941,"language":554,"meta":555,"style":555},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { CatalogApi } from \"..\u002Fcatalog\u002Fcontract\u002Fcatalog.api\";\n\nconst api = new CatalogApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\n\u002F\u002F `page` is `EventPageResponse`'s output — `{ data: EventResponse[], metadata: { queryCount } }`.\nconst page = await api.client.browse({\n  query: { filter: { name: { like: \"%Gala%\" }, priceAmount: { lte: 20_000 } }, page: 1, size: 20 },\n});\n","src\u002Fclient\u002Fcatalog.client.ts",[530,943,944,966,987,991,1038,1042,1047,1076,1154],{"__ignoreMap":555},[559,945,946,948,950,953,955,957,959,962,964],{"class":561,"line":562},[559,947,566],{"class":565},[559,949,570],{"class":569},[559,951,952],{"class":573}," ClientTransport",[559,954,583],{"class":569},[559,956,586],{"class":565},[559,958,589],{"class":569},[559,960,961],{"class":592},"@heximon\u002Fclient",[559,963,596],{"class":569},[559,965,599],{"class":569},[559,967,968,970,972,974,976,978,980,983,985],{"class":561,"line":602},[559,969,566],{"class":565},[559,971,570],{"class":569},[559,973,707],{"class":573},[559,975,583],{"class":569},[559,977,586],{"class":565},[559,979,589],{"class":569},[559,981,982],{"class":592},"..\u002Fcatalog\u002Fcontract\u002Fcatalog.api",[559,984,596],{"class":569},[559,986,599],{"class":569},[559,988,989],{"class":561,"line":610},[559,990,680],{"emptyLinePlaceholder":679},[559,992,993,996,999,1002,1005,1007,1010,1012,1015,1017,1019,1022,1024,1026,1029,1031,1033,1036],{"class":561,"line":619},[559,994,995],{"class":702},"const",[559,997,998],{"class":573}," api ",[559,1000,1001],{"class":569},"=",[559,1003,1004],{"class":569}," new",[559,1006,707],{"class":713},[559,1008,1009],{"class":573},"(ClientTransport",[559,1011,534],{"class":569},[559,1013,1014],{"class":713},"fetch",[559,1016,716],{"class":573},[559,1018,793],{"class":569},[559,1020,1021],{"class":725}," baseUrl",[559,1023,729],{"class":569},[559,1025,589],{"class":569},[559,1027,1028],{"class":592},"https:\u002F\u002Fapi.example.com",[559,1030,596],{"class":569},[559,1032,583],{"class":569},[559,1034,1035],{"class":573},"))",[559,1037,599],{"class":569},[559,1039,1040],{"class":561,"line":627},[559,1041,680],{"emptyLinePlaceholder":679},[559,1043,1044],{"class":561,"line":635},[559,1045,1046],{"class":686},"\u002F\u002F `page` is `EventPageResponse`'s output — `{ data: EventResponse[], metadata: { queryCount } }`.\n",[559,1048,1049,1051,1054,1056,1059,1062,1064,1067,1069,1072,1074],{"class":561,"line":643},[559,1050,995],{"class":702},[559,1052,1053],{"class":573}," page ",[559,1055,1001],{"class":569},[559,1057,1058],{"class":565}," await",[559,1060,1061],{"class":573}," api",[559,1063,534],{"class":569},[559,1065,1066],{"class":573},"client",[559,1068,534],{"class":569},[559,1070,1071],{"class":713},"browse",[559,1073,716],{"class":573},[559,1075,719],{"class":569},[559,1077,1078,1081,1083,1085,1088,1090,1092,1095,1097,1099,1102,1104,1106,1109,1111,1114,1117,1119,1121,1124,1126,1129,1131,1133,1136,1138,1141,1143,1146,1148,1151],{"class":561,"line":651},[559,1079,1080],{"class":725},"  query",[559,1082,729],{"class":569},[559,1084,570],{"class":569},[559,1086,1087],{"class":725}," filter",[559,1089,729],{"class":569},[559,1091,570],{"class":569},[559,1093,1094],{"class":725}," name",[559,1096,729],{"class":569},[559,1098,570],{"class":569},[559,1100,1101],{"class":725}," like",[559,1103,729],{"class":569},[559,1105,589],{"class":569},[559,1107,1108],{"class":592},"%Gala%",[559,1110,596],{"class":569},[559,1112,1113],{"class":569}," },",[559,1115,1116],{"class":725}," priceAmount",[559,1118,729],{"class":569},[559,1120,570],{"class":569},[559,1122,1123],{"class":725}," lte",[559,1125,729],{"class":569},[559,1127,1128],{"class":796}," 20_000",[559,1130,583],{"class":569},[559,1132,1113],{"class":569},[559,1134,1135],{"class":725}," page",[559,1137,729],{"class":569},[559,1139,1140],{"class":796}," 1",[559,1142,577],{"class":569},[559,1144,1145],{"class":725}," size",[559,1147,729],{"class":569},[559,1149,1150],{"class":796}," 20",[559,1152,1153],{"class":569}," },\n",[559,1155,1156,1158,1160],{"class":561,"line":659},[559,1157,662],{"class":569},[559,1159,775],{"class":573},[559,1161,599],{"class":569},[499,1163,1164],{},"Everything below is the server that makes that call type-check and return real, paginated data.",[536,1166,1168],{"id":1167},"define-the-contract-and-dtos","Define the contract and DTOs",[499,1170,1171,1172,1175,1176,1179,1180,1183,1184,1189],{},"The contract's schemas are the boundary. ",[530,1173,1174],{},"@heximon\u002Fschema"," ships two framework builders that carry the\nwhole list-endpoint story — ",[530,1177,1178],{},"QuerySchema"," for the request, ",[530,1181,1182],{},"PaginatedResponseSchema"," for the response — over\nany ",[503,1185,1188],{"href":1186,"rel":1187},"https:\u002F\u002Fstandardschema.dev",[527],"Standard Schema"," (zod here; valibot\u002Farktype work identically):",[549,1191,1194],{"className":551,"code":1192,"filename":1193,"language":554,"meta":555,"style":555},"import { PaginatedResponseSchema, QuerySchema, Schema, SchemaObject } from \"@heximon\u002Fschema\";\nimport { z } from \"zod\";\n\n\u002F\u002F The publish-event request body (price in minor units + an ISO-4217 currency).\nexport class PublishEventBody extends SchemaObject({\n  name: z.string().min(1),\n  capacity: z.number().int().min(1),\n  priceAmount: z.number().int().min(0),\n  currency: z.string().length(3),\n}) {}\n\n\u002F\u002F The event the API returns — the aggregate projected to a flat wire shape.\nexport class EventResponse extends SchemaObject({\n  id: z.string(),\n  name: z.string(),\n  slug: z.string(),\n  capacity: z.number(),\n  priceAmount: z.number(),\n  currency: z.string(),\n}) {}\n\n\u002F\u002F A URL query is always string-valued, so a numeric filter operand needs a coercing leaf: `z.coerce.number()`\n\u002F\u002F validates AND writes the coerced number back, so the repository reads a real `number`, not `\"2000\"`.\nconst numericOperand = z.coerce.number();\n\n\u002F\u002F The browse query DTO — validates the bracket-expanded query string against the RESPONSE field names, and\n\u002F\u002F bakes in validated, capped, defaulted page\u002Fsize pagination (`maxPageSize: 100`).\nexport class BrowseEventsQuerySchema extends QuerySchema.create(\n  { name: z.string(), capacity: numericOperand, priceAmount: numericOperand },\n  { maxPageSize: 100 },\n) {}\n\n\u002F\u002F A page of `EventResponse` read DTOs plus its total-count `metadata` — the `browse` route's success body.\nexport class EventPageResponse extends Schema(\n  PaginatedResponseSchema.create(EventResponse.schema),\n) {}\n\n\u002F\u002F The 201 publish response (only the new event's id) and the `:id` path parameter.\nexport class EventCreatedResponse extends SchemaObject({ id: z.string() }) {}\nexport class EventIdParam extends SchemaObject({ id: z.string() }) {}\n","src\u002Fcatalog\u002Fcontract\u002Fcatalog.dto.ts",[530,1195,1196,1232,1254,1258,1263,1280,1311,1346,1380,1409,1417,1421,1426,1443,1460,1476,1493,1509,1525,1541,1549,1554,1560,1566,1591,1596,1602,1608,1630,1669,1684,1691,1696,1702,1718,1738,1745,1750,1756,1794],{"__ignoreMap":555},[559,1197,1198,1200,1202,1205,1207,1210,1212,1215,1217,1220,1222,1224,1226,1228,1230],{"class":561,"line":562},[559,1199,566],{"class":565},[559,1201,570],{"class":569},[559,1203,1204],{"class":573}," PaginatedResponseSchema",[559,1206,577],{"class":569},[559,1208,1209],{"class":573}," QuerySchema",[559,1211,577],{"class":569},[559,1213,1214],{"class":573}," Schema",[559,1216,577],{"class":569},[559,1218,1219],{"class":573}," SchemaObject",[559,1221,583],{"class":569},[559,1223,586],{"class":565},[559,1225,589],{"class":569},[559,1227,1174],{"class":592},[559,1229,596],{"class":569},[559,1231,599],{"class":569},[559,1233,1234,1236,1238,1241,1243,1245,1247,1250,1252],{"class":561,"line":602},[559,1235,566],{"class":565},[559,1237,570],{"class":569},[559,1239,1240],{"class":573}," z",[559,1242,583],{"class":569},[559,1244,586],{"class":565},[559,1246,589],{"class":569},[559,1248,1249],{"class":592},"zod",[559,1251,596],{"class":569},[559,1253,599],{"class":569},[559,1255,1256],{"class":561,"line":610},[559,1257,680],{"emptyLinePlaceholder":679},[559,1259,1260],{"class":561,"line":619},[559,1261,1262],{"class":686},"\u002F\u002F The publish-event request body (price in minor units + an ISO-4217 currency).\n",[559,1264,1265,1267,1269,1272,1274,1276,1278],{"class":561,"line":627},[559,1266,699],{"class":565},[559,1268,703],{"class":702},[559,1270,1271],{"class":706}," PublishEventBody",[559,1273,710],{"class":702},[559,1275,1219],{"class":713},[559,1277,716],{"class":573},[559,1279,719],{"class":569},[559,1281,1282,1285,1287,1289,1291,1294,1297,1299,1302,1304,1307,1309],{"class":561,"line":635},[559,1283,1284],{"class":725},"  name",[559,1286,729],{"class":569},[559,1288,1240],{"class":573},[559,1290,534],{"class":569},[559,1292,1293],{"class":713},"string",[559,1295,1296],{"class":573},"()",[559,1298,534],{"class":569},[559,1300,1301],{"class":713},"min",[559,1303,716],{"class":573},[559,1305,1306],{"class":796},"1",[559,1308,775],{"class":573},[559,1310,616],{"class":569},[559,1312,1313,1316,1318,1320,1322,1325,1327,1329,1332,1334,1336,1338,1340,1342,1344],{"class":561,"line":643},[559,1314,1315],{"class":725},"  capacity",[559,1317,729],{"class":569},[559,1319,1240],{"class":573},[559,1321,534],{"class":569},[559,1323,1324],{"class":713},"number",[559,1326,1296],{"class":573},[559,1328,534],{"class":569},[559,1330,1331],{"class":713},"int",[559,1333,1296],{"class":573},[559,1335,534],{"class":569},[559,1337,1301],{"class":713},[559,1339,716],{"class":573},[559,1341,1306],{"class":796},[559,1343,775],{"class":573},[559,1345,616],{"class":569},[559,1347,1348,1351,1353,1355,1357,1359,1361,1363,1365,1367,1369,1371,1373,1376,1378],{"class":561,"line":651},[559,1349,1350],{"class":725},"  priceAmount",[559,1352,729],{"class":569},[559,1354,1240],{"class":573},[559,1356,534],{"class":569},[559,1358,1324],{"class":713},[559,1360,1296],{"class":573},[559,1362,534],{"class":569},[559,1364,1331],{"class":713},[559,1366,1296],{"class":573},[559,1368,534],{"class":569},[559,1370,1301],{"class":713},[559,1372,716],{"class":573},[559,1374,1375],{"class":796},"0",[559,1377,775],{"class":573},[559,1379,616],{"class":569},[559,1381,1382,1385,1387,1389,1391,1393,1395,1397,1400,1402,1405,1407],{"class":561,"line":659},[559,1383,1384],{"class":725},"  currency",[559,1386,729],{"class":569},[559,1388,1240],{"class":573},[559,1390,534],{"class":569},[559,1392,1293],{"class":713},[559,1394,1296],{"class":573},[559,1396,534],{"class":569},[559,1398,1399],{"class":713},"length",[559,1401,716],{"class":573},[559,1403,1404],{"class":796},"3",[559,1406,775],{"class":573},[559,1408,616],{"class":569},[559,1410,1411,1413,1415],{"class":561,"line":676},[559,1412,662],{"class":569},[559,1414,931],{"class":573},[559,1416,934],{"class":569},[559,1418,1419],{"class":561,"line":683},[559,1420,680],{"emptyLinePlaceholder":679},[559,1422,1423],{"class":561,"line":690},[559,1424,1425],{"class":686},"\u002F\u002F The event the API returns — the aggregate projected to a flat wire shape.\n",[559,1427,1428,1430,1432,1435,1437,1439,1441],{"class":561,"line":696},[559,1429,699],{"class":565},[559,1431,703],{"class":702},[559,1433,1434],{"class":706}," EventResponse",[559,1436,710],{"class":702},[559,1438,1219],{"class":713},[559,1440,716],{"class":573},[559,1442,719],{"class":569},[559,1444,1445,1448,1450,1452,1454,1456,1458],{"class":561,"line":722},[559,1446,1447],{"class":725},"  id",[559,1449,729],{"class":569},[559,1451,1240],{"class":573},[559,1453,534],{"class":569},[559,1455,1293],{"class":713},[559,1457,1296],{"class":573},[559,1459,616],{"class":569},[559,1461,1462,1464,1466,1468,1470,1472,1474],{"class":561,"line":741},[559,1463,1284],{"class":725},[559,1465,729],{"class":569},[559,1467,1240],{"class":573},[559,1469,534],{"class":569},[559,1471,1293],{"class":713},[559,1473,1296],{"class":573},[559,1475,616],{"class":569},[559,1477,1478,1481,1483,1485,1487,1489,1491],{"class":561,"line":751},[559,1479,1480],{"class":725},"  slug",[559,1482,729],{"class":569},[559,1484,1240],{"class":573},[559,1486,534],{"class":569},[559,1488,1293],{"class":713},[559,1490,1296],{"class":573},[559,1492,616],{"class":569},[559,1494,1495,1497,1499,1501,1503,1505,1507],{"class":561,"line":811},[559,1496,1315],{"class":725},[559,1498,729],{"class":569},[559,1500,1240],{"class":573},[559,1502,534],{"class":569},[559,1504,1324],{"class":713},[559,1506,1296],{"class":573},[559,1508,616],{"class":569},[559,1510,1511,1513,1515,1517,1519,1521,1523],{"class":561,"line":866},[559,1512,1350],{"class":725},[559,1514,729],{"class":569},[559,1516,1240],{"class":573},[559,1518,534],{"class":569},[559,1520,1324],{"class":713},[559,1522,1296],{"class":573},[559,1524,616],{"class":569},[559,1526,1527,1529,1531,1533,1535,1537,1539],{"class":561,"line":920},[559,1528,1384],{"class":725},[559,1530,729],{"class":569},[559,1532,1240],{"class":573},[559,1534,534],{"class":569},[559,1536,1293],{"class":713},[559,1538,1296],{"class":573},[559,1540,616],{"class":569},[559,1542,1543,1545,1547],{"class":561,"line":926},[559,1544,662],{"class":569},[559,1546,931],{"class":573},[559,1548,934],{"class":569},[559,1550,1552],{"class":561,"line":1551},21,[559,1553,680],{"emptyLinePlaceholder":679},[559,1555,1557],{"class":561,"line":1556},22,[559,1558,1559],{"class":686},"\u002F\u002F A URL query is always string-valued, so a numeric filter operand needs a coercing leaf: `z.coerce.number()`\n",[559,1561,1563],{"class":561,"line":1562},23,[559,1564,1565],{"class":686},"\u002F\u002F validates AND writes the coerced number back, so the repository reads a real `number`, not `\"2000\"`.\n",[559,1567,1569,1571,1574,1576,1578,1580,1583,1585,1587,1589],{"class":561,"line":1568},24,[559,1570,995],{"class":702},[559,1572,1573],{"class":573}," numericOperand ",[559,1575,1001],{"class":569},[559,1577,1240],{"class":573},[559,1579,534],{"class":569},[559,1581,1582],{"class":573},"coerce",[559,1584,534],{"class":569},[559,1586,1324],{"class":713},[559,1588,1296],{"class":573},[559,1590,599],{"class":569},[559,1592,1594],{"class":561,"line":1593},25,[559,1595,680],{"emptyLinePlaceholder":679},[559,1597,1599],{"class":561,"line":1598},26,[559,1600,1601],{"class":686},"\u002F\u002F The browse query DTO — validates the bracket-expanded query string against the RESPONSE field names, and\n",[559,1603,1605],{"class":561,"line":1604},27,[559,1606,1607],{"class":686},"\u002F\u002F bakes in validated, capped, defaulted page\u002Fsize pagination (`maxPageSize: 100`).\n",[559,1609,1611,1613,1615,1618,1620,1622,1624,1627],{"class":561,"line":1610},28,[559,1612,699],{"class":565},[559,1614,703],{"class":702},[559,1616,1617],{"class":706}," BrowseEventsQuerySchema",[559,1619,710],{"class":702},[559,1621,1209],{"class":573},[559,1623,534],{"class":569},[559,1625,1626],{"class":713},"create",[559,1628,1629],{"class":573},"(\n",[559,1631,1633,1636,1638,1640,1642,1644,1646,1648,1650,1653,1655,1658,1660,1662,1664,1666],{"class":561,"line":1632},29,[559,1634,1635],{"class":569},"  {",[559,1637,1094],{"class":725},[559,1639,729],{"class":569},[559,1641,1240],{"class":573},[559,1643,534],{"class":569},[559,1645,1293],{"class":713},[559,1647,1296],{"class":573},[559,1649,577],{"class":569},[559,1651,1652],{"class":725}," capacity",[559,1654,729],{"class":569},[559,1656,1657],{"class":573}," numericOperand",[559,1659,577],{"class":569},[559,1661,1116],{"class":725},[559,1663,729],{"class":569},[559,1665,1573],{"class":573},[559,1667,1668],{"class":569},"},\n",[559,1670,1672,1674,1677,1679,1682],{"class":561,"line":1671},30,[559,1673,1635],{"class":569},[559,1675,1676],{"class":725}," maxPageSize",[559,1678,729],{"class":569},[559,1680,1681],{"class":796}," 100",[559,1683,1153],{"class":569},[559,1685,1687,1689],{"class":561,"line":1686},31,[559,1688,931],{"class":573},[559,1690,934],{"class":569},[559,1692,1694],{"class":561,"line":1693},32,[559,1695,680],{"emptyLinePlaceholder":679},[559,1697,1699],{"class":561,"line":1698},33,[559,1700,1701],{"class":686},"\u002F\u002F A page of `EventResponse` read DTOs plus its total-count `metadata` — the `browse` route's success body.\n",[559,1703,1705,1707,1709,1712,1714,1716],{"class":561,"line":1704},34,[559,1706,699],{"class":565},[559,1708,703],{"class":702},[559,1710,1711],{"class":706}," EventPageResponse",[559,1713,710],{"class":702},[559,1715,1214],{"class":713},[559,1717,1629],{"class":573},[559,1719,1721,1724,1726,1728,1731,1733,1736],{"class":561,"line":1720},35,[559,1722,1723],{"class":573},"  PaginatedResponseSchema",[559,1725,534],{"class":569},[559,1727,1626],{"class":713},[559,1729,1730],{"class":573},"(EventResponse",[559,1732,534],{"class":569},[559,1734,1735],{"class":573},"schema)",[559,1737,616],{"class":569},[559,1739,1741,1743],{"class":561,"line":1740},36,[559,1742,931],{"class":573},[559,1744,934],{"class":569},[559,1746,1748],{"class":561,"line":1747},37,[559,1749,680],{"emptyLinePlaceholder":679},[559,1751,1753],{"class":561,"line":1752},38,[559,1754,1755],{"class":686},"\u002F\u002F The 201 publish response (only the new event's id) and the `:id` path parameter.\n",[559,1757,1759,1761,1763,1766,1768,1770,1772,1774,1777,1779,1781,1783,1785,1788,1790,1792],{"class":561,"line":1758},39,[559,1760,699],{"class":565},[559,1762,703],{"class":702},[559,1764,1765],{"class":706}," EventCreatedResponse",[559,1767,710],{"class":702},[559,1769,1219],{"class":713},[559,1771,716],{"class":573},[559,1773,793],{"class":569},[559,1775,1776],{"class":725}," id",[559,1778,729],{"class":569},[559,1780,1240],{"class":573},[559,1782,534],{"class":569},[559,1784,1293],{"class":713},[559,1786,1787],{"class":573},"() ",[559,1789,662],{"class":569},[559,1791,931],{"class":573},[559,1793,934],{"class":569},[559,1795,1797,1799,1801,1804,1806,1808,1810,1812,1814,1816,1818,1820,1822,1824,1826,1828],{"class":561,"line":1796},40,[559,1798,699],{"class":565},[559,1800,703],{"class":702},[559,1802,1803],{"class":706}," EventIdParam",[559,1805,710],{"class":702},[559,1807,1219],{"class":713},[559,1809,716],{"class":573},[559,1811,793],{"class":569},[559,1813,1776],{"class":725},[559,1815,729],{"class":569},[559,1817,1240],{"class":573},[559,1819,534],{"class":569},[559,1821,1293],{"class":713},[559,1823,1787],{"class":573},[559,1825,662],{"class":569},[559,1827,931],{"class":573},[559,1829,934],{"class":569},[499,1831,1832,1835,1836,1839,1840,1843,1844,1847,1848,1851,1852,1854,1855,1858],{},[530,1833,1834],{},"QuerySchema.create(shape, options)"," returns a class that is both the validated query ",[508,1837,1838],{},"type","\n(",[530,1841,1842],{},"{ filter?, order?, page, size }",") and the ",[530,1845,1846],{},"StandardSchemaV1"," ",[508,1849,1850],{},"value"," the ",[530,1853,1071],{}," route's ",[530,1856,1857],{},".query()","\nreferences — page mode is the default, both fields always present, defaulted and capped, so no handler-side\nfallback.",[499,1860,1861,1864,1865,1868,1869,534],{},[530,1862,1863],{},"PaginatedResponseSchema.create(itemSchema)"," wraps a per-item schema in ",[530,1866,1867],{},"{ data: item[], metadata: { queryCount } }"," — the total count alongside the current page, so a client renders \"1,204 results\" without a\nsecond request. Both are covered in depth in ",[503,1870,1871],{"href":442},"Paginate a list",[536,1873,1875],{"id":1874},"model-the-aggregate-and-its-repository","Model the aggregate and its repository",[499,1877,1878,1879,1882,1883,1886,1887,1890,1891,1894],{},"The write side owns an ",[508,1880,1881],{},"aggregate root"," — the consistency boundary where invariants live. ",[530,1884,1885],{},"Event"," holds\nits state as value objects (a ",[530,1888,1889],{},"Slug"," derived from the name, a ",[530,1892,1893],{},"Money"," price), validated on construction, so\na malformed event can never exist:",[549,1896,1899],{"className":551,"code":1897,"filename":1898,"language":554,"meta":555,"style":555},"import type { Branded } from \"@heximon\u002Fprimitives\";\nimport { Id } from \"@heximon\u002Fruntime\";\nimport { AggregateRoot } from \"@heximon\u002Fdomain\";\nimport { Money, Slug } from \"..\u002Fshared\u002Fvalue-objects\";\n\n\u002F\u002F A nominal brand: `EventId.generate()` mints a fresh v7 id, `EventId.from(raw)` adopts an inbound string.\nexport type EventId = Branded\u003Cstring, \"EventId\">;\nexport const EventId = Id\u003CEventId>();\n\n\u002F\u002F The scalars the publish command carries — no value objects, so the message stays transport-agnostic.\nexport interface PublishEventInput {\n  name: string;\n  capacity: number;\n  priceAmount: number;\n  currency: string;\n}\n\n\u002F\u002F Domain props hold value objects, not raw scalars.\ninterface EventProps extends Record\u003Cstring, unknown> {\n  name: string;\n  slug: Slug;\n  capacity: number;\n  price: Money;\n}\n\nexport class Event extends AggregateRoot\u003CEventProps, EventId> {\n  \u002F\u002F Built through the factory, never the raw constructor — the slug is derived and the price validated here.\n  public static create(id: EventId, props: PublishEventInput): Event {\n    return new Event(id, {\n      name: props.name,\n      slug: Slug.of(props.name),\n      capacity: props.capacity,\n      price: Money.of(props.priceAmount, props.currency),\n    });\n  }\n\n  public get name(): string {\n    return this.props.name;\n  }\n\n  public get price(): Money {\n    return this.props.price;\n  }\n\n  \u002F\u002F …`slug` and `capacity` getters — one line each, same shape.\n}\n","src\u002Fcatalog\u002Fdomain\u002Fevent.entity.ts",[530,1900,1901,1926,1948,1970,1997,2001,2006,2037,2062,2066,2071,2083,2094,2105,2115,2125,2130,2134,2139,2165,2175,2185,2195,2206,2210,2214,2240,2245,2282,2299,2315,2342,2358,2393,2402,2407,2411,2427,2442,2446,2450,2466,2482,2487,2492,2498],{"__ignoreMap":555},[559,1902,1903,1905,1908,1910,1913,1915,1917,1919,1922,1924],{"class":561,"line":562},[559,1904,566],{"class":565},[559,1906,1907],{"class":565}," type",[559,1909,570],{"class":569},[559,1911,1912],{"class":573}," Branded",[559,1914,583],{"class":569},[559,1916,586],{"class":565},[559,1918,589],{"class":569},[559,1920,1921],{"class":592},"@heximon\u002Fprimitives",[559,1923,596],{"class":569},[559,1925,599],{"class":569},[559,1927,1928,1930,1932,1935,1937,1939,1941,1944,1946],{"class":561,"line":602},[559,1929,566],{"class":565},[559,1931,570],{"class":569},[559,1933,1934],{"class":573}," Id",[559,1936,583],{"class":569},[559,1938,586],{"class":565},[559,1940,589],{"class":569},[559,1942,1943],{"class":592},"@heximon\u002Fruntime",[559,1945,596],{"class":569},[559,1947,599],{"class":569},[559,1949,1950,1952,1954,1957,1959,1961,1963,1966,1968],{"class":561,"line":610},[559,1951,566],{"class":565},[559,1953,570],{"class":569},[559,1955,1956],{"class":573}," AggregateRoot",[559,1958,583],{"class":569},[559,1960,586],{"class":565},[559,1962,589],{"class":569},[559,1964,1965],{"class":592},"@heximon\u002Fdomain",[559,1967,596],{"class":569},[559,1969,599],{"class":569},[559,1971,1972,1974,1976,1979,1981,1984,1986,1988,1990,1993,1995],{"class":561,"line":619},[559,1973,566],{"class":565},[559,1975,570],{"class":569},[559,1977,1978],{"class":573}," Money",[559,1980,577],{"class":569},[559,1982,1983],{"class":573}," Slug",[559,1985,583],{"class":569},[559,1987,586],{"class":565},[559,1989,589],{"class":569},[559,1991,1992],{"class":592},"..\u002Fshared\u002Fvalue-objects",[559,1994,596],{"class":569},[559,1996,599],{"class":569},[559,1998,1999],{"class":561,"line":627},[559,2000,680],{"emptyLinePlaceholder":679},[559,2002,2003],{"class":561,"line":635},[559,2004,2005],{"class":686},"\u002F\u002F A nominal brand: `EventId.generate()` mints a fresh v7 id, `EventId.from(raw)` adopts an inbound string.\n",[559,2007,2008,2010,2012,2015,2018,2020,2023,2025,2027,2029,2032,2034],{"class":561,"line":643},[559,2009,699],{"class":565},[559,2011,1907],{"class":702},[559,2013,2014],{"class":706}," EventId",[559,2016,2017],{"class":569}," =",[559,2019,1912],{"class":706},[559,2021,2022],{"class":569},"\u003C",[559,2024,1293],{"class":706},[559,2026,577],{"class":569},[559,2028,589],{"class":569},[559,2030,2031],{"class":592},"EventId",[559,2033,596],{"class":569},[559,2035,2036],{"class":569},">;\n",[559,2038,2039,2041,2044,2047,2049,2051,2053,2055,2058,2060],{"class":561,"line":651},[559,2040,699],{"class":565},[559,2042,2043],{"class":702}," const",[559,2045,2046],{"class":573}," EventId ",[559,2048,1001],{"class":569},[559,2050,1934],{"class":713},[559,2052,2022],{"class":569},[559,2054,2031],{"class":706},[559,2056,2057],{"class":569},">",[559,2059,1296],{"class":573},[559,2061,599],{"class":569},[559,2063,2064],{"class":561,"line":659},[559,2065,680],{"emptyLinePlaceholder":679},[559,2067,2068],{"class":561,"line":676},[559,2069,2070],{"class":686},"\u002F\u002F The scalars the publish command carries — no value objects, so the message stays transport-agnostic.\n",[559,2072,2073,2075,2078,2081],{"class":561,"line":683},[559,2074,699],{"class":565},[559,2076,2077],{"class":702}," interface",[559,2079,2080],{"class":706}," PublishEventInput",[559,2082,607],{"class":569},[559,2084,2085,2087,2089,2092],{"class":561,"line":690},[559,2086,1284],{"class":725},[559,2088,729],{"class":569},[559,2090,2091],{"class":706}," string",[559,2093,599],{"class":569},[559,2095,2096,2098,2100,2103],{"class":561,"line":696},[559,2097,1315],{"class":725},[559,2099,729],{"class":569},[559,2101,2102],{"class":706}," number",[559,2104,599],{"class":569},[559,2106,2107,2109,2111,2113],{"class":561,"line":722},[559,2108,1350],{"class":725},[559,2110,729],{"class":569},[559,2112,2102],{"class":706},[559,2114,599],{"class":569},[559,2116,2117,2119,2121,2123],{"class":561,"line":741},[559,2118,1384],{"class":725},[559,2120,729],{"class":569},[559,2122,2091],{"class":706},[559,2124,599],{"class":569},[559,2126,2127],{"class":561,"line":751},[559,2128,2129],{"class":569},"}\n",[559,2131,2132],{"class":561,"line":811},[559,2133,680],{"emptyLinePlaceholder":679},[559,2135,2136],{"class":561,"line":866},[559,2137,2138],{"class":686},"\u002F\u002F Domain props hold value objects, not raw scalars.\n",[559,2140,2141,2144,2147,2149,2152,2154,2156,2158,2161,2163],{"class":561,"line":920},[559,2142,2143],{"class":702},"interface",[559,2145,2146],{"class":706}," EventProps",[559,2148,710],{"class":702},[559,2150,2151],{"class":706}," Record",[559,2153,2022],{"class":569},[559,2155,1293],{"class":706},[559,2157,577],{"class":569},[559,2159,2160],{"class":706}," unknown",[559,2162,2057],{"class":569},[559,2164,607],{"class":569},[559,2166,2167,2169,2171,2173],{"class":561,"line":926},[559,2168,1284],{"class":725},[559,2170,729],{"class":569},[559,2172,2091],{"class":706},[559,2174,599],{"class":569},[559,2176,2177,2179,2181,2183],{"class":561,"line":1551},[559,2178,1480],{"class":725},[559,2180,729],{"class":569},[559,2182,1983],{"class":706},[559,2184,599],{"class":569},[559,2186,2187,2189,2191,2193],{"class":561,"line":1556},[559,2188,1315],{"class":725},[559,2190,729],{"class":569},[559,2192,2102],{"class":706},[559,2194,599],{"class":569},[559,2196,2197,2200,2202,2204],{"class":561,"line":1562},[559,2198,2199],{"class":725},"  price",[559,2201,729],{"class":569},[559,2203,1978],{"class":706},[559,2205,599],{"class":569},[559,2207,2208],{"class":561,"line":1568},[559,2209,2129],{"class":569},[559,2211,2212],{"class":561,"line":1593},[559,2213,680],{"emptyLinePlaceholder":679},[559,2215,2216,2218,2220,2223,2225,2227,2229,2232,2234,2236,2238],{"class":561,"line":1598},[559,2217,699],{"class":565},[559,2219,703],{"class":702},[559,2221,2222],{"class":706}," Event",[559,2224,710],{"class":702},[559,2226,1956],{"class":706},[559,2228,2022],{"class":569},[559,2230,2231],{"class":706},"EventProps",[559,2233,577],{"class":569},[559,2235,2014],{"class":706},[559,2237,2057],{"class":569},[559,2239,607],{"class":569},[559,2241,2242],{"class":561,"line":1604},[559,2243,2244],{"class":686},"  \u002F\u002F Built through the factory, never the raw constructor — the slug is derived and the price validated here.\n",[559,2246,2247,2250,2253,2256,2258,2262,2264,2266,2268,2271,2273,2275,2278,2280],{"class":561,"line":1610},[559,2248,2249],{"class":702},"  public",[559,2251,2252],{"class":702}," static",[559,2254,2255],{"class":725}," create",[559,2257,716],{"class":569},[559,2259,2261],{"class":2260},"sHdIc","id",[559,2263,729],{"class":569},[559,2265,2014],{"class":706},[559,2267,577],{"class":569},[559,2269,2270],{"class":2260}," props",[559,2272,729],{"class":569},[559,2274,2080],{"class":706},[559,2276,2277],{"class":569},"):",[559,2279,2222],{"class":706},[559,2281,607],{"class":569},[559,2283,2284,2287,2289,2291,2293,2295,2297],{"class":561,"line":1632},[559,2285,2286],{"class":565},"    return",[559,2288,1004],{"class":569},[559,2290,2222],{"class":713},[559,2292,716],{"class":725},[559,2294,2261],{"class":573},[559,2296,577],{"class":569},[559,2298,607],{"class":569},[559,2300,2301,2304,2306,2308,2310,2313],{"class":561,"line":1671},[559,2302,2303],{"class":725},"      name",[559,2305,729],{"class":569},[559,2307,2270],{"class":573},[559,2309,534],{"class":569},[559,2311,2312],{"class":573},"name",[559,2314,616],{"class":569},[559,2316,2317,2320,2322,2324,2326,2329,2331,2334,2336,2338,2340],{"class":561,"line":1686},[559,2318,2319],{"class":725},"      slug",[559,2321,729],{"class":569},[559,2323,1983],{"class":573},[559,2325,534],{"class":569},[559,2327,2328],{"class":713},"of",[559,2330,716],{"class":725},[559,2332,2333],{"class":573},"props",[559,2335,534],{"class":569},[559,2337,2312],{"class":573},[559,2339,775],{"class":725},[559,2341,616],{"class":569},[559,2343,2344,2347,2349,2351,2353,2356],{"class":561,"line":1693},[559,2345,2346],{"class":725},"      capacity",[559,2348,729],{"class":569},[559,2350,2270],{"class":573},[559,2352,534],{"class":569},[559,2354,2355],{"class":573},"capacity",[559,2357,616],{"class":569},[559,2359,2360,2363,2365,2367,2369,2371,2373,2375,2377,2380,2382,2384,2386,2389,2391],{"class":561,"line":1698},[559,2361,2362],{"class":725},"      price",[559,2364,729],{"class":569},[559,2366,1978],{"class":573},[559,2368,534],{"class":569},[559,2370,2328],{"class":713},[559,2372,716],{"class":725},[559,2374,2333],{"class":573},[559,2376,534],{"class":569},[559,2378,2379],{"class":573},"priceAmount",[559,2381,577],{"class":569},[559,2383,2270],{"class":573},[559,2385,534],{"class":569},[559,2387,2388],{"class":573},"currency",[559,2390,775],{"class":725},[559,2392,616],{"class":569},[559,2394,2395,2398,2400],{"class":561,"line":1704},[559,2396,2397],{"class":569},"    }",[559,2399,775],{"class":725},[559,2401,599],{"class":569},[559,2403,2404],{"class":561,"line":1720},[559,2405,2406],{"class":569},"  }\n",[559,2408,2409],{"class":561,"line":1740},[559,2410,680],{"emptyLinePlaceholder":679},[559,2412,2413,2415,2418,2420,2423,2425],{"class":561,"line":1747},[559,2414,2249],{"class":702},[559,2416,2417],{"class":702}," get",[559,2419,1094],{"class":725},[559,2421,2422],{"class":569},"():",[559,2424,2091],{"class":706},[559,2426,607],{"class":569},[559,2428,2429,2431,2434,2436,2438,2440],{"class":561,"line":1752},[559,2430,2286],{"class":565},[559,2432,2433],{"class":569}," this.",[559,2435,2333],{"class":573},[559,2437,534],{"class":569},[559,2439,2312],{"class":573},[559,2441,599],{"class":569},[559,2443,2444],{"class":561,"line":1758},[559,2445,2406],{"class":569},[559,2447,2448],{"class":561,"line":1796},[559,2449,680],{"emptyLinePlaceholder":679},[559,2451,2453,2455,2457,2460,2462,2464],{"class":561,"line":2452},41,[559,2454,2249],{"class":702},[559,2456,2417],{"class":702},[559,2458,2459],{"class":725}," price",[559,2461,2422],{"class":569},[559,2463,1978],{"class":706},[559,2465,607],{"class":569},[559,2467,2469,2471,2473,2475,2477,2480],{"class":561,"line":2468},42,[559,2470,2286],{"class":565},[559,2472,2433],{"class":569},[559,2474,2333],{"class":573},[559,2476,534],{"class":569},[559,2478,2479],{"class":573},"price",[559,2481,599],{"class":569},[559,2483,2485],{"class":561,"line":2484},43,[559,2486,2406],{"class":569},[559,2488,2490],{"class":561,"line":2489},44,[559,2491,680],{"emptyLinePlaceholder":679},[559,2493,2495],{"class":561,"line":2494},45,[559,2496,2497],{"class":686},"  \u002F\u002F …`slug` and `capacity` getters — one line each, same shape.\n",[559,2499,2501],{"class":561,"line":2500},46,[559,2502,2129],{"class":569},[499,2504,2505,2507,2508,2510,2511,2514,2515,2517],{},[530,2506,1893],{}," and ",[530,2509,1889],{}," are ordinary value objects — factories that enforce their invariant on construction;\n",[503,2512,2513],{"href":471},"Model a DDD aggregate"," builds that exact ",[530,2516,1893],{}," step by step.",[499,2519,2520,2521,2524,2525,2527,2528,2531,2532,2535,2536,2538,2539,2542,2543,2277],{},"A Drizzle table backs the aggregate. ",[530,2522,2523],{},"DrizzleSQLiteEntity.define"," binds the table to the entity constructor\nso the mapper rehydrates rows into ",[530,2526,1885],{}," instances, and ",[530,2529,2530],{},"valueObject(...)"," flattens each value object\nacross its columns — ",[530,2533,2534],{},"slug"," into one, ",[530,2537,2479],{}," into two (",[530,2540,2541],{},"price_amount"," \u002F ",[530,2544,2545],{},"price_currency",[549,2547,2550],{"className":551,"code":2548,"filename":2549,"language":554,"meta":555,"style":555},"import { DrizzleSQLiteEntity, dateObject, valueObject } from \"@heximon\u002Fdrizzle\u002Fsqlite-core\";\nimport { defineRelations } from \"drizzle-orm\";\nimport { integer, text } from \"drizzle-orm\u002Fsqlite-core\";\nimport { Event, type EventId } from \"..\u002Fdomain\u002Fevent.entity\";\nimport { Money, Slug } from \"..\u002Fshared\u002Fvalue-objects\";\n\n\u002F\u002F The framework-owned identity columns (`id`, `created_at`, `updated_at`, `version`) are required by the\n\u002F\u002F entity base; `version` drives optimistic concurrency on `save`.\nexport const Events = DrizzleSQLiteEntity.define(Event, \"events\", {\n  id: text(\"id\").notNull().primaryKey().$type\u003CEventId>(),\n  createdAt: dateObject(\"created_at\").notNull(),\n  updatedAt: dateObject(\"updated_at\").notNull(),\n  version: integer(\"version\").notNull().default(1),\n  name: text(\"name\").notNull(),\n  slug: valueObject(Slug, { value: text(\"slug\").notNull().unique() }),\n  capacity: integer(\"capacity\").notNull(),\n  price: valueObject(Money, {\n    amount: integer(\"price_amount\").notNull(),\n    currency: text(\"price_currency\").notNull(),\n  }),\n});\n\nexport const schema = { events: Events } as const;\nexport const relations = defineRelations(schema, () => ({}));\n","src\u002Fcatalog\u002Fpersistence\u002Fevents.schema.ts",[530,2551,2552,2584,2606,2633,2660,2684,2688,2693,2698,2732,2779,2807,2835,2874,2900,2951,2977,2992,3019,3046,3055,3063,3067,3096],{"__ignoreMap":555},[559,2553,2554,2556,2558,2561,2563,2566,2568,2571,2573,2575,2577,2580,2582],{"class":561,"line":562},[559,2555,566],{"class":565},[559,2557,570],{"class":569},[559,2559,2560],{"class":573}," DrizzleSQLiteEntity",[559,2562,577],{"class":569},[559,2564,2565],{"class":573}," dateObject",[559,2567,577],{"class":569},[559,2569,2570],{"class":573}," valueObject",[559,2572,583],{"class":569},[559,2574,586],{"class":565},[559,2576,589],{"class":569},[559,2578,2579],{"class":592},"@heximon\u002Fdrizzle\u002Fsqlite-core",[559,2581,596],{"class":569},[559,2583,599],{"class":569},[559,2585,2586,2588,2590,2593,2595,2597,2599,2602,2604],{"class":561,"line":602},[559,2587,566],{"class":565},[559,2589,570],{"class":569},[559,2591,2592],{"class":573}," defineRelations",[559,2594,583],{"class":569},[559,2596,586],{"class":565},[559,2598,589],{"class":569},[559,2600,2601],{"class":592},"drizzle-orm",[559,2603,596],{"class":569},[559,2605,599],{"class":569},[559,2607,2608,2610,2612,2615,2617,2620,2622,2624,2626,2629,2631],{"class":561,"line":610},[559,2609,566],{"class":565},[559,2611,570],{"class":569},[559,2613,2614],{"class":573}," integer",[559,2616,577],{"class":569},[559,2618,2619],{"class":573}," text",[559,2621,583],{"class":569},[559,2623,586],{"class":565},[559,2625,589],{"class":569},[559,2627,2628],{"class":592},"drizzle-orm\u002Fsqlite-core",[559,2630,596],{"class":569},[559,2632,599],{"class":569},[559,2634,2635,2637,2639,2641,2643,2645,2647,2649,2651,2653,2656,2658],{"class":561,"line":619},[559,2636,566],{"class":565},[559,2638,570],{"class":569},[559,2640,2222],{"class":573},[559,2642,577],{"class":569},[559,2644,1907],{"class":565},[559,2646,2014],{"class":573},[559,2648,583],{"class":569},[559,2650,586],{"class":565},[559,2652,589],{"class":569},[559,2654,2655],{"class":592},"..\u002Fdomain\u002Fevent.entity",[559,2657,596],{"class":569},[559,2659,599],{"class":569},[559,2661,2662,2664,2666,2668,2670,2672,2674,2676,2678,2680,2682],{"class":561,"line":627},[559,2663,566],{"class":565},[559,2665,570],{"class":569},[559,2667,1978],{"class":573},[559,2669,577],{"class":569},[559,2671,1983],{"class":573},[559,2673,583],{"class":569},[559,2675,586],{"class":565},[559,2677,589],{"class":569},[559,2679,1992],{"class":592},[559,2681,596],{"class":569},[559,2683,599],{"class":569},[559,2685,2686],{"class":561,"line":635},[559,2687,680],{"emptyLinePlaceholder":679},[559,2689,2690],{"class":561,"line":643},[559,2691,2692],{"class":686},"\u002F\u002F The framework-owned identity columns (`id`, `created_at`, `updated_at`, `version`) are required by the\n",[559,2694,2695],{"class":561,"line":651},[559,2696,2697],{"class":686},"\u002F\u002F entity base; `version` drives optimistic concurrency on `save`.\n",[559,2699,2700,2702,2704,2707,2709,2711,2713,2716,2719,2721,2723,2726,2728,2730],{"class":561,"line":659},[559,2701,699],{"class":565},[559,2703,2043],{"class":702},[559,2705,2706],{"class":573}," Events ",[559,2708,1001],{"class":569},[559,2710,2560],{"class":573},[559,2712,534],{"class":569},[559,2714,2715],{"class":713},"define",[559,2717,2718],{"class":573},"(Event",[559,2720,577],{"class":569},[559,2722,589],{"class":569},[559,2724,2725],{"class":592},"events",[559,2727,596],{"class":569},[559,2729,577],{"class":569},[559,2731,607],{"class":569},[559,2733,2734,2736,2738,2740,2742,2744,2746,2748,2750,2752,2755,2757,2759,2762,2764,2766,2769,2771,2773,2775,2777],{"class":561,"line":676},[559,2735,1447],{"class":725},[559,2737,729],{"class":569},[559,2739,2619],{"class":713},[559,2741,716],{"class":573},[559,2743,596],{"class":569},[559,2745,2261],{"class":592},[559,2747,596],{"class":569},[559,2749,775],{"class":573},[559,2751,534],{"class":569},[559,2753,2754],{"class":713},"notNull",[559,2756,1296],{"class":573},[559,2758,534],{"class":569},[559,2760,2761],{"class":713},"primaryKey",[559,2763,1296],{"class":573},[559,2765,534],{"class":569},[559,2767,2768],{"class":713},"$type",[559,2770,2022],{"class":569},[559,2772,2031],{"class":706},[559,2774,2057],{"class":569},[559,2776,1296],{"class":573},[559,2778,616],{"class":569},[559,2780,2781,2784,2786,2788,2790,2792,2795,2797,2799,2801,2803,2805],{"class":561,"line":683},[559,2782,2783],{"class":725},"  createdAt",[559,2785,729],{"class":569},[559,2787,2565],{"class":713},[559,2789,716],{"class":573},[559,2791,596],{"class":569},[559,2793,2794],{"class":592},"created_at",[559,2796,596],{"class":569},[559,2798,775],{"class":573},[559,2800,534],{"class":569},[559,2802,2754],{"class":713},[559,2804,1296],{"class":573},[559,2806,616],{"class":569},[559,2808,2809,2812,2814,2816,2818,2820,2823,2825,2827,2829,2831,2833],{"class":561,"line":690},[559,2810,2811],{"class":725},"  updatedAt",[559,2813,729],{"class":569},[559,2815,2565],{"class":713},[559,2817,716],{"class":573},[559,2819,596],{"class":569},[559,2821,2822],{"class":592},"updated_at",[559,2824,596],{"class":569},[559,2826,775],{"class":573},[559,2828,534],{"class":569},[559,2830,2754],{"class":713},[559,2832,1296],{"class":573},[559,2834,616],{"class":569},[559,2836,2837,2840,2842,2844,2846,2848,2851,2853,2855,2857,2859,2861,2863,2866,2868,2870,2872],{"class":561,"line":696},[559,2838,2839],{"class":725},"  version",[559,2841,729],{"class":569},[559,2843,2614],{"class":713},[559,2845,716],{"class":573},[559,2847,596],{"class":569},[559,2849,2850],{"class":592},"version",[559,2852,596],{"class":569},[559,2854,775],{"class":573},[559,2856,534],{"class":569},[559,2858,2754],{"class":713},[559,2860,1296],{"class":573},[559,2862,534],{"class":569},[559,2864,2865],{"class":713},"default",[559,2867,716],{"class":573},[559,2869,1306],{"class":796},[559,2871,775],{"class":573},[559,2873,616],{"class":569},[559,2875,2876,2878,2880,2882,2884,2886,2888,2890,2892,2894,2896,2898],{"class":561,"line":722},[559,2877,1284],{"class":725},[559,2879,729],{"class":569},[559,2881,2619],{"class":713},[559,2883,716],{"class":573},[559,2885,596],{"class":569},[559,2887,2312],{"class":592},[559,2889,596],{"class":569},[559,2891,775],{"class":573},[559,2893,534],{"class":569},[559,2895,2754],{"class":713},[559,2897,1296],{"class":573},[559,2899,616],{"class":569},[559,2901,2902,2904,2906,2908,2911,2913,2915,2918,2920,2922,2924,2926,2928,2930,2932,2934,2936,2938,2940,2943,2945,2947,2949],{"class":561,"line":741},[559,2903,1480],{"class":725},[559,2905,729],{"class":569},[559,2907,2570],{"class":713},[559,2909,2910],{"class":573},"(Slug",[559,2912,577],{"class":569},[559,2914,570],{"class":569},[559,2916,2917],{"class":725}," value",[559,2919,729],{"class":569},[559,2921,2619],{"class":713},[559,2923,716],{"class":573},[559,2925,596],{"class":569},[559,2927,2534],{"class":592},[559,2929,596],{"class":569},[559,2931,775],{"class":573},[559,2933,534],{"class":569},[559,2935,2754],{"class":713},[559,2937,1296],{"class":573},[559,2939,534],{"class":569},[559,2941,2942],{"class":713},"unique",[559,2944,1787],{"class":573},[559,2946,662],{"class":569},[559,2948,775],{"class":573},[559,2950,616],{"class":569},[559,2952,2953,2955,2957,2959,2961,2963,2965,2967,2969,2971,2973,2975],{"class":561,"line":751},[559,2954,1315],{"class":725},[559,2956,729],{"class":569},[559,2958,2614],{"class":713},[559,2960,716],{"class":573},[559,2962,596],{"class":569},[559,2964,2355],{"class":592},[559,2966,596],{"class":569},[559,2968,775],{"class":573},[559,2970,534],{"class":569},[559,2972,2754],{"class":713},[559,2974,1296],{"class":573},[559,2976,616],{"class":569},[559,2978,2979,2981,2983,2985,2988,2990],{"class":561,"line":811},[559,2980,2199],{"class":725},[559,2982,729],{"class":569},[559,2984,2570],{"class":713},[559,2986,2987],{"class":573},"(Money",[559,2989,577],{"class":569},[559,2991,607],{"class":569},[559,2993,2994,2997,2999,3001,3003,3005,3007,3009,3011,3013,3015,3017],{"class":561,"line":866},[559,2995,2996],{"class":725},"    amount",[559,2998,729],{"class":569},[559,3000,2614],{"class":713},[559,3002,716],{"class":573},[559,3004,596],{"class":569},[559,3006,2541],{"class":592},[559,3008,596],{"class":569},[559,3010,775],{"class":573},[559,3012,534],{"class":569},[559,3014,2754],{"class":713},[559,3016,1296],{"class":573},[559,3018,616],{"class":569},[559,3020,3021,3024,3026,3028,3030,3032,3034,3036,3038,3040,3042,3044],{"class":561,"line":920},[559,3022,3023],{"class":725},"    currency",[559,3025,729],{"class":569},[559,3027,2619],{"class":713},[559,3029,716],{"class":573},[559,3031,596],{"class":569},[559,3033,2545],{"class":592},[559,3035,596],{"class":569},[559,3037,775],{"class":573},[559,3039,534],{"class":569},[559,3041,2754],{"class":713},[559,3043,1296],{"class":573},[559,3045,616],{"class":569},[559,3047,3048,3051,3053],{"class":561,"line":926},[559,3049,3050],{"class":569},"  }",[559,3052,775],{"class":573},[559,3054,616],{"class":569},[559,3056,3057,3059,3061],{"class":561,"line":1551},[559,3058,662],{"class":569},[559,3060,775],{"class":573},[559,3062,599],{"class":569},[559,3064,3065],{"class":561,"line":1556},[559,3066,680],{"emptyLinePlaceholder":679},[559,3068,3069,3071,3073,3076,3078,3080,3083,3085,3087,3089,3092,3094],{"class":561,"line":1562},[559,3070,699],{"class":565},[559,3072,2043],{"class":702},[559,3074,3075],{"class":573}," schema ",[559,3077,1001],{"class":569},[559,3079,570],{"class":569},[559,3081,3082],{"class":725}," events",[559,3084,729],{"class":569},[559,3086,2706],{"class":573},[559,3088,662],{"class":569},[559,3090,3091],{"class":565}," as",[559,3093,2043],{"class":702},[559,3095,599],{"class":569},[559,3097,3098,3100,3102,3105,3107,3109,3112,3114,3117,3120,3123,3126,3128],{"class":561,"line":1568},[559,3099,699],{"class":565},[559,3101,2043],{"class":702},[559,3103,3104],{"class":573}," relations ",[559,3106,1001],{"class":569},[559,3108,2592],{"class":713},[559,3110,3111],{"class":573},"(schema",[559,3113,577],{"class":569},[559,3115,3116],{"class":569}," ()",[559,3118,3119],{"class":702}," =>",[559,3121,3122],{"class":573}," (",[559,3124,3125],{"class":569},"{}",[559,3127,1035],{"class":573},[559,3129,599],{"class":569},[499,3131,3132,3133,3136,3137,3140,3141,616,3144,3147],{},"The repository is a ",[508,3134,3135],{},"port"," (an abstract class, so it is both a DI token and a nominal type) plus a\ndialect concrete. The query and command handlers inject the port; the concrete extends the framework's\nentity-repository base, inheriting the full CRUD surface — ",[530,3138,3139],{},"save"," (optimistic-concurrency), ",[530,3142,3143],{},"getById",[530,3145,3146],{},"getPage",", counting — with no method bodies to write:",[549,3149,3152],{"className":551,"code":3150,"filename":3151,"language":554,"meta":555,"style":555},"import { Repository } from \"@heximon\u002Fdomain\";\nimport type { Event } from \"..\u002Fdomain\u002Fevent.entity\";\n\nexport abstract class EventRepository extends Repository\u003CEvent> {}\n","src\u002Fcatalog\u002Fports\u002Fevent.repository.ts",[530,3153,3154,3175,3197,3201],{"__ignoreMap":555},[559,3155,3156,3158,3160,3163,3165,3167,3169,3171,3173],{"class":561,"line":562},[559,3157,566],{"class":565},[559,3159,570],{"class":569},[559,3161,3162],{"class":573}," Repository",[559,3164,583],{"class":569},[559,3166,586],{"class":565},[559,3168,589],{"class":569},[559,3170,1965],{"class":592},[559,3172,596],{"class":569},[559,3174,599],{"class":569},[559,3176,3177,3179,3181,3183,3185,3187,3189,3191,3193,3195],{"class":561,"line":602},[559,3178,566],{"class":565},[559,3180,1907],{"class":565},[559,3182,570],{"class":569},[559,3184,2222],{"class":573},[559,3186,583],{"class":569},[559,3188,586],{"class":565},[559,3190,589],{"class":569},[559,3192,2655],{"class":592},[559,3194,596],{"class":569},[559,3196,599],{"class":569},[559,3198,3199],{"class":561,"line":610},[559,3200,680],{"emptyLinePlaceholder":679},[559,3202,3203,3205,3208,3210,3213,3215,3217,3219,3221,3223],{"class":561,"line":619},[559,3204,699],{"class":565},[559,3206,3207],{"class":702}," abstract",[559,3209,703],{"class":702},[559,3211,3212],{"class":706}," EventRepository",[559,3214,710],{"class":702},[559,3216,3162],{"class":706},[559,3218,2022],{"class":569},[559,3220,1885],{"class":706},[559,3222,2057],{"class":569},[559,3224,3225],{"class":569}," {}\n",[549,3227,3230],{"className":551,"code":3228,"filename":3229,"language":554,"meta":555,"style":555},"import { DrizzleLibSQLDatabase, DrizzleLibSQLEntityRepository } from \"@heximon\u002Fdrizzle\u002Flibsql\";\nimport { AppDatabase } from \"..\u002F..\u002Fdatabase\u002Fapp-database\";\nimport { Event } from \"..\u002Fdomain\u002Fevent.entity\";\nimport { EventRepository } from \"..\u002Fports\u002Fevent.repository\";\n\n\u002F\u002F Binds the `\"events\"` schema key + the entity constructor and `implements EventRepository` so the module\n\u002F\u002F binds it under the port; its one dependency is the app's `AppDatabase`. Swap for the MySQL twin, no\n\u002F\u002F handler changes.\nexport class SqliteEventRepository\n  extends DrizzleLibSQLEntityRepository\u003CDrizzleLibSQLDatabase, Event>\n  implements EventRepository\n{\n  public constructor(database: AppDatabase) {\n    super(database, \"events\", Event);\n  }\n}\n","src\u002Fcatalog\u002Fpersistence\u002Fevent.repository.ts",[530,3231,3232,3259,3281,3301,3322,3326,3331,3336,3341,3350,3369,3377,3381,3401,3426,3430],{"__ignoreMap":555},[559,3233,3234,3236,3238,3241,3243,3246,3248,3250,3252,3255,3257],{"class":561,"line":562},[559,3235,566],{"class":565},[559,3237,570],{"class":569},[559,3239,3240],{"class":573}," DrizzleLibSQLDatabase",[559,3242,577],{"class":569},[559,3244,3245],{"class":573}," DrizzleLibSQLEntityRepository",[559,3247,583],{"class":569},[559,3249,586],{"class":565},[559,3251,589],{"class":569},[559,3253,3254],{"class":592},"@heximon\u002Fdrizzle\u002Flibsql",[559,3256,596],{"class":569},[559,3258,599],{"class":569},[559,3260,3261,3263,3265,3268,3270,3272,3274,3277,3279],{"class":561,"line":602},[559,3262,566],{"class":565},[559,3264,570],{"class":569},[559,3266,3267],{"class":573}," AppDatabase",[559,3269,583],{"class":569},[559,3271,586],{"class":565},[559,3273,589],{"class":569},[559,3275,3276],{"class":592},"..\u002F..\u002Fdatabase\u002Fapp-database",[559,3278,596],{"class":569},[559,3280,599],{"class":569},[559,3282,3283,3285,3287,3289,3291,3293,3295,3297,3299],{"class":561,"line":610},[559,3284,566],{"class":565},[559,3286,570],{"class":569},[559,3288,2222],{"class":573},[559,3290,583],{"class":569},[559,3292,586],{"class":565},[559,3294,589],{"class":569},[559,3296,2655],{"class":592},[559,3298,596],{"class":569},[559,3300,599],{"class":569},[559,3302,3303,3305,3307,3309,3311,3313,3315,3318,3320],{"class":561,"line":619},[559,3304,566],{"class":565},[559,3306,570],{"class":569},[559,3308,3212],{"class":573},[559,3310,583],{"class":569},[559,3312,586],{"class":565},[559,3314,589],{"class":569},[559,3316,3317],{"class":592},"..\u002Fports\u002Fevent.repository",[559,3319,596],{"class":569},[559,3321,599],{"class":569},[559,3323,3324],{"class":561,"line":627},[559,3325,680],{"emptyLinePlaceholder":679},[559,3327,3328],{"class":561,"line":635},[559,3329,3330],{"class":686},"\u002F\u002F Binds the `\"events\"` schema key + the entity constructor and `implements EventRepository` so the module\n",[559,3332,3333],{"class":561,"line":643},[559,3334,3335],{"class":686},"\u002F\u002F binds it under the port; its one dependency is the app's `AppDatabase`. Swap for the MySQL twin, no\n",[559,3337,3338],{"class":561,"line":651},[559,3339,3340],{"class":686},"\u002F\u002F handler changes.\n",[559,3342,3343,3345,3347],{"class":561,"line":659},[559,3344,699],{"class":565},[559,3346,703],{"class":702},[559,3348,3349],{"class":706}," SqliteEventRepository\n",[559,3351,3352,3355,3357,3359,3362,3364,3366],{"class":561,"line":676},[559,3353,3354],{"class":702},"  extends",[559,3356,3245],{"class":706},[559,3358,2022],{"class":569},[559,3360,3361],{"class":706},"DrizzleLibSQLDatabase",[559,3363,577],{"class":569},[559,3365,2222],{"class":706},[559,3367,3368],{"class":569},">\n",[559,3370,3371,3374],{"class":561,"line":683},[559,3372,3373],{"class":702},"  implements",[559,3375,3376],{"class":706}," EventRepository\n",[559,3378,3379],{"class":561,"line":690},[559,3380,719],{"class":569},[559,3382,3383,3385,3388,3390,3393,3395,3397,3399],{"class":561,"line":696},[559,3384,2249],{"class":702},[559,3386,3387],{"class":702}," constructor",[559,3389,716],{"class":569},[559,3391,3392],{"class":2260},"database",[559,3394,729],{"class":569},[559,3396,3267],{"class":706},[559,3398,775],{"class":569},[559,3400,607],{"class":569},[559,3402,3403,3406,3408,3410,3412,3414,3416,3418,3420,3422,3424],{"class":561,"line":722},[559,3404,3405],{"class":573},"    super",[559,3407,716],{"class":725},[559,3409,3392],{"class":573},[559,3411,577],{"class":569},[559,3413,589],{"class":569},[559,3415,2725],{"class":592},[559,3417,596],{"class":569},[559,3419,577],{"class":569},[559,3421,2222],{"class":573},[559,3423,775],{"class":725},[559,3425,599],{"class":569},[559,3427,3428],{"class":561,"line":741},[559,3429,2406],{"class":569},[559,3431,3432],{"class":561,"line":751},[559,3433,2129],{"class":569},[499,3435,3436,3439,3440,3443,3444,3447,3448,3451,3452,3455,3456,3459,3460,3463,3464,3467],{},[530,3437,3438],{},"AppDatabase"," is a named ",[530,3441,3442],{},"DrizzleLibSQLDatabase\u003CSchema, Relations>"," subclass — the one concrete DI token\nevery repository injects. Its ",[530,3445,3446],{},"DrizzleLibSQLConfig"," and the ",[530,3449,3450],{},"DatabaseModule"," that provides it are wired\nexactly as ",[503,3453,453],{"href":3454},"\u002Fdocs\u002Frecipes\u002Fcrud-api#wire-the-database"," shows; point its schema at the\n",[530,3457,3458],{},"{ events }"," table above. ",[503,3461,3462],{"href":83},"Drizzle persistence"," goes deep on the mapper,\n",[530,3465,3466],{},"valueObject"," columns, and the three dialects.",[536,3469,3471],{"id":3470},"handle-the-reads","Handle the reads",[499,3473,3474,3475,3478,3479,3482,3483,3486,3487,3489,3490,3493,3494,3497,3498,3500,3501,3504],{},"A ",[508,3476,3477],{},"query mapper"," is the read side's single source of truth. One declarative ",[530,3480,3481],{},"fields"," map drives BOTH\ndirections: ",[530,3484,3485],{},"toResponse"," projects an ",[530,3488,1885],{}," aggregate OUT to a flat DTO, and the inherited ",[530,3491,3492],{},"toQuery","\ntranslates a response-vocabulary filter\u002Forder back IN to an ",[530,3495,3496],{},"EntityQuery"," the repository accepts — so a\nrename like ",[530,3499,2379],{}," → ",[530,3502,3503],{},"price.amount"," stays in lockstep across reads and filters:",[549,3506,3509],{"className":551,"code":3507,"filename":3508,"language":554,"meta":555,"style":555},"import { type FieldMap, QueryMapper } from \"@heximon\u002Fdomain\";\nimport type { EventResponse } from \"..\u002Fcontract\u002Fcatalog.dto\";\nimport type { Event } from \"..\u002Fdomain\u002Fevent.entity\";\n\nexport class EventQueryMapper extends QueryMapper\u003CEventResponse, Event> {\n  \u002F\u002F The response-field → entity-path correspondence (the renamed `price` sub-fields are dotted paths).\n  protected readonly fields = {\n    name: \"name\",\n    capacity: \"capacity\",\n    priceAmount: \"price.amount\",\n    currency: \"price.currency\",\n  } satisfies FieldMap\u003CEventResponse, Event>;\n\n  public toResponse(event: Event): EventResponse {\n    return {\n      id: event.id,\n      name: event.name,\n      slug: event.slug.toString(),\n      capacity: event.capacity,\n      priceAmount: event.price.amount,\n      currency: event.price.currency,\n    };\n  }\n}\n","src\u002Fcatalog\u002Fquery\u002Fevent.query-mapper.ts",[530,3510,3511,3539,3562,3584,3588,3614,3619,3634,3649,3664,3679,3694,3713,3717,3739,3745,3761,3775,3796,3810,3830,3849,3854,3858],{"__ignoreMap":555},[559,3512,3513,3515,3517,3519,3522,3524,3527,3529,3531,3533,3535,3537],{"class":561,"line":562},[559,3514,566],{"class":565},[559,3516,570],{"class":569},[559,3518,1907],{"class":565},[559,3520,3521],{"class":573}," FieldMap",[559,3523,577],{"class":569},[559,3525,3526],{"class":573}," QueryMapper",[559,3528,583],{"class":569},[559,3530,586],{"class":565},[559,3532,589],{"class":569},[559,3534,1965],{"class":592},[559,3536,596],{"class":569},[559,3538,599],{"class":569},[559,3540,3541,3543,3545,3547,3549,3551,3553,3555,3558,3560],{"class":561,"line":602},[559,3542,566],{"class":565},[559,3544,1907],{"class":565},[559,3546,570],{"class":569},[559,3548,1434],{"class":573},[559,3550,583],{"class":569},[559,3552,586],{"class":565},[559,3554,589],{"class":569},[559,3556,3557],{"class":592},"..\u002Fcontract\u002Fcatalog.dto",[559,3559,596],{"class":569},[559,3561,599],{"class":569},[559,3563,3564,3566,3568,3570,3572,3574,3576,3578,3580,3582],{"class":561,"line":610},[559,3565,566],{"class":565},[559,3567,1907],{"class":565},[559,3569,570],{"class":569},[559,3571,2222],{"class":573},[559,3573,583],{"class":569},[559,3575,586],{"class":565},[559,3577,589],{"class":569},[559,3579,2655],{"class":592},[559,3581,596],{"class":569},[559,3583,599],{"class":569},[559,3585,3586],{"class":561,"line":619},[559,3587,680],{"emptyLinePlaceholder":679},[559,3589,3590,3592,3594,3597,3599,3601,3603,3606,3608,3610,3612],{"class":561,"line":627},[559,3591,699],{"class":565},[559,3593,703],{"class":702},[559,3595,3596],{"class":706}," EventQueryMapper",[559,3598,710],{"class":702},[559,3600,3526],{"class":706},[559,3602,2022],{"class":569},[559,3604,3605],{"class":706},"EventResponse",[559,3607,577],{"class":569},[559,3609,2222],{"class":706},[559,3611,2057],{"class":569},[559,3613,607],{"class":569},[559,3615,3616],{"class":561,"line":635},[559,3617,3618],{"class":686},"  \u002F\u002F The response-field → entity-path correspondence (the renamed `price` sub-fields are dotted paths).\n",[559,3620,3621,3624,3627,3630,3632],{"class":561,"line":643},[559,3622,3623],{"class":702},"  protected",[559,3625,3626],{"class":702}," readonly",[559,3628,3629],{"class":725}," fields",[559,3631,2017],{"class":569},[559,3633,607],{"class":569},[559,3635,3636,3639,3641,3643,3645,3647],{"class":561,"line":651},[559,3637,3638],{"class":725},"    name",[559,3640,729],{"class":569},[559,3642,589],{"class":569},[559,3644,2312],{"class":592},[559,3646,596],{"class":569},[559,3648,616],{"class":569},[559,3650,3651,3654,3656,3658,3660,3662],{"class":561,"line":659},[559,3652,3653],{"class":725},"    capacity",[559,3655,729],{"class":569},[559,3657,589],{"class":569},[559,3659,2355],{"class":592},[559,3661,596],{"class":569},[559,3663,616],{"class":569},[559,3665,3666,3669,3671,3673,3675,3677],{"class":561,"line":676},[559,3667,3668],{"class":725},"    priceAmount",[559,3670,729],{"class":569},[559,3672,589],{"class":569},[559,3674,3503],{"class":592},[559,3676,596],{"class":569},[559,3678,616],{"class":569},[559,3680,3681,3683,3685,3687,3690,3692],{"class":561,"line":683},[559,3682,3023],{"class":725},[559,3684,729],{"class":569},[559,3686,589],{"class":569},[559,3688,3689],{"class":592},"price.currency",[559,3691,596],{"class":569},[559,3693,616],{"class":569},[559,3695,3696,3698,3701,3703,3705,3707,3709,3711],{"class":561,"line":690},[559,3697,3050],{"class":569},[559,3699,3700],{"class":565}," satisfies",[559,3702,3521],{"class":706},[559,3704,2022],{"class":569},[559,3706,3605],{"class":706},[559,3708,577],{"class":569},[559,3710,2222],{"class":706},[559,3712,2036],{"class":569},[559,3714,3715],{"class":561,"line":696},[559,3716,680],{"emptyLinePlaceholder":679},[559,3718,3719,3721,3724,3726,3729,3731,3733,3735,3737],{"class":561,"line":722},[559,3720,2249],{"class":702},[559,3722,3723],{"class":725}," toResponse",[559,3725,716],{"class":569},[559,3727,3728],{"class":2260},"event",[559,3730,729],{"class":569},[559,3732,2222],{"class":706},[559,3734,2277],{"class":569},[559,3736,1434],{"class":706},[559,3738,607],{"class":569},[559,3740,3741,3743],{"class":561,"line":741},[559,3742,2286],{"class":565},[559,3744,607],{"class":569},[559,3746,3747,3750,3752,3755,3757,3759],{"class":561,"line":751},[559,3748,3749],{"class":725},"      id",[559,3751,729],{"class":569},[559,3753,3754],{"class":573}," event",[559,3756,534],{"class":569},[559,3758,2261],{"class":573},[559,3760,616],{"class":569},[559,3762,3763,3765,3767,3769,3771,3773],{"class":561,"line":811},[559,3764,2303],{"class":725},[559,3766,729],{"class":569},[559,3768,3754],{"class":573},[559,3770,534],{"class":569},[559,3772,2312],{"class":573},[559,3774,616],{"class":569},[559,3776,3777,3779,3781,3783,3785,3787,3789,3792,3794],{"class":561,"line":866},[559,3778,2319],{"class":725},[559,3780,729],{"class":569},[559,3782,3754],{"class":573},[559,3784,534],{"class":569},[559,3786,2534],{"class":573},[559,3788,534],{"class":569},[559,3790,3791],{"class":713},"toString",[559,3793,1296],{"class":725},[559,3795,616],{"class":569},[559,3797,3798,3800,3802,3804,3806,3808],{"class":561,"line":920},[559,3799,2346],{"class":725},[559,3801,729],{"class":569},[559,3803,3754],{"class":573},[559,3805,534],{"class":569},[559,3807,2355],{"class":573},[559,3809,616],{"class":569},[559,3811,3812,3815,3817,3819,3821,3823,3825,3828],{"class":561,"line":926},[559,3813,3814],{"class":725},"      priceAmount",[559,3816,729],{"class":569},[559,3818,3754],{"class":573},[559,3820,534],{"class":569},[559,3822,2479],{"class":573},[559,3824,534],{"class":569},[559,3826,3827],{"class":573},"amount",[559,3829,616],{"class":569},[559,3831,3832,3835,3837,3839,3841,3843,3845,3847],{"class":561,"line":1551},[559,3833,3834],{"class":725},"      currency",[559,3836,729],{"class":569},[559,3838,3754],{"class":573},[559,3840,534],{"class":569},[559,3842,2479],{"class":573},[559,3844,534],{"class":569},[559,3846,2388],{"class":573},[559,3848,616],{"class":569},[559,3850,3851],{"class":561,"line":1556},[559,3852,3853],{"class":569},"    };\n",[559,3855,3856],{"class":561,"line":1562},[559,3857,2406],{"class":569},[559,3859,3860],{"class":561,"line":1568},[559,3861,2129],{"class":569},[499,3863,3864,3865,3867],{},"The browse handler is the whole read path in one method: map the validated query to an ",[530,3866,3496],{},", page\nthe repository, and project each aggregate back to a DTO — so the query resolves to plain, cache-safe data,\nnever a domain aggregate:",[549,3869,3872],{"className":551,"code":3870,"filename":3871,"language":554,"meta":555,"style":555},"import { Query, type QueryHandler } from \"@heximon\u002Fcqrs\";\nimport { BrowseEventsQuerySchema, type EventResponse } from \"..\u002Fcontract\u002Fcatalog.dto\";\nimport { EventRepository } from \"..\u002Fports\u002Fevent.repository\";\nimport { EventQueryMapper } from \".\u002Fevent.query-mapper\";\n\nexport type BrowseEventsInput = InstanceType\u003Ctypeof BrowseEventsQuerySchema>;\n\n\u002F\u002F A page of read DTOs plus its total-count metadata — the query's result type, carried by `Query\u003CEventPage>`.\nexport interface EventPage {\n  readonly data: readonly EventResponse[];\n  readonly metadata: { readonly queryCount: number };\n}\n\nexport class BrowseEventsQuery extends Query\u003CEventPage> {\n  public constructor(public readonly input: BrowseEventsInput) {\n    super();\n  }\n}\n\nexport class BrowseEventsQueryHandler implements QueryHandler\u003CBrowseEventsQuery> {\n  public constructor(\n    private readonly events: EventRepository,\n    private readonly mapper: EventQueryMapper,\n  ) {}\n\n  public async handle(query: BrowseEventsQuery): Promise\u003CEventPage> {\n    \u002F\u002F Response vocabulary → entity vocabulary; `page`\u002F`size` pass straight through to `getPage`.\n    const entityQuery = this.mapper.toQuery(query.input);\n    const { rows, total } = await this.events.getPage(\n      { page: query.input.page, size: query.input.size },\n      entityQuery,\n    );\n\n    return {\n      data: rows.map((event) => this.mapper.toResponse(event)),\n      metadata: { queryCount: total },\n    };\n  }\n}\n","src\u002Fcatalog\u002Fquery\u002Fbrowse-events.ts",[530,3873,3874,3903,3929,3949,3970,3974,3995,3999,4004,4015,4034,4057,4061,4065,4087,4111,4119,4123,4127,4131,4154,4162,4177,4192,4199,4203,4234,4239,4271,4301,4341,4348,4355,4359,4365,4405,4422,4426,4430],{"__ignoreMap":555},[559,3875,3876,3878,3880,3883,3885,3887,3890,3892,3894,3896,3899,3901],{"class":561,"line":562},[559,3877,566],{"class":565},[559,3879,570],{"class":569},[559,3881,3882],{"class":573}," Query",[559,3884,577],{"class":569},[559,3886,1907],{"class":565},[559,3888,3889],{"class":573}," QueryHandler",[559,3891,583],{"class":569},[559,3893,586],{"class":565},[559,3895,589],{"class":569},[559,3897,3898],{"class":592},"@heximon\u002Fcqrs",[559,3900,596],{"class":569},[559,3902,599],{"class":569},[559,3904,3905,3907,3909,3911,3913,3915,3917,3919,3921,3923,3925,3927],{"class":561,"line":602},[559,3906,566],{"class":565},[559,3908,570],{"class":569},[559,3910,1617],{"class":573},[559,3912,577],{"class":569},[559,3914,1907],{"class":565},[559,3916,1434],{"class":573},[559,3918,583],{"class":569},[559,3920,586],{"class":565},[559,3922,589],{"class":569},[559,3924,3557],{"class":592},[559,3926,596],{"class":569},[559,3928,599],{"class":569},[559,3930,3931,3933,3935,3937,3939,3941,3943,3945,3947],{"class":561,"line":610},[559,3932,566],{"class":565},[559,3934,570],{"class":569},[559,3936,3212],{"class":573},[559,3938,583],{"class":569},[559,3940,586],{"class":565},[559,3942,589],{"class":569},[559,3944,3317],{"class":592},[559,3946,596],{"class":569},[559,3948,599],{"class":569},[559,3950,3951,3953,3955,3957,3959,3961,3963,3966,3968],{"class":561,"line":619},[559,3952,566],{"class":565},[559,3954,570],{"class":569},[559,3956,3596],{"class":573},[559,3958,583],{"class":569},[559,3960,586],{"class":565},[559,3962,589],{"class":569},[559,3964,3965],{"class":592},".\u002Fevent.query-mapper",[559,3967,596],{"class":569},[559,3969,599],{"class":569},[559,3971,3972],{"class":561,"line":627},[559,3973,680],{"emptyLinePlaceholder":679},[559,3975,3976,3978,3980,3983,3985,3988,3991,3993],{"class":561,"line":635},[559,3977,699],{"class":565},[559,3979,1907],{"class":702},[559,3981,3982],{"class":706}," BrowseEventsInput",[559,3984,2017],{"class":569},[559,3986,3987],{"class":706}," InstanceType",[559,3989,3990],{"class":569},"\u003Ctypeof",[559,3992,1617],{"class":573},[559,3994,2036],{"class":569},[559,3996,3997],{"class":561,"line":643},[559,3998,680],{"emptyLinePlaceholder":679},[559,4000,4001],{"class":561,"line":651},[559,4002,4003],{"class":686},"\u002F\u002F A page of read DTOs plus its total-count metadata — the query's result type, carried by `Query\u003CEventPage>`.\n",[559,4005,4006,4008,4010,4013],{"class":561,"line":659},[559,4007,699],{"class":565},[559,4009,2077],{"class":702},[559,4011,4012],{"class":706}," EventPage",[559,4014,607],{"class":569},[559,4016,4017,4020,4023,4025,4027,4029,4032],{"class":561,"line":676},[559,4018,4019],{"class":702},"  readonly",[559,4021,4022],{"class":725}," data",[559,4024,729],{"class":569},[559,4026,3626],{"class":702},[559,4028,1434],{"class":706},[559,4030,4031],{"class":573},"[]",[559,4033,599],{"class":569},[559,4035,4036,4038,4041,4043,4045,4047,4050,4052,4054],{"class":561,"line":683},[559,4037,4019],{"class":702},[559,4039,4040],{"class":725}," metadata",[559,4042,729],{"class":569},[559,4044,570],{"class":569},[559,4046,3626],{"class":702},[559,4048,4049],{"class":725}," queryCount",[559,4051,729],{"class":569},[559,4053,2102],{"class":706},[559,4055,4056],{"class":569}," };\n",[559,4058,4059],{"class":561,"line":690},[559,4060,2129],{"class":569},[559,4062,4063],{"class":561,"line":696},[559,4064,680],{"emptyLinePlaceholder":679},[559,4066,4067,4069,4071,4074,4076,4078,4080,4083,4085],{"class":561,"line":722},[559,4068,699],{"class":565},[559,4070,703],{"class":702},[559,4072,4073],{"class":706}," BrowseEventsQuery",[559,4075,710],{"class":702},[559,4077,3882],{"class":706},[559,4079,2022],{"class":569},[559,4081,4082],{"class":706},"EventPage",[559,4084,2057],{"class":569},[559,4086,607],{"class":569},[559,4088,4089,4091,4093,4095,4098,4100,4103,4105,4107,4109],{"class":561,"line":741},[559,4090,2249],{"class":702},[559,4092,3387],{"class":702},[559,4094,716],{"class":569},[559,4096,4097],{"class":702},"public",[559,4099,3626],{"class":702},[559,4101,4102],{"class":2260}," input",[559,4104,729],{"class":569},[559,4106,3982],{"class":706},[559,4108,775],{"class":569},[559,4110,607],{"class":569},[559,4112,4113,4115,4117],{"class":561,"line":751},[559,4114,3405],{"class":573},[559,4116,1296],{"class":725},[559,4118,599],{"class":569},[559,4120,4121],{"class":561,"line":811},[559,4122,2406],{"class":569},[559,4124,4125],{"class":561,"line":866},[559,4126,2129],{"class":569},[559,4128,4129],{"class":561,"line":920},[559,4130,680],{"emptyLinePlaceholder":679},[559,4132,4133,4135,4137,4140,4143,4145,4147,4150,4152],{"class":561,"line":926},[559,4134,699],{"class":565},[559,4136,703],{"class":702},[559,4138,4139],{"class":706}," BrowseEventsQueryHandler",[559,4141,4142],{"class":702}," implements",[559,4144,3889],{"class":706},[559,4146,2022],{"class":569},[559,4148,4149],{"class":706},"BrowseEventsQuery",[559,4151,2057],{"class":569},[559,4153,607],{"class":569},[559,4155,4156,4158,4160],{"class":561,"line":1551},[559,4157,2249],{"class":702},[559,4159,3387],{"class":702},[559,4161,1629],{"class":569},[559,4163,4164,4167,4169,4171,4173,4175],{"class":561,"line":1556},[559,4165,4166],{"class":702},"    private",[559,4168,3626],{"class":702},[559,4170,3082],{"class":2260},[559,4172,729],{"class":569},[559,4174,3212],{"class":706},[559,4176,616],{"class":569},[559,4178,4179,4181,4183,4186,4188,4190],{"class":561,"line":1562},[559,4180,4166],{"class":702},[559,4182,3626],{"class":702},[559,4184,4185],{"class":2260}," mapper",[559,4187,729],{"class":569},[559,4189,3596],{"class":706},[559,4191,616],{"class":569},[559,4193,4194,4197],{"class":561,"line":1568},[559,4195,4196],{"class":569},"  )",[559,4198,3225],{"class":569},[559,4200,4201],{"class":561,"line":1593},[559,4202,680],{"emptyLinePlaceholder":679},[559,4204,4205,4207,4210,4213,4215,4217,4219,4221,4223,4226,4228,4230,4232],{"class":561,"line":1598},[559,4206,2249],{"class":702},[559,4208,4209],{"class":702}," async",[559,4211,4212],{"class":725}," handle",[559,4214,716],{"class":569},[559,4216,780],{"class":2260},[559,4218,729],{"class":569},[559,4220,4073],{"class":706},[559,4222,2277],{"class":569},[559,4224,4225],{"class":706}," Promise",[559,4227,2022],{"class":569},[559,4229,4082],{"class":706},[559,4231,2057],{"class":569},[559,4233,607],{"class":569},[559,4235,4236],{"class":561,"line":1604},[559,4237,4238],{"class":686},"    \u002F\u002F Response vocabulary → entity vocabulary; `page`\u002F`size` pass straight through to `getPage`.\n",[559,4240,4241,4244,4247,4249,4251,4254,4256,4258,4260,4262,4264,4267,4269],{"class":561,"line":1610},[559,4242,4243],{"class":702},"    const",[559,4245,4246],{"class":573}," entityQuery",[559,4248,2017],{"class":569},[559,4250,2433],{"class":569},[559,4252,4253],{"class":573},"mapper",[559,4255,534],{"class":569},[559,4257,3492],{"class":713},[559,4259,716],{"class":725},[559,4261,780],{"class":573},[559,4263,534],{"class":569},[559,4265,4266],{"class":573},"input",[559,4268,775],{"class":725},[559,4270,599],{"class":569},[559,4272,4273,4275,4277,4280,4282,4285,4287,4289,4291,4293,4295,4297,4299],{"class":561,"line":1632},[559,4274,4243],{"class":702},[559,4276,570],{"class":569},[559,4278,4279],{"class":573}," rows",[559,4281,577],{"class":569},[559,4283,4284],{"class":573}," total",[559,4286,583],{"class":569},[559,4288,2017],{"class":569},[559,4290,1058],{"class":565},[559,4292,2433],{"class":569},[559,4294,2725],{"class":573},[559,4296,534],{"class":569},[559,4298,3146],{"class":713},[559,4300,1629],{"class":725},[559,4302,4303,4306,4308,4310,4313,4315,4317,4319,4322,4324,4326,4328,4330,4332,4334,4336,4339],{"class":561,"line":1671},[559,4304,4305],{"class":569},"      {",[559,4307,1135],{"class":725},[559,4309,729],{"class":569},[559,4311,4312],{"class":573}," query",[559,4314,534],{"class":569},[559,4316,4266],{"class":573},[559,4318,534],{"class":569},[559,4320,4321],{"class":573},"page",[559,4323,577],{"class":569},[559,4325,1145],{"class":725},[559,4327,729],{"class":569},[559,4329,4312],{"class":573},[559,4331,534],{"class":569},[559,4333,4266],{"class":573},[559,4335,534],{"class":569},[559,4337,4338],{"class":573},"size",[559,4340,1153],{"class":569},[559,4342,4343,4346],{"class":561,"line":1686},[559,4344,4345],{"class":573},"      entityQuery",[559,4347,616],{"class":569},[559,4349,4350,4353],{"class":561,"line":1693},[559,4351,4352],{"class":725},"    )",[559,4354,599],{"class":569},[559,4356,4357],{"class":561,"line":1698},[559,4358,680],{"emptyLinePlaceholder":679},[559,4360,4361,4363],{"class":561,"line":1704},[559,4362,2286],{"class":565},[559,4364,607],{"class":569},[559,4366,4367,4370,4372,4374,4376,4379,4381,4383,4385,4387,4389,4391,4393,4395,4397,4399,4401,4403],{"class":561,"line":1720},[559,4368,4369],{"class":725},"      data",[559,4371,729],{"class":569},[559,4373,4279],{"class":573},[559,4375,534],{"class":569},[559,4377,4378],{"class":713},"map",[559,4380,716],{"class":725},[559,4382,716],{"class":569},[559,4384,3728],{"class":2260},[559,4386,775],{"class":569},[559,4388,3119],{"class":702},[559,4390,2433],{"class":569},[559,4392,4253],{"class":573},[559,4394,534],{"class":569},[559,4396,3485],{"class":713},[559,4398,716],{"class":725},[559,4400,3728],{"class":573},[559,4402,1035],{"class":725},[559,4404,616],{"class":569},[559,4406,4407,4410,4412,4414,4416,4418,4420],{"class":561,"line":1740},[559,4408,4409],{"class":725},"      metadata",[559,4411,729],{"class":569},[559,4413,570],{"class":569},[559,4415,4049],{"class":725},[559,4417,729],{"class":569},[559,4419,4284],{"class":573},[559,4421,1153],{"class":569},[559,4423,4424],{"class":561,"line":1747},[559,4425,3853],{"class":569},[559,4427,4428],{"class":561,"line":1752},[559,4429,2406],{"class":569},[559,4431,4432],{"class":561,"line":1758},[559,4433,2129],{"class":569},[499,4435,4436,4437,2542,4440,4443,4444,4447,4448,4450,4451,2507,4453,4455,4456,534],{},"Reading one event by id is the same shape minus the pagination — a ",[530,4438,4439],{},"GetEventQuery",[530,4441,4442],{},"GetEventQueryHandler","\npair (imported by the controller below) that calls ",[530,4445,4446],{},"events.getById(id)"," and reuses the mapper's\n",[530,4449,3485],{},", so ",[530,4452,1071],{},[530,4454,763],{}," return the same ",[530,4457,3605],{},[536,4459,4461],{"id":4460},"handle-the-write","Handle the write",[499,4463,4464,4465,4468],{},"A command states intent and returns ",[508,4466,4467],{},"void"," — the client mints the id up front (so the write is idempotent\non it) and reads the result back with a query. The handler builds the aggregate through its factory and\nsaves it:",[549,4470,4473],{"className":551,"code":4471,"filename":4472,"language":554,"meta":555,"style":555},"import { Command, type CommandHandler } from \"@heximon\u002Fcqrs\";\nimport { Event, type EventId, type PublishEventInput } from \"..\u002Fdomain\u002Fevent.entity\";\nimport { EventRepository } from \"..\u002Fports\u002Fevent.repository\";\n\n\u002F\u002F A command is `(id, data)`: the caller-minted id plus the create input — the same shape the entity factory\n\u002F\u002F consumes, so the handler passes it straight through.\nexport class PublishEventCommand extends Command {\n  public constructor(\n    public readonly id: EventId,\n    public readonly data: PublishEventInput,\n  ) {\n    super();\n  }\n}\n\n\u002F\u002F `{ database: false }` documents the single-write, non-transactional intent — one INSERT is already atomic,\n\u002F\u002F so the handler injects a repository but no `Database`, and the compiler's likely-non-transactional warning\n\u002F\u002F is suppressed. A command that writes AND publishes would instead own a `Database.runInTransaction`.\nexport class PublishEventCommandHandler implements CommandHandler\u003CPublishEventCommand, { database: false }> {\n  public constructor(private readonly events: EventRepository) {}\n\n  public async handle(command: PublishEventCommand): Promise\u003Cvoid> {\n    const event = Event.create(command.id, command.data);\n\n    await this.events.save(event);\n  }\n}\n","src\u002Fcatalog\u002Fcommand\u002Fpublish-event.ts",[530,4474,4475,4503,4535,4555,4559,4564,4569,4584,4592,4607,4621,4627,4635,4639,4643,4647,4652,4657,4662,4697,4720,4724,4753,4789,4793,4814,4818],{"__ignoreMap":555},[559,4476,4477,4479,4481,4484,4486,4488,4491,4493,4495,4497,4499,4501],{"class":561,"line":562},[559,4478,566],{"class":565},[559,4480,570],{"class":569},[559,4482,4483],{"class":573}," Command",[559,4485,577],{"class":569},[559,4487,1907],{"class":565},[559,4489,4490],{"class":573}," CommandHandler",[559,4492,583],{"class":569},[559,4494,586],{"class":565},[559,4496,589],{"class":569},[559,4498,3898],{"class":592},[559,4500,596],{"class":569},[559,4502,599],{"class":569},[559,4504,4505,4507,4509,4511,4513,4515,4517,4519,4521,4523,4525,4527,4529,4531,4533],{"class":561,"line":602},[559,4506,566],{"class":565},[559,4508,570],{"class":569},[559,4510,2222],{"class":573},[559,4512,577],{"class":569},[559,4514,1907],{"class":565},[559,4516,2014],{"class":573},[559,4518,577],{"class":569},[559,4520,1907],{"class":565},[559,4522,2080],{"class":573},[559,4524,583],{"class":569},[559,4526,586],{"class":565},[559,4528,589],{"class":569},[559,4530,2655],{"class":592},[559,4532,596],{"class":569},[559,4534,599],{"class":569},[559,4536,4537,4539,4541,4543,4545,4547,4549,4551,4553],{"class":561,"line":610},[559,4538,566],{"class":565},[559,4540,570],{"class":569},[559,4542,3212],{"class":573},[559,4544,583],{"class":569},[559,4546,586],{"class":565},[559,4548,589],{"class":569},[559,4550,3317],{"class":592},[559,4552,596],{"class":569},[559,4554,599],{"class":569},[559,4556,4557],{"class":561,"line":619},[559,4558,680],{"emptyLinePlaceholder":679},[559,4560,4561],{"class":561,"line":627},[559,4562,4563],{"class":686},"\u002F\u002F A command is `(id, data)`: the caller-minted id plus the create input — the same shape the entity factory\n",[559,4565,4566],{"class":561,"line":635},[559,4567,4568],{"class":686},"\u002F\u002F consumes, so the handler passes it straight through.\n",[559,4570,4571,4573,4575,4578,4580,4582],{"class":561,"line":643},[559,4572,699],{"class":565},[559,4574,703],{"class":702},[559,4576,4577],{"class":706}," PublishEventCommand",[559,4579,710],{"class":702},[559,4581,4483],{"class":706},[559,4583,607],{"class":569},[559,4585,4586,4588,4590],{"class":561,"line":651},[559,4587,2249],{"class":702},[559,4589,3387],{"class":702},[559,4591,1629],{"class":569},[559,4593,4594,4597,4599,4601,4603,4605],{"class":561,"line":659},[559,4595,4596],{"class":702},"    public",[559,4598,3626],{"class":702},[559,4600,1776],{"class":2260},[559,4602,729],{"class":569},[559,4604,2014],{"class":706},[559,4606,616],{"class":569},[559,4608,4609,4611,4613,4615,4617,4619],{"class":561,"line":676},[559,4610,4596],{"class":702},[559,4612,3626],{"class":702},[559,4614,4022],{"class":2260},[559,4616,729],{"class":569},[559,4618,2080],{"class":706},[559,4620,616],{"class":569},[559,4622,4623,4625],{"class":561,"line":683},[559,4624,4196],{"class":569},[559,4626,607],{"class":569},[559,4628,4629,4631,4633],{"class":561,"line":690},[559,4630,3405],{"class":573},[559,4632,1296],{"class":725},[559,4634,599],{"class":569},[559,4636,4637],{"class":561,"line":696},[559,4638,2406],{"class":569},[559,4640,4641],{"class":561,"line":722},[559,4642,2129],{"class":569},[559,4644,4645],{"class":561,"line":741},[559,4646,680],{"emptyLinePlaceholder":679},[559,4648,4649],{"class":561,"line":751},[559,4650,4651],{"class":686},"\u002F\u002F `{ database: false }` documents the single-write, non-transactional intent — one INSERT is already atomic,\n",[559,4653,4654],{"class":561,"line":811},[559,4655,4656],{"class":686},"\u002F\u002F so the handler injects a repository but no `Database`, and the compiler's likely-non-transactional warning\n",[559,4658,4659],{"class":561,"line":866},[559,4660,4661],{"class":686},"\u002F\u002F is suppressed. A command that writes AND publishes would instead own a `Database.runInTransaction`.\n",[559,4663,4664,4666,4668,4671,4673,4675,4677,4680,4682,4684,4687,4689,4692,4695],{"class":561,"line":920},[559,4665,699],{"class":565},[559,4667,703],{"class":702},[559,4669,4670],{"class":706}," PublishEventCommandHandler",[559,4672,4142],{"class":702},[559,4674,4490],{"class":706},[559,4676,2022],{"class":569},[559,4678,4679],{"class":706},"PublishEventCommand",[559,4681,577],{"class":569},[559,4683,570],{"class":569},[559,4685,4686],{"class":725}," database",[559,4688,729],{"class":569},[559,4690,4691],{"class":706}," false",[559,4693,4694],{"class":569}," }>",[559,4696,607],{"class":569},[559,4698,4699,4701,4703,4705,4708,4710,4712,4714,4716,4718],{"class":561,"line":926},[559,4700,2249],{"class":702},[559,4702,3387],{"class":702},[559,4704,716],{"class":569},[559,4706,4707],{"class":702},"private",[559,4709,3626],{"class":702},[559,4711,3082],{"class":2260},[559,4713,729],{"class":569},[559,4715,3212],{"class":706},[559,4717,775],{"class":569},[559,4719,3225],{"class":569},[559,4721,4722],{"class":561,"line":1551},[559,4723,680],{"emptyLinePlaceholder":679},[559,4725,4726,4728,4730,4732,4734,4737,4739,4741,4743,4745,4747,4749,4751],{"class":561,"line":1556},[559,4727,2249],{"class":702},[559,4729,4209],{"class":702},[559,4731,4212],{"class":725},[559,4733,716],{"class":569},[559,4735,4736],{"class":2260},"command",[559,4738,729],{"class":569},[559,4740,4577],{"class":706},[559,4742,2277],{"class":569},[559,4744,4225],{"class":706},[559,4746,2022],{"class":569},[559,4748,4467],{"class":706},[559,4750,2057],{"class":569},[559,4752,607],{"class":569},[559,4754,4755,4757,4759,4761,4763,4765,4767,4769,4771,4773,4775,4777,4780,4782,4785,4787],{"class":561,"line":1562},[559,4756,4243],{"class":702},[559,4758,3754],{"class":573},[559,4760,2017],{"class":569},[559,4762,2222],{"class":573},[559,4764,534],{"class":569},[559,4766,1626],{"class":713},[559,4768,716],{"class":725},[559,4770,4736],{"class":573},[559,4772,534],{"class":569},[559,4774,2261],{"class":573},[559,4776,577],{"class":569},[559,4778,4779],{"class":573}," command",[559,4781,534],{"class":569},[559,4783,4784],{"class":573},"data",[559,4786,775],{"class":725},[559,4788,599],{"class":569},[559,4790,4791],{"class":561,"line":1568},[559,4792,680],{"emptyLinePlaceholder":679},[559,4794,4795,4798,4800,4802,4804,4806,4808,4810,4812],{"class":561,"line":1593},[559,4796,4797],{"class":565},"    await",[559,4799,2433],{"class":569},[559,4801,2725],{"class":573},[559,4803,534],{"class":569},[559,4805,3139],{"class":713},[559,4807,716],{"class":725},[559,4809,3728],{"class":573},[559,4811,775],{"class":725},[559,4813,599],{"class":569},[559,4815,4816],{"class":561,"line":1598},[559,4817,2406],{"class":569},[559,4819,4820],{"class":561,"line":1604},[559,4821,2129],{"class":569},[536,4823,4825],{"id":4824},"bind-the-controller","Bind the controller",[499,4827,4828,4829,4832,4833,4836,4837,4839],{},"In contract mode the controller declares ",[530,4830,4831],{},"implements Controller\u003CCatalogApi>"," — each handler name matches a\nroute key and ",[530,4834,4835],{},"Action\u003CCatalogApi, key>"," types the action off that route (a missing or misnamed handler is a\nTypeScript error). It holds no domain logic: every handler translates HTTP into a CQRS message through the\ninjected buses, and the read handlers pass the already-projected ",[530,4838,3605],{}," straight out:",[549,4841,4844],{"className":551,"code":4842,"filename":4843,"language":554,"meta":555,"style":555},"import { NotFoundError } from \"@heximon\u002Fruntime\u002Ferrors\";\nimport { CommandBus, QueryBus } from \"@heximon\u002Fcqrs\";\nimport type { Action, Controller } from \"@heximon\u002Fhttp\";\nimport { PublishEventCommand } from \"..\u002Fcommand\u002Fpublish-event\";\nimport { CatalogApi } from \"..\u002Fcontract\u002Fcatalog.api\";\nimport { EventId } from \"..\u002Fdomain\u002Fevent.entity\";\nimport { BrowseEventsQuery } from \"..\u002Fquery\u002Fbrowse-events\";\nimport { GetEventQuery } from \"..\u002Fquery\u002Fget-event\";\n\nexport class CatalogController implements Controller\u003CCatalogApi> {\n  public constructor(\n    private readonly commandBus: CommandBus,\n    private readonly queryBus: QueryBus,\n  ) {}\n\n  public async browse(action: Action\u003CCatalogApi, \"browse\">) {\n    const query = await action.request.getValidatedQuery();\n\n    return this.queryBus.execute(new BrowseEventsQuery(query));\n  }\n\n  public async publish(action: Action\u003CCatalogApi, \"publish\">) {\n    const body = await action.request.readValidatedBody();\n    const id = EventId.generate();\n\n    await this.commandBus.execute(new PublishEventCommand(id, body));\n\n    return action.respond(201, { id });\n  }\n\n  public async get(action: Action\u003CCatalogApi, \"get\">) {\n    const { id } = await action.request.getValidatedPathParams();\n    const event = await this.queryBus.execute(new GetEventQuery(EventId.from(id)));\n\n    if (event === undefined) {\n      throw new NotFoundError(`Event ${id} not found`);\n    }\n\n    return event;\n  }\n}\n","src\u002Fcatalog\u002Fhttp\u002Fcatalog.controller.ts",[530,4845,4846,4868,4894,4923,4944,4965,4985,5006,5028,5032,5054,5062,5077,5092,5098,5102,5137,5164,5168,5197,5201,5205,5239,5265,5284,5288,5319,5323,5351,5355,5359,5391,5420,5462,5466,5485,5518,5523,5527,5535,5539],{"__ignoreMap":555},[559,4847,4848,4850,4852,4855,4857,4859,4861,4864,4866],{"class":561,"line":562},[559,4849,566],{"class":565},[559,4851,570],{"class":569},[559,4853,4854],{"class":573}," NotFoundError",[559,4856,583],{"class":569},[559,4858,586],{"class":565},[559,4860,589],{"class":569},[559,4862,4863],{"class":592},"@heximon\u002Fruntime\u002Ferrors",[559,4865,596],{"class":569},[559,4867,599],{"class":569},[559,4869,4870,4872,4874,4877,4879,4882,4884,4886,4888,4890,4892],{"class":561,"line":602},[559,4871,566],{"class":565},[559,4873,570],{"class":569},[559,4875,4876],{"class":573}," CommandBus",[559,4878,577],{"class":569},[559,4880,4881],{"class":573}," QueryBus",[559,4883,583],{"class":569},[559,4885,586],{"class":565},[559,4887,589],{"class":569},[559,4889,3898],{"class":592},[559,4891,596],{"class":569},[559,4893,599],{"class":569},[559,4895,4896,4898,4900,4902,4905,4907,4910,4912,4914,4916,4919,4921],{"class":561,"line":610},[559,4897,566],{"class":565},[559,4899,1907],{"class":565},[559,4901,570],{"class":569},[559,4903,4904],{"class":573}," Action",[559,4906,577],{"class":569},[559,4908,4909],{"class":573}," Controller",[559,4911,583],{"class":569},[559,4913,586],{"class":565},[559,4915,589],{"class":569},[559,4917,4918],{"class":592},"@heximon\u002Fhttp",[559,4920,596],{"class":569},[559,4922,599],{"class":569},[559,4924,4925,4927,4929,4931,4933,4935,4937,4940,4942],{"class":561,"line":619},[559,4926,566],{"class":565},[559,4928,570],{"class":569},[559,4930,4577],{"class":573},[559,4932,583],{"class":569},[559,4934,586],{"class":565},[559,4936,589],{"class":569},[559,4938,4939],{"class":592},"..\u002Fcommand\u002Fpublish-event",[559,4941,596],{"class":569},[559,4943,599],{"class":569},[559,4945,4946,4948,4950,4952,4954,4956,4958,4961,4963],{"class":561,"line":627},[559,4947,566],{"class":565},[559,4949,570],{"class":569},[559,4951,707],{"class":573},[559,4953,583],{"class":569},[559,4955,586],{"class":565},[559,4957,589],{"class":569},[559,4959,4960],{"class":592},"..\u002Fcontract\u002Fcatalog.api",[559,4962,596],{"class":569},[559,4964,599],{"class":569},[559,4966,4967,4969,4971,4973,4975,4977,4979,4981,4983],{"class":561,"line":635},[559,4968,566],{"class":565},[559,4970,570],{"class":569},[559,4972,2014],{"class":573},[559,4974,583],{"class":569},[559,4976,586],{"class":565},[559,4978,589],{"class":569},[559,4980,2655],{"class":592},[559,4982,596],{"class":569},[559,4984,599],{"class":569},[559,4986,4987,4989,4991,4993,4995,4997,4999,5002,5004],{"class":561,"line":643},[559,4988,566],{"class":565},[559,4990,570],{"class":569},[559,4992,4073],{"class":573},[559,4994,583],{"class":569},[559,4996,586],{"class":565},[559,4998,589],{"class":569},[559,5000,5001],{"class":592},"..\u002Fquery\u002Fbrowse-events",[559,5003,596],{"class":569},[559,5005,599],{"class":569},[559,5007,5008,5010,5012,5015,5017,5019,5021,5024,5026],{"class":561,"line":651},[559,5009,566],{"class":565},[559,5011,570],{"class":569},[559,5013,5014],{"class":573}," GetEventQuery",[559,5016,583],{"class":569},[559,5018,586],{"class":565},[559,5020,589],{"class":569},[559,5022,5023],{"class":592},"..\u002Fquery\u002Fget-event",[559,5025,596],{"class":569},[559,5027,599],{"class":569},[559,5029,5030],{"class":561,"line":659},[559,5031,680],{"emptyLinePlaceholder":679},[559,5033,5034,5036,5038,5041,5043,5045,5047,5050,5052],{"class":561,"line":676},[559,5035,699],{"class":565},[559,5037,703],{"class":702},[559,5039,5040],{"class":706}," CatalogController",[559,5042,4142],{"class":702},[559,5044,4909],{"class":706},[559,5046,2022],{"class":569},[559,5048,5049],{"class":706},"CatalogApi",[559,5051,2057],{"class":569},[559,5053,607],{"class":569},[559,5055,5056,5058,5060],{"class":561,"line":683},[559,5057,2249],{"class":702},[559,5059,3387],{"class":702},[559,5061,1629],{"class":569},[559,5063,5064,5066,5068,5071,5073,5075],{"class":561,"line":690},[559,5065,4166],{"class":702},[559,5067,3626],{"class":702},[559,5069,5070],{"class":2260}," commandBus",[559,5072,729],{"class":569},[559,5074,4876],{"class":706},[559,5076,616],{"class":569},[559,5078,5079,5081,5083,5086,5088,5090],{"class":561,"line":696},[559,5080,4166],{"class":702},[559,5082,3626],{"class":702},[559,5084,5085],{"class":2260}," queryBus",[559,5087,729],{"class":569},[559,5089,4881],{"class":706},[559,5091,616],{"class":569},[559,5093,5094,5096],{"class":561,"line":722},[559,5095,4196],{"class":569},[559,5097,3225],{"class":569},[559,5099,5100],{"class":561,"line":741},[559,5101,680],{"emptyLinePlaceholder":679},[559,5103,5104,5106,5108,5111,5113,5116,5118,5120,5122,5124,5126,5128,5130,5132,5135],{"class":561,"line":751},[559,5105,2249],{"class":702},[559,5107,4209],{"class":702},[559,5109,5110],{"class":725}," browse",[559,5112,716],{"class":569},[559,5114,5115],{"class":2260},"action",[559,5117,729],{"class":569},[559,5119,4904],{"class":706},[559,5121,2022],{"class":569},[559,5123,5049],{"class":706},[559,5125,577],{"class":569},[559,5127,589],{"class":569},[559,5129,1071],{"class":592},[559,5131,596],{"class":569},[559,5133,5134],{"class":569},">)",[559,5136,607],{"class":569},[559,5138,5139,5141,5143,5145,5147,5150,5152,5155,5157,5160,5162],{"class":561,"line":811},[559,5140,4243],{"class":702},[559,5142,4312],{"class":573},[559,5144,2017],{"class":569},[559,5146,1058],{"class":565},[559,5148,5149],{"class":573}," action",[559,5151,534],{"class":569},[559,5153,5154],{"class":573},"request",[559,5156,534],{"class":569},[559,5158,5159],{"class":713},"getValidatedQuery",[559,5161,1296],{"class":725},[559,5163,599],{"class":569},[559,5165,5166],{"class":561,"line":866},[559,5167,680],{"emptyLinePlaceholder":679},[559,5169,5170,5172,5174,5177,5179,5182,5184,5187,5189,5191,5193,5195],{"class":561,"line":920},[559,5171,2286],{"class":565},[559,5173,2433],{"class":569},[559,5175,5176],{"class":573},"queryBus",[559,5178,534],{"class":569},[559,5180,5181],{"class":713},"execute",[559,5183,716],{"class":725},[559,5185,5186],{"class":569},"new",[559,5188,4073],{"class":713},[559,5190,716],{"class":725},[559,5192,780],{"class":573},[559,5194,1035],{"class":725},[559,5196,599],{"class":569},[559,5198,5199],{"class":561,"line":926},[559,5200,2406],{"class":569},[559,5202,5203],{"class":561,"line":1551},[559,5204,680],{"emptyLinePlaceholder":679},[559,5206,5207,5209,5211,5214,5216,5218,5220,5222,5224,5226,5228,5230,5233,5235,5237],{"class":561,"line":1556},[559,5208,2249],{"class":702},[559,5210,4209],{"class":702},[559,5212,5213],{"class":725}," publish",[559,5215,716],{"class":569},[559,5217,5115],{"class":2260},[559,5219,729],{"class":569},[559,5221,4904],{"class":706},[559,5223,2022],{"class":569},[559,5225,5049],{"class":706},[559,5227,577],{"class":569},[559,5229,589],{"class":569},[559,5231,5232],{"class":592},"publish",[559,5234,596],{"class":569},[559,5236,5134],{"class":569},[559,5238,607],{"class":569},[559,5240,5241,5243,5246,5248,5250,5252,5254,5256,5258,5261,5263],{"class":561,"line":1562},[559,5242,4243],{"class":702},[559,5244,5245],{"class":573}," body",[559,5247,2017],{"class":569},[559,5249,1058],{"class":565},[559,5251,5149],{"class":573},[559,5253,534],{"class":569},[559,5255,5154],{"class":573},[559,5257,534],{"class":569},[559,5259,5260],{"class":713},"readValidatedBody",[559,5262,1296],{"class":725},[559,5264,599],{"class":569},[559,5266,5267,5269,5271,5273,5275,5277,5280,5282],{"class":561,"line":1568},[559,5268,4243],{"class":702},[559,5270,1776],{"class":573},[559,5272,2017],{"class":569},[559,5274,2014],{"class":573},[559,5276,534],{"class":569},[559,5278,5279],{"class":713},"generate",[559,5281,1296],{"class":725},[559,5283,599],{"class":569},[559,5285,5286],{"class":561,"line":1593},[559,5287,680],{"emptyLinePlaceholder":679},[559,5289,5290,5292,5294,5297,5299,5301,5303,5305,5307,5309,5311,5313,5315,5317],{"class":561,"line":1598},[559,5291,4797],{"class":565},[559,5293,2433],{"class":569},[559,5295,5296],{"class":573},"commandBus",[559,5298,534],{"class":569},[559,5300,5181],{"class":713},[559,5302,716],{"class":725},[559,5304,5186],{"class":569},[559,5306,4577],{"class":713},[559,5308,716],{"class":725},[559,5310,2261],{"class":573},[559,5312,577],{"class":569},[559,5314,5245],{"class":573},[559,5316,1035],{"class":725},[559,5318,599],{"class":569},[559,5320,5321],{"class":561,"line":1604},[559,5322,680],{"emptyLinePlaceholder":679},[559,5324,5325,5327,5329,5331,5334,5336,5339,5341,5343,5345,5347,5349],{"class":561,"line":1610},[559,5326,2286],{"class":565},[559,5328,5149],{"class":573},[559,5330,534],{"class":569},[559,5332,5333],{"class":713},"respond",[559,5335,716],{"class":725},[559,5337,5338],{"class":796},"201",[559,5340,577],{"class":569},[559,5342,570],{"class":569},[559,5344,1776],{"class":573},[559,5346,583],{"class":569},[559,5348,775],{"class":725},[559,5350,599],{"class":569},[559,5352,5353],{"class":561,"line":1632},[559,5354,2406],{"class":569},[559,5356,5357],{"class":561,"line":1671},[559,5358,680],{"emptyLinePlaceholder":679},[559,5360,5361,5363,5365,5367,5369,5371,5373,5375,5377,5379,5381,5383,5385,5387,5389],{"class":561,"line":1686},[559,5362,2249],{"class":702},[559,5364,4209],{"class":702},[559,5366,2417],{"class":725},[559,5368,716],{"class":569},[559,5370,5115],{"class":2260},[559,5372,729],{"class":569},[559,5374,4904],{"class":706},[559,5376,2022],{"class":569},[559,5378,5049],{"class":706},[559,5380,577],{"class":569},[559,5382,589],{"class":569},[559,5384,763],{"class":592},[559,5386,596],{"class":569},[559,5388,5134],{"class":569},[559,5390,607],{"class":569},[559,5392,5393,5395,5397,5399,5401,5403,5405,5407,5409,5411,5413,5416,5418],{"class":561,"line":1693},[559,5394,4243],{"class":702},[559,5396,570],{"class":569},[559,5398,1776],{"class":573},[559,5400,583],{"class":569},[559,5402,2017],{"class":569},[559,5404,1058],{"class":565},[559,5406,5149],{"class":573},[559,5408,534],{"class":569},[559,5410,5154],{"class":573},[559,5412,534],{"class":569},[559,5414,5415],{"class":713},"getValidatedPathParams",[559,5417,1296],{"class":725},[559,5419,599],{"class":569},[559,5421,5422,5424,5426,5428,5430,5432,5434,5436,5438,5440,5442,5444,5446,5448,5450,5453,5455,5457,5460],{"class":561,"line":1698},[559,5423,4243],{"class":702},[559,5425,3754],{"class":573},[559,5427,2017],{"class":569},[559,5429,1058],{"class":565},[559,5431,2433],{"class":569},[559,5433,5176],{"class":573},[559,5435,534],{"class":569},[559,5437,5181],{"class":713},[559,5439,716],{"class":725},[559,5441,5186],{"class":569},[559,5443,5014],{"class":713},[559,5445,716],{"class":725},[559,5447,2031],{"class":573},[559,5449,534],{"class":569},[559,5451,5452],{"class":713},"from",[559,5454,716],{"class":725},[559,5456,2261],{"class":573},[559,5458,5459],{"class":725},")))",[559,5461,599],{"class":569},[559,5463,5464],{"class":561,"line":1704},[559,5465,680],{"emptyLinePlaceholder":679},[559,5467,5468,5471,5473,5475,5478,5481,5483],{"class":561,"line":1720},[559,5469,5470],{"class":565},"    if",[559,5472,3122],{"class":725},[559,5474,3728],{"class":573},[559,5476,5477],{"class":569}," ===",[559,5479,5480],{"class":569}," undefined",[559,5482,931],{"class":725},[559,5484,719],{"class":569},[559,5486,5487,5490,5492,5494,5496,5499,5502,5505,5507,5509,5512,5514,5516],{"class":561,"line":1740},[559,5488,5489],{"class":565},"      throw",[559,5491,1004],{"class":569},[559,5493,4854],{"class":713},[559,5495,716],{"class":725},[559,5497,5498],{"class":569},"`",[559,5500,5501],{"class":592},"Event ",[559,5503,5504],{"class":569},"${",[559,5506,2261],{"class":573},[559,5508,662],{"class":569},[559,5510,5511],{"class":592}," not found",[559,5513,5498],{"class":569},[559,5515,775],{"class":725},[559,5517,599],{"class":569},[559,5519,5520],{"class":561,"line":1747},[559,5521,5522],{"class":569},"    }\n",[559,5524,5525],{"class":561,"line":1752},[559,5526,680],{"emptyLinePlaceholder":679},[559,5528,5529,5531,5533],{"class":561,"line":1758},[559,5530,2286],{"class":565},[559,5532,3754],{"class":573},[559,5534,599],{"class":569},[559,5536,5537],{"class":561,"line":1796},[559,5538,2406],{"class":569},[559,5540,5541],{"class":561,"line":2452},[559,5542,2129],{"class":569},[499,5544,501,5545,2542,5548,5551,5552,5555],{},[530,5546,5547],{},"CommandBus",[530,5549,5550],{},"QueryBus"," are core providers the CQRS plugin contributes — you inject them, you never\ndeclare them. A thrown ",[530,5553,5554],{},"NotFoundError"," renders an RFC 9457 problem response with no try\u002Fcatch here.",[536,5557,5559],{"id":5558},"wire-the-module","Wire the module",[499,5561,5562,5563,5566,5567,5570,5571,5574,5575,729],{},"One module binds every piece. It binds the ",[530,5564,5565],{},"EventRepository"," port to its SQLite concrete (the dialect swap\nlives on this one line), provides the read-side mapper, and lists the handlers under ",[530,5568,5569],{},"cqrs:"," and the\ncontroller under ",[530,5572,5573],{},"http:"," — those namespaces are how the compiler dispatches them, so a handler or controller\nnever goes in ",[530,5576,5577],{},"providers",[549,5579,5582],{"className":551,"code":5580,"filename":5581,"language":554,"meta":555,"style":555},"import { Module } from \"@heximon\u002Fruntime\";\nimport { DatabaseModule } from \"..\u002Fdatabase\u002Fdatabase.module\";\nimport { PublishEventCommandHandler } from \".\u002Fcommand\u002Fpublish-event\";\nimport { CatalogController } from \".\u002Fhttp\u002Fcatalog.controller\";\nimport { SqliteEventRepository } from \".\u002Fpersistence\u002Fevent.repository\";\nimport { EventRepository } from \".\u002Fports\u002Fevent.repository\";\nimport { BrowseEventsQueryHandler } from \".\u002Fquery\u002Fbrowse-events\";\nimport { EventQueryMapper } from \".\u002Fquery\u002Fevent.query-mapper\";\nimport { GetEventQueryHandler } from \".\u002Fquery\u002Fget-event\";\n\nexport class CatalogModule extends Module({\n  imports: [DatabaseModule],\n  providers: [{ provide: EventRepository, useClass: SqliteEventRepository }, EventQueryMapper],\n  http: { controllers: [CatalogController] },\n  cqrs: {\n    commandHandlers: [PublishEventCommandHandler],\n    queryHandlers: [BrowseEventsQueryHandler, GetEventQueryHandler],\n  },\n}) {}\n","src\u002Fcatalog\u002Fcatalog.module.ts",[530,5583,5584,5605,5627,5648,5669,5691,5712,5733,5754,5776,5780,5797,5809,5846,5865,5874,5886,5903,5907],{"__ignoreMap":555},[559,5585,5586,5588,5590,5593,5595,5597,5599,5601,5603],{"class":561,"line":562},[559,5587,566],{"class":565},[559,5589,570],{"class":569},[559,5591,5592],{"class":573}," Module",[559,5594,583],{"class":569},[559,5596,586],{"class":565},[559,5598,589],{"class":569},[559,5600,1943],{"class":592},[559,5602,596],{"class":569},[559,5604,599],{"class":569},[559,5606,5607,5609,5611,5614,5616,5618,5620,5623,5625],{"class":561,"line":602},[559,5608,566],{"class":565},[559,5610,570],{"class":569},[559,5612,5613],{"class":573}," DatabaseModule",[559,5615,583],{"class":569},[559,5617,586],{"class":565},[559,5619,589],{"class":569},[559,5621,5622],{"class":592},"..\u002Fdatabase\u002Fdatabase.module",[559,5624,596],{"class":569},[559,5626,599],{"class":569},[559,5628,5629,5631,5633,5635,5637,5639,5641,5644,5646],{"class":561,"line":610},[559,5630,566],{"class":565},[559,5632,570],{"class":569},[559,5634,4670],{"class":573},[559,5636,583],{"class":569},[559,5638,586],{"class":565},[559,5640,589],{"class":569},[559,5642,5643],{"class":592},".\u002Fcommand\u002Fpublish-event",[559,5645,596],{"class":569},[559,5647,599],{"class":569},[559,5649,5650,5652,5654,5656,5658,5660,5662,5665,5667],{"class":561,"line":619},[559,5651,566],{"class":565},[559,5653,570],{"class":569},[559,5655,5040],{"class":573},[559,5657,583],{"class":569},[559,5659,586],{"class":565},[559,5661,589],{"class":569},[559,5663,5664],{"class":592},".\u002Fhttp\u002Fcatalog.controller",[559,5666,596],{"class":569},[559,5668,599],{"class":569},[559,5670,5671,5673,5675,5678,5680,5682,5684,5687,5689],{"class":561,"line":627},[559,5672,566],{"class":565},[559,5674,570],{"class":569},[559,5676,5677],{"class":573}," SqliteEventRepository",[559,5679,583],{"class":569},[559,5681,586],{"class":565},[559,5683,589],{"class":569},[559,5685,5686],{"class":592},".\u002Fpersistence\u002Fevent.repository",[559,5688,596],{"class":569},[559,5690,599],{"class":569},[559,5692,5693,5695,5697,5699,5701,5703,5705,5708,5710],{"class":561,"line":635},[559,5694,566],{"class":565},[559,5696,570],{"class":569},[559,5698,3212],{"class":573},[559,5700,583],{"class":569},[559,5702,586],{"class":565},[559,5704,589],{"class":569},[559,5706,5707],{"class":592},".\u002Fports\u002Fevent.repository",[559,5709,596],{"class":569},[559,5711,599],{"class":569},[559,5713,5714,5716,5718,5720,5722,5724,5726,5729,5731],{"class":561,"line":643},[559,5715,566],{"class":565},[559,5717,570],{"class":569},[559,5719,4139],{"class":573},[559,5721,583],{"class":569},[559,5723,586],{"class":565},[559,5725,589],{"class":569},[559,5727,5728],{"class":592},".\u002Fquery\u002Fbrowse-events",[559,5730,596],{"class":569},[559,5732,599],{"class":569},[559,5734,5735,5737,5739,5741,5743,5745,5747,5750,5752],{"class":561,"line":651},[559,5736,566],{"class":565},[559,5738,570],{"class":569},[559,5740,3596],{"class":573},[559,5742,583],{"class":569},[559,5744,586],{"class":565},[559,5746,589],{"class":569},[559,5748,5749],{"class":592},".\u002Fquery\u002Fevent.query-mapper",[559,5751,596],{"class":569},[559,5753,599],{"class":569},[559,5755,5756,5758,5760,5763,5765,5767,5769,5772,5774],{"class":561,"line":659},[559,5757,566],{"class":565},[559,5759,570],{"class":569},[559,5761,5762],{"class":573}," GetEventQueryHandler",[559,5764,583],{"class":569},[559,5766,586],{"class":565},[559,5768,589],{"class":569},[559,5770,5771],{"class":592},".\u002Fquery\u002Fget-event",[559,5773,596],{"class":569},[559,5775,599],{"class":569},[559,5777,5778],{"class":561,"line":676},[559,5779,680],{"emptyLinePlaceholder":679},[559,5781,5782,5784,5786,5789,5791,5793,5795],{"class":561,"line":683},[559,5783,699],{"class":565},[559,5785,703],{"class":702},[559,5787,5788],{"class":706}," CatalogModule",[559,5790,710],{"class":702},[559,5792,5592],{"class":713},[559,5794,716],{"class":573},[559,5796,719],{"class":569},[559,5798,5799,5802,5804,5807],{"class":561,"line":690},[559,5800,5801],{"class":725},"  imports",[559,5803,729],{"class":569},[559,5805,5806],{"class":573}," [DatabaseModule]",[559,5808,616],{"class":569},[559,5810,5811,5814,5816,5819,5821,5824,5826,5828,5830,5833,5835,5838,5841,5844],{"class":561,"line":696},[559,5812,5813],{"class":725},"  providers",[559,5815,729],{"class":569},[559,5817,5818],{"class":573}," [",[559,5820,793],{"class":569},[559,5822,5823],{"class":725}," provide",[559,5825,729],{"class":569},[559,5827,3212],{"class":573},[559,5829,577],{"class":569},[559,5831,5832],{"class":725}," useClass",[559,5834,729],{"class":569},[559,5836,5837],{"class":573}," SqliteEventRepository ",[559,5839,5840],{"class":569},"},",[559,5842,5843],{"class":573}," EventQueryMapper]",[559,5845,616],{"class":569},[559,5847,5848,5851,5853,5855,5858,5860,5863],{"class":561,"line":722},[559,5849,5850],{"class":725},"  http",[559,5852,729],{"class":569},[559,5854,570],{"class":569},[559,5856,5857],{"class":725}," controllers",[559,5859,729],{"class":569},[559,5861,5862],{"class":573}," [CatalogController] ",[559,5864,1668],{"class":569},[559,5866,5867,5870,5872],{"class":561,"line":741},[559,5868,5869],{"class":725},"  cqrs",[559,5871,729],{"class":569},[559,5873,607],{"class":569},[559,5875,5876,5879,5881,5884],{"class":561,"line":751},[559,5877,5878],{"class":725},"    commandHandlers",[559,5880,729],{"class":569},[559,5882,5883],{"class":573}," [PublishEventCommandHandler]",[559,5885,616],{"class":569},[559,5887,5888,5891,5893,5896,5898,5901],{"class":561,"line":811},[559,5889,5890],{"class":725},"    queryHandlers",[559,5892,729],{"class":569},[559,5894,5895],{"class":573}," [BrowseEventsQueryHandler",[559,5897,577],{"class":569},[559,5899,5900],{"class":573}," GetEventQueryHandler]",[559,5902,616],{"class":569},[559,5904,5905],{"class":561,"line":866},[559,5906,923],{"class":569},[559,5908,5909,5911,5913],{"class":561,"line":920},[559,5910,662],{"class":569},[559,5912,931],{"class":573},[559,5914,934],{"class":569},[499,5916,5917],{},"Two compiler plugins back it — the HTTP plugin for the contract controller, the CQRS plugin for the\nhandlers. The Drizzle repository needs none; it's an ordinary provider:",[549,5919,5922],{"className":551,"code":5920,"filename":5921,"language":554,"meta":555,"style":555},"import { defineHeximonConfig } from \"@heximon\u002Fbuild\";\nimport { CqrsPlugin } from \"@heximon\u002Fcqrs\u002Fcompiler\";\nimport { HttpPlugin } from \"@heximon\u002Fhttp\u002Fcompiler\";\n\nexport default defineHeximonConfig({ plugins: [new HttpPlugin(), new CqrsPlugin()] });\n","heximon.config.ts",[530,5923,5924,5946,5968,5990,5994],{"__ignoreMap":555},[559,5925,5926,5928,5930,5933,5935,5937,5939,5942,5944],{"class":561,"line":562},[559,5927,566],{"class":565},[559,5929,570],{"class":569},[559,5931,5932],{"class":573}," defineHeximonConfig",[559,5934,583],{"class":569},[559,5936,586],{"class":565},[559,5938,589],{"class":569},[559,5940,5941],{"class":592},"@heximon\u002Fbuild",[559,5943,596],{"class":569},[559,5945,599],{"class":569},[559,5947,5948,5950,5952,5955,5957,5959,5961,5964,5966],{"class":561,"line":602},[559,5949,566],{"class":565},[559,5951,570],{"class":569},[559,5953,5954],{"class":573}," CqrsPlugin",[559,5956,583],{"class":569},[559,5958,586],{"class":565},[559,5960,589],{"class":569},[559,5962,5963],{"class":592},"@heximon\u002Fcqrs\u002Fcompiler",[559,5965,596],{"class":569},[559,5967,599],{"class":569},[559,5969,5970,5972,5974,5977,5979,5981,5983,5986,5988],{"class":561,"line":610},[559,5971,566],{"class":565},[559,5973,570],{"class":569},[559,5975,5976],{"class":573}," HttpPlugin",[559,5978,583],{"class":569},[559,5980,586],{"class":565},[559,5982,589],{"class":569},[559,5984,5985],{"class":592},"@heximon\u002Fhttp\u002Fcompiler",[559,5987,596],{"class":569},[559,5989,599],{"class":569},[559,5991,5992],{"class":561,"line":619},[559,5993,680],{"emptyLinePlaceholder":679},[559,5995,5996,5998,6001,6003,6005,6007,6010,6012,6014,6016,6018,6020,6022,6024,6026,6029,6031,6033],{"class":561,"line":627},[559,5997,699],{"class":565},[559,5999,6000],{"class":565}," default",[559,6002,5932],{"class":713},[559,6004,716],{"class":573},[559,6006,793],{"class":569},[559,6008,6009],{"class":725}," plugins",[559,6011,729],{"class":569},[559,6013,5818],{"class":573},[559,6015,5186],{"class":569},[559,6017,5976],{"class":713},[559,6019,1296],{"class":573},[559,6021,577],{"class":569},[559,6023,1004],{"class":569},[559,6025,5954],{"class":713},[559,6027,6028],{"class":573},"()] ",[559,6030,662],{"class":569},[559,6032,775],{"class":573},[559,6034,599],{"class":569},[6036,6037,6039,6040,6043,6044,534],"callout",{"type":6038},"tip","To ship this whole feature as a reusable package — the port ",[530,6041,6042],{},"require","d and each app binding the dialect\nconcrete + database across the boundary — see ",[503,6045,6046],{"href":476},"Publish a feature package",[536,6048,6050],{"id":6049},"call-it-from-a-typed-client","Call it from a typed client",[499,6052,6053,6054,6056,6057,6060,6061,6068,6069,6072,6073,6075],{},"The frontend imports the ",[530,6055,5049],{}," class, constructs it with a transport, and calls it. A ",[530,6058,6059],{},".client","\ncaller returns the route's 2xx body and ",[508,6062,6063,6064,6067],{},"throws a ",[530,6065,6066],{},"ContractError"," on any non-2xx"," — so a ",[530,6070,6071],{},"404"," from ",[530,6074,763],{},"\nis an exception you narrow on, not a status you check by hand:",[549,6077,6079],{"className":551,"code":6078,"filename":941,"language":554,"meta":555,"style":555},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { ContractError } from \"@heximon\u002Fcontract\";\nimport { CatalogApi } from \"..\u002Fcatalog\u002Fcontract\u002Fcatalog.api\";\n\nconst api = new CatalogApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\n\u002F\u002F Publish, then read back by the returned id — both calls typed off the SAME contract the server binds.\nconst { id } = await api.client.publish({\n  body: { name: \"Spring Gala\", capacity: 100, priceAmount: 5000, currency: \"EUR\" },\n});\n\ntry {\n  const event = await api.client.get({ params: { id } });\n  console.log(event.name); \u002F\u002F typed as `EventResponse`\n} catch (error) {\n  if (error instanceof ContractError && error.status === 404) {\n    console.warn(\"event not found\");\n  }\n}\n",[530,6080,6081,6101,6122,6142,6146,6184,6188,6193,6222,6275,6283,6287,6294,6336,6362,6374,6409,6432,6436],{"__ignoreMap":555},[559,6082,6083,6085,6087,6089,6091,6093,6095,6097,6099],{"class":561,"line":562},[559,6084,566],{"class":565},[559,6086,570],{"class":569},[559,6088,952],{"class":573},[559,6090,583],{"class":569},[559,6092,586],{"class":565},[559,6094,589],{"class":569},[559,6096,961],{"class":592},[559,6098,596],{"class":569},[559,6100,599],{"class":569},[559,6102,6103,6105,6107,6110,6112,6114,6116,6118,6120],{"class":561,"line":602},[559,6104,566],{"class":565},[559,6106,570],{"class":569},[559,6108,6109],{"class":573}," ContractError",[559,6111,583],{"class":569},[559,6113,586],{"class":565},[559,6115,589],{"class":569},[559,6117,593],{"class":592},[559,6119,596],{"class":569},[559,6121,599],{"class":569},[559,6123,6124,6126,6128,6130,6132,6134,6136,6138,6140],{"class":561,"line":610},[559,6125,566],{"class":565},[559,6127,570],{"class":569},[559,6129,707],{"class":573},[559,6131,583],{"class":569},[559,6133,586],{"class":565},[559,6135,589],{"class":569},[559,6137,982],{"class":592},[559,6139,596],{"class":569},[559,6141,599],{"class":569},[559,6143,6144],{"class":561,"line":619},[559,6145,680],{"emptyLinePlaceholder":679},[559,6147,6148,6150,6152,6154,6156,6158,6160,6162,6164,6166,6168,6170,6172,6174,6176,6178,6180,6182],{"class":561,"line":627},[559,6149,995],{"class":702},[559,6151,998],{"class":573},[559,6153,1001],{"class":569},[559,6155,1004],{"class":569},[559,6157,707],{"class":713},[559,6159,1009],{"class":573},[559,6161,534],{"class":569},[559,6163,1014],{"class":713},[559,6165,716],{"class":573},[559,6167,793],{"class":569},[559,6169,1021],{"class":725},[559,6171,729],{"class":569},[559,6173,589],{"class":569},[559,6175,1028],{"class":592},[559,6177,596],{"class":569},[559,6179,583],{"class":569},[559,6181,1035],{"class":573},[559,6183,599],{"class":569},[559,6185,6186],{"class":561,"line":635},[559,6187,680],{"emptyLinePlaceholder":679},[559,6189,6190],{"class":561,"line":643},[559,6191,6192],{"class":686},"\u002F\u002F Publish, then read back by the returned id — both calls typed off the SAME contract the server binds.\n",[559,6194,6195,6197,6199,6202,6204,6206,6208,6210,6212,6214,6216,6218,6220],{"class":561,"line":651},[559,6196,995],{"class":702},[559,6198,570],{"class":569},[559,6200,6201],{"class":573}," id ",[559,6203,662],{"class":569},[559,6205,2017],{"class":569},[559,6207,1058],{"class":565},[559,6209,1061],{"class":573},[559,6211,534],{"class":569},[559,6213,1066],{"class":573},[559,6215,534],{"class":569},[559,6217,5232],{"class":713},[559,6219,716],{"class":573},[559,6221,719],{"class":569},[559,6223,6224,6227,6229,6231,6233,6235,6237,6240,6242,6244,6246,6248,6250,6252,6254,6256,6259,6261,6264,6266,6268,6271,6273],{"class":561,"line":659},[559,6225,6226],{"class":725},"  body",[559,6228,729],{"class":569},[559,6230,570],{"class":569},[559,6232,1094],{"class":725},[559,6234,729],{"class":569},[559,6236,589],{"class":569},[559,6238,6239],{"class":592},"Spring Gala",[559,6241,596],{"class":569},[559,6243,577],{"class":569},[559,6245,1652],{"class":725},[559,6247,729],{"class":569},[559,6249,1681],{"class":796},[559,6251,577],{"class":569},[559,6253,1116],{"class":725},[559,6255,729],{"class":569},[559,6257,6258],{"class":796}," 5000",[559,6260,577],{"class":569},[559,6262,6263],{"class":725}," currency",[559,6265,729],{"class":569},[559,6267,589],{"class":569},[559,6269,6270],{"class":592},"EUR",[559,6272,596],{"class":569},[559,6274,1153],{"class":569},[559,6276,6277,6279,6281],{"class":561,"line":676},[559,6278,662],{"class":569},[559,6280,775],{"class":573},[559,6282,599],{"class":569},[559,6284,6285],{"class":561,"line":683},[559,6286,680],{"emptyLinePlaceholder":679},[559,6288,6289,6292],{"class":561,"line":690},[559,6290,6291],{"class":565},"try",[559,6293,607],{"class":569},[559,6295,6296,6299,6301,6303,6305,6307,6309,6311,6313,6315,6317,6319,6322,6324,6326,6328,6330,6332,6334],{"class":561,"line":696},[559,6297,6298],{"class":702},"  const",[559,6300,3754],{"class":573},[559,6302,2017],{"class":569},[559,6304,1058],{"class":565},[559,6306,1061],{"class":573},[559,6308,534],{"class":569},[559,6310,1066],{"class":573},[559,6312,534],{"class":569},[559,6314,763],{"class":713},[559,6316,716],{"class":725},[559,6318,793],{"class":569},[559,6320,6321],{"class":725}," params",[559,6323,729],{"class":569},[559,6325,570],{"class":569},[559,6327,1776],{"class":573},[559,6329,583],{"class":569},[559,6331,583],{"class":569},[559,6333,775],{"class":725},[559,6335,599],{"class":569},[559,6337,6338,6341,6343,6346,6348,6350,6352,6354,6356,6359],{"class":561,"line":722},[559,6339,6340],{"class":573},"  console",[559,6342,534],{"class":569},[559,6344,6345],{"class":713},"log",[559,6347,716],{"class":725},[559,6349,3728],{"class":573},[559,6351,534],{"class":569},[559,6353,2312],{"class":573},[559,6355,775],{"class":725},[559,6357,6358],{"class":569},";",[559,6360,6361],{"class":686}," \u002F\u002F typed as `EventResponse`\n",[559,6363,6364,6366,6369,6372],{"class":561,"line":741},[559,6365,662],{"class":569},[559,6367,6368],{"class":565}," catch",[559,6370,6371],{"class":573}," (error) ",[559,6373,719],{"class":569},[559,6375,6376,6379,6381,6384,6387,6389,6392,6395,6397,6400,6402,6405,6407],{"class":561,"line":751},[559,6377,6378],{"class":565},"  if",[559,6380,3122],{"class":725},[559,6382,6383],{"class":573},"error",[559,6385,6386],{"class":569}," instanceof",[559,6388,6109],{"class":706},[559,6390,6391],{"class":569}," &&",[559,6393,6394],{"class":573}," error",[559,6396,534],{"class":569},[559,6398,6399],{"class":573},"status",[559,6401,5477],{"class":569},[559,6403,6404],{"class":796}," 404",[559,6406,931],{"class":725},[559,6408,719],{"class":569},[559,6410,6411,6414,6416,6419,6421,6423,6426,6428,6430],{"class":561,"line":811},[559,6412,6413],{"class":573},"    console",[559,6415,534],{"class":569},[559,6417,6418],{"class":713},"warn",[559,6420,716],{"class":725},[559,6422,596],{"class":569},[559,6424,6425],{"class":592},"event not found",[559,6427,596],{"class":569},[559,6429,775],{"class":725},[559,6431,599],{"class":569},[559,6433,6434],{"class":561,"line":866},[559,6435,2406],{"class":569},[559,6437,6438],{"class":561,"line":920},[559,6439,2129],{"class":569},[499,6441,6442,6445,6446,6449,6450,6453,6454,6457,6458,6461,6462,6465,6466,6469],{},[530,6443,6444],{},"ClientTransport.fetch"," is the network driver; ",[530,6447,6448],{},"ClientTransport.internal"," (in-process, for SSR) and\n",[530,6451,6452],{},"ClientTransport.mock"," (canned responses, for tests) fill the same seam with no other change. Prefer\n",[530,6455,6456],{},"api.raw(\"get\", { params: { id } })"," over the ",[530,6459,6460],{},"try\u002Fcatch"," when you want the full ",[530,6463,6464],{},"{ status, body }"," union\nwithout throwing — see ",[503,6467,6468],{"href":73},"the client"," for both forms and the vue-query bindings.",[536,6471,6473],{"id":6472},"see-also","See also",[6475,6476,6477,6486,6497,6505,6518,6523,6535],"ul",{},[6478,6479,6480,6482,6483,6485],"li",{},[503,6481,453],{"href":454}," — the simpler starting point: a thin controller over a plain\nrepository, no contract or CQRS, and where the ",[530,6484,3438],{}," connection wiring is built up step by step.",[6478,6487,6488,6490,6491,2507,6494,6496],{},[503,6489,1871],{"href":442}," — ",[530,6492,6493],{},"QuerySchema.create",[530,6495,1182],{}," on\ntheir own, including offset mode and the page-size ceiling.",[6478,6498,6499,6501,6502,6504],{},[503,6500,2513],{"href":471}," — the aggregate root, value objects, invariants, and\ndomain events behind the ",[530,6503,1885],{}," on this page.",[6478,6506,6507,6510,6511,6513,6514,6517],{},[503,6508,6509],{"href":239},"Repository pattern"," — filtering and paging an ",[530,6512,3496],{},", and the\n",[530,6515,6516],{},"QueryMapper"," that maps response-vocabulary field names to entity fields.",[6478,6519,6520,6522],{},[503,6521,233],{"href":234}," — commands, queries, the buses, and when splitting reads from writes earns\nits keep.",[6478,6524,6525,6527,6528,6531,6532,6534],{},[503,6526,67],{"href":68}," — the full ",[530,6529,6530],{},"Route"," builder; ",[503,6533,6468],{"href":73},"\n— every transport and the typed self-client end to end.",[6478,6536,6537,6543,6544,6546],{},[503,6538,6540,6541,533],{"href":525,"rel":6539},[527],"the flagship ",[530,6542,532],{},"\n— this exact chain as a runnable, dual-dialect (SQLite + MySQL) bounded-context package, with an\nend-to-end test that drives ",[530,6545,1071],{}," through the renamed-field filter and multi-page pagination.",[6548,6549,6550],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":555,"searchDepth":602,"depth":602,"links":6552},[6553,6554,6555,6556,6557,6558,6559,6560,6561],{"id":538,"depth":602,"text":539},{"id":1167,"depth":602,"text":1168},{"id":1874,"depth":602,"text":1875},{"id":3470,"depth":602,"text":3471},{"id":4460,"depth":602,"text":4461},{"id":4824,"depth":602,"text":4825},{"id":5558,"depth":602,"text":5559},{"id":6049,"depth":602,"text":6050},{"id":6472,"depth":602,"text":6473},"The full best-practice CRUD chain — a shared Contract + typed self-client, QuerySchema\u002FPaginatedResponseSchema pagination, CQRS command\u002Fquery handlers, and a Drizzle aggregate repository behind an EntityQuery mapper.","md",null,{},{"icon":492},{"title":489,"description":6562},"rtwqFGk7BGTj8oZfzffPH0xJMPm2jeXoqzciBmlHYRU",[6570,6564],{"title":485,"path":486,"stem":487,"description":6571,"icon":95,"children":-1},"A multi-step saga that compensates itself, with no central coordinator — each bounded context reacts to integration events over the transactional outbox and emits the next, with at-least-once delivery and per-handler idempotency.",1783300761903]