[{"data":1,"prerenderedAt":8413},["ShallowReactive",2],{"navigation_docs_en":3,"-en-getting-started-sample-app":342,"-en-getting-started-sample-app-surround":8408},[4,45,61,96,132,166,196,217,241,265],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Coming from Laravel","\u002Fen\u002Fgetting-started\u002Fcoming-from-laravel","en\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Coming from Symfony","\u002Fen\u002Fgetting-started\u002Fcoming-from-symfony","en\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Your first module","\u002Fen\u002Fgetting-started\u002Ffirst-module","en\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Project structure","\u002Fen\u002Fgetting-started\u002Fproject-structure","en\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"The shop sample application","\u002Fen\u002Fgetting-started\u002Fsample-app","en\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F10.reference",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F10.reference\u002F1.configuration","i-lucide-settings",{"title":57,"path":58,"stem":59,"icon":60},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F10.reference\u002F2.dependencies","i-lucide-package",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[67,72,77,82,86,91],{"title":68,"path":69,"stem":70,"icon":71},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture","i-lucide-layers",{"title":73,"path":74,"stem":75,"icon":76},"Application lifecycle","\u002Fen\u002Fconcepts\u002Fapplication-lifecycle","en\u002F2.concepts\u002F2.application-lifecycle","i-lucide-power",{"title":78,"path":79,"stem":80,"icon":81},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F3.error-model","i-lucide-shield-alert",{"title":52,"path":83,"stem":84,"icon":85},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F4.configuration","i-lucide-settings-2",{"title":87,"path":88,"stem":89,"icon":90},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F5.codegen-pipeline","i-lucide-file-json",{"title":92,"path":93,"stem":94,"icon":95},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F6.design-patterns","i-lucide-puzzle",{"title":97,"icon":98,"path":99,"stem":100,"children":101,"page":44},"HTTP & Routing","i-lucide-globe","\u002Fen\u002Fhttp","en\u002F3.http",[102,107,112,117,122,127],{"title":103,"path":104,"stem":105,"icon":106},"The server core","\u002Fen\u002Fhttp\u002Fserver","en\u002F3.http\u002F1.server","i-lucide-server",{"title":108,"path":109,"stem":110,"icon":111},"The Fiber engine","\u002Fen\u002Fhttp\u002Ffiber","en\u002F3.http\u002F2.fiber","i-lucide-zap",{"title":113,"path":114,"stem":115,"icon":116},"The chi engine","\u002Fen\u002Fhttp\u002Fchi","en\u002F3.http\u002F3.chi","i-lucide-route",{"title":118,"path":119,"stem":120,"icon":121},"Error responses","\u002Fen\u002Fhttp\u002Ferror-responses","en\u002F3.http\u002F4.error-responses","i-lucide-octagon-alert",{"title":123,"path":124,"stem":125,"icon":126},"Validation","\u002Fen\u002Fhttp\u002Fvalidation","en\u002F3.http\u002F5.validation","i-lucide-badge-check",{"title":128,"path":129,"stem":130,"icon":131},"Pagination","\u002Fen\u002Fhttp\u002Fpagination","en\u002F3.http\u002F6.pagination","i-lucide-list-ordered",{"title":133,"icon":134,"path":135,"stem":136,"children":137,"page":44},"Database","i-lucide-database","\u002Fen\u002Fdatabase","en\u002F4.database",[138,142,147,151,156,161],{"title":139,"path":140,"stem":141,"icon":134},"Overview","\u002Fen\u002Fdatabase\u002Foverview","en\u002F4.database\u002F1.overview",{"title":143,"path":144,"stem":145,"icon":146},"pgx","\u002Fen\u002Fdatabase\u002Fpgx","en\u002F4.database\u002F2.pgx","i-lucide-plug",{"title":148,"path":149,"stem":150,"icon":71},"bun","\u002Fen\u002Fdatabase\u002Fbun","en\u002F4.database\u002F3.bun",{"title":152,"path":153,"stem":154,"icon":155},"Transactions","\u002Fen\u002Fdatabase\u002Ftransactions","en\u002F4.database\u002F4.transactions","i-lucide-git-merge",{"title":157,"path":158,"stem":159,"icon":160},"Migrations","\u002Fen\u002Fdatabase\u002Fmigrations","en\u002F4.database\u002F5.migrations","i-lucide-file-stack",{"title":162,"path":163,"stem":164,"icon":165},"Seeders","\u002Fen\u002Fdatabase\u002Fseeding","en\u002F4.database\u002F6.seeding","i-lucide-sprout",{"title":167,"icon":168,"path":169,"stem":170,"children":171,"page":44},"Async & Background","i-lucide-workflow","\u002Fen\u002Fasync","en\u002F5.async",[172,176,181,186,191],{"title":173,"path":174,"stem":175,"icon":131},"Queue","\u002Fen\u002Fasync\u002Fqueue","en\u002F5.async\u002F1.queue",{"title":177,"path":178,"stem":179,"icon":180},"Events","\u002Fen\u002Fasync\u002Fevents","en\u002F5.async\u002F2.events","i-lucide-radio",{"title":182,"path":183,"stem":184,"icon":185},"Outbox","\u002Fen\u002Fasync\u002Foutbox","en\u002F5.async\u002F3.outbox","i-lucide-inbox",{"title":187,"path":188,"stem":189,"icon":190},"Scheduling","\u002Fen\u002Fasync\u002Fscheduler","en\u002F5.async\u002F4.scheduler","i-lucide-calendar-clock",{"title":192,"path":193,"stem":194,"icon":195},"Worker","\u002Fen\u002Fasync\u002Fworker","en\u002F5.async\u002F5.worker","i-lucide-cog",{"title":197,"icon":198,"path":199,"stem":200,"children":201,"page":44},"Security","i-lucide-shield-check","\u002Fen\u002Fsecurity","en\u002F6.security",[202,207,212],{"title":203,"path":204,"stem":205,"icon":206},"Authentication","\u002Fen\u002Fsecurity\u002Fauthentication","en\u002F6.security\u002F1.authentication","i-lucide-key-round",{"title":208,"path":209,"stem":210,"icon":211},"RBAC","\u002Fen\u002Fsecurity\u002Frbac","en\u002F6.security\u002F2.rbac","i-lucide-users",{"title":213,"path":214,"stem":215,"icon":216},"Policies","\u002Fen\u002Fsecurity\u002Fpolicies","en\u002F6.security\u002F3.policies","i-lucide-gavel",{"title":218,"icon":219,"path":220,"stem":221,"children":222,"page":44},"Observability","i-lucide-activity","\u002Fen\u002Fobservability","en\u002F7.observability",[223,226,231,236],{"title":139,"path":224,"stem":225,"icon":219},"\u002Fen\u002Fobservability\u002Foverview","en\u002F7.observability\u002F1.overview",{"title":227,"path":228,"stem":229,"icon":230},"Logging","\u002Fen\u002Fobservability\u002Flogging","en\u002F7.observability\u002F2.logging","i-lucide-scroll-text",{"title":232,"path":233,"stem":234,"icon":235},"OpenTelemetry","\u002Fen\u002Fobservability\u002Fopentelemetry","en\u002F7.observability\u002F3.opentelemetry","i-lucide-radar",{"title":237,"path":238,"stem":239,"icon":240},"Sentry","\u002Fen\u002Fobservability\u002Fsentry","en\u002F7.observability\u002F4.sentry","i-lucide-bug",{"title":242,"icon":243,"path":244,"stem":245,"children":246,"page":44},"Storage & Mail","i-lucide-hard-drive","\u002Fen\u002Fstorage-mail","en\u002F8.storage-mail",[247,251,256,261],{"title":248,"path":249,"stem":250,"icon":243},"Storage","\u002Fen\u002Fstorage-mail\u002Fstorage","en\u002F8.storage-mail\u002F1.storage",{"title":252,"path":253,"stem":254,"icon":255},"Email","\u002Fen\u002Fstorage-mail\u002Fmail","en\u002F8.storage-mail\u002F2.mail","i-lucide-mail",{"title":257,"path":258,"stem":259,"icon":260},"Notifications","\u002Fen\u002Fstorage-mail\u002Fnotifications","en\u002F8.storage-mail\u002F3.notifications","i-lucide-bell",{"title":262,"path":263,"stem":264,"icon":180},"Realtime","\u002Fen\u002Fstorage-mail\u002Frealtime","en\u002F8.storage-mail\u002F4.realtime",{"title":266,"icon":267,"path":268,"stem":269,"children":270,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F9.cli",[271,274,279,284,289,294,299,303,308,313,318,323,328,333,337],{"title":139,"path":272,"stem":273,"icon":267},"\u002Fen\u002Fcli\u002Foverview","en\u002F9.cli\u002F1.overview",{"title":275,"path":276,"stem":277,"icon":278},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F9.cli\u002F10.add-db","i-lucide-database-zap",{"title":280,"path":281,"stem":282,"icon":283},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F9.cli\u002F11.add-compose","i-lucide-container",{"title":285,"path":286,"stem":287,"icon":288},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F9.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":290,"path":291,"stem":292,"icon":293},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F9.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":295,"path":296,"stem":297,"icon":298},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F9.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":300,"path":301,"stem":302,"icon":165},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F9.cli\u002F15.add-seeder",{"title":304,"path":305,"stem":306,"icon":307},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F9.cli\u002F2.new-project","i-lucide-folder-plus",{"title":309,"path":310,"stem":311,"icon":312},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F9.cli\u002F3.new-module","i-lucide-blocks",{"title":314,"path":315,"stem":316,"icon":317},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F9.cli\u002F4.add-surface","i-lucide-layers-2",{"title":319,"path":320,"stem":321,"icon":322},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F9.cli\u002F5.add-core","i-lucide-box",{"title":324,"path":325,"stem":326,"icon":327},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F9.cli\u002F6.add-handler","i-lucide-webhook",{"title":329,"path":330,"stem":331,"icon":332},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F9.cli\u002F7.new-migration","i-lucide-file-plus",{"title":334,"path":335,"stem":336,"icon":195},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F9.cli\u002F8.worker-generators",{"title":338,"path":339,"stem":340,"icon":341},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F9.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"id":343,"title":40,"body":344,"description":8401,"extension":8402,"links":8403,"meta":8404,"navigation":8405,"path":41,"seo":8406,"stem":42,"__hash__":8407},"docs_en\u002Fen\u002F1.getting-started\u002F7.sample-app.md",{"type":345,"value":346,"toc":8395},"minimark",[347,356,361,439,443,446,671,675,724,7715,7732,8226,8240,8244,8251,8384,8391],[348,349,350,351,355],"p",{},"The documentation's examples come from one coherent project: ",[352,353,354],"strong",{},"shop"," is a webshop backend with two surfaces, a worker binary, events and a scheduled job. You don't need to build it to read the docs, but every page references this project's files, so the details add up to one coherent whole.",[357,358,360],"h2",{"id":359},"what-it-models","What it models",[362,363,364,385,403,415,427],"ul",{},[365,366,367,375,376,380,381,384],"li",{},[352,368,369,370,374],{},"The ",[371,372,373],"code",{},"api"," surface"," (public): product listing with ",[377,378,379],"a",{"href":129},"cursor pagination",", placing an order (",[371,382,383],{},"PlaceOrder","), with validation, a policy check and a transaction.",[365,386,387,392,393,396,397,402],{},[352,388,369,389,374],{},[371,390,391],{},"admin",": product CRUD and image upload to ",[377,394,395],{"href":249},"object storage",", behind ",[377,398,399],{"href":209},[371,400,401],{},"RequireRole(\"admin\")",".",[365,404,405,411,412,402],{},[352,406,369,407,410],{},[371,408,409],{},"orderPlaced"," event",": dispatched from the order-placement transaction, reaching the queue through the ",[377,413,414],{"href":183},"outbox",[365,416,417,423,424,402],{},[352,418,369,419,422],{},[371,420,421],{},"sendOrderConfirmation"," listener",": runs in the worker, sends an ",[377,425,426],{"href":253},"MJML e-mail",[365,428,429,435,436,402],{},[352,430,369,431,434],{},[371,432,433],{},"nightlySalesReport"," job",": runs every night, ",[377,437,438],{"href":188},"replica-safe",[357,440,442],{"id":441},"how-its-generated","How it's generated",[348,444,445],{},"The entire scaffold comes from the CLI: with exactly these commands:",[447,448,453],"pre",{"className":449,"code":450,"language":451,"meta":452,"style":452},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go tool gpsystem new project shop --module-path github.com\u002Facme\u002Fshop \\\n  --dir .\u002Fshop                    # --engine chi and\u002For --db bun also available\ncd shop\n\ngo tool gpsystem new module shop                 # api surface, by default\ngo tool gpsystem add surface shop admin\ngo tool gpsystem add event shop orderPlaced\ngo tool gpsystem add listener shop orderPlaced sendOrderConfirmation --queue mail\ngo tool gpsystem add job shop nightlySalesReport --cron \"0 3 * * *\"\ngo tool gpsystem new migration create_products_and_orders\n\nmise run generate                                # tsp → OpenAPI → server code → build\n","sh","",[371,454,455,490,503,513,520,539,558,576,603,634,651,656],{"__ignoreMap":452},[456,457,460,464,468,471,474,477,480,483,486],"span",{"class":458,"line":459},"line",1,[456,461,463],{"class":462},"sBMFI","go",[456,465,467],{"class":466},"sfazB"," tool",[456,469,470],{"class":466}," gpsystem",[456,472,473],{"class":466}," new",[456,475,476],{"class":466}," project",[456,478,479],{"class":466}," shop",[456,481,482],{"class":466}," --module-path",[456,484,485],{"class":466}," github.com\u002Facme\u002Fshop",[456,487,489],{"class":488},"sTEyZ"," \\\n",[456,491,493,496,499],{"class":458,"line":492},2,[456,494,495],{"class":466},"  --dir",[456,497,498],{"class":466}," .\u002Fshop",[456,500,502],{"class":501},"sHwdD","                    # --engine chi and\u002For --db bun also available\n",[456,504,506,510],{"class":458,"line":505},3,[456,507,509],{"class":508},"s2Zo4","cd",[456,511,512],{"class":466}," shop\n",[456,514,516],{"class":458,"line":515},4,[456,517,519],{"emptyLinePlaceholder":518},true,"\n",[456,521,523,525,527,529,531,534,536],{"class":458,"line":522},5,[456,524,463],{"class":462},[456,526,467],{"class":466},[456,528,470],{"class":466},[456,530,473],{"class":466},[456,532,533],{"class":466}," module",[456,535,479],{"class":466},[456,537,538],{"class":501},"                 # api surface, by default\n",[456,540,542,544,546,548,551,553,555],{"class":458,"line":541},6,[456,543,463],{"class":462},[456,545,467],{"class":466},[456,547,470],{"class":466},[456,549,550],{"class":466}," add",[456,552,374],{"class":466},[456,554,479],{"class":466},[456,556,557],{"class":466}," admin\n",[456,559,561,563,565,567,569,571,573],{"class":458,"line":560},7,[456,562,463],{"class":462},[456,564,467],{"class":466},[456,566,470],{"class":466},[456,568,550],{"class":466},[456,570,410],{"class":466},[456,572,479],{"class":466},[456,574,575],{"class":466}," orderPlaced\n",[456,577,579,581,583,585,587,589,591,594,597,600],{"class":458,"line":578},8,[456,580,463],{"class":462},[456,582,467],{"class":466},[456,584,470],{"class":466},[456,586,550],{"class":466},[456,588,422],{"class":466},[456,590,479],{"class":466},[456,592,593],{"class":466}," orderPlaced",[456,595,596],{"class":466}," sendOrderConfirmation",[456,598,599],{"class":466}," --queue",[456,601,602],{"class":466}," mail\n",[456,604,606,608,610,612,614,616,618,621,624,628,631],{"class":458,"line":605},9,[456,607,463],{"class":462},[456,609,467],{"class":466},[456,611,470],{"class":466},[456,613,550],{"class":466},[456,615,434],{"class":466},[456,617,479],{"class":466},[456,619,620],{"class":466}," nightlySalesReport",[456,622,623],{"class":466}," --cron",[456,625,627],{"class":626},"sMK4o"," \"",[456,629,630],{"class":466},"0 3 * * *",[456,632,633],{"class":626},"\"\n",[456,635,637,639,641,643,645,648],{"class":458,"line":636},10,[456,638,463],{"class":462},[456,640,467],{"class":466},[456,642,470],{"class":466},[456,644,473],{"class":466},[456,646,647],{"class":466}," migration",[456,649,650],{"class":466}," create_products_and_orders\n",[456,652,654],{"class":458,"line":653},11,[456,655,519],{"emptyLinePlaceholder":518},[456,657,659,662,665,668],{"class":458,"line":658},12,[456,660,661],{"class":462},"mise",[456,663,664],{"class":466}," run",[456,666,667],{"class":466}," generate",[456,669,670],{"class":501},"                                # tsp → OpenAPI → server code → build\n",[357,672,674],{"id":673},"the-shape-of-the-project","The shape of the project",[348,676,677,678,680,681,684,685,687,688,691,692,694,695,698,699,702,703,705,706,709,710,713,714,716,717,716,720,723],{},"Every file below is exactly what the generator + your business logic produce, click through the tree. The ",[371,679,373],{}," surface mounts at the module root (",[371,682,683],{},"\u002Fapi\u002Fv1\u002Fshop\u002F...","), ",[371,686,391],{}," under its own prefix (",[371,689,690],{},"\u002Fapi\u002Fv1\u002Fadmin\u002Fshop\u002F...","), see ",[377,693,314],{"href":315},". The shared ordering rule lives in the module's ",[371,696,697],{},"core\u002F"," package and the persistence in the module-level ",[371,700,701],{},"repository\u002F","; the ",[371,704,373],{}," surface's ",[371,707,708],{},"service\u002F"," is a thin seam over them. The generated ",[371,711,712],{},"\u002F\u002F gpsystem:*"," anchor comments are mostly omitted for readability; in your own project leave them in place, later ",[371,715,314],{}," \u002F ",[371,718,719],{},"add event",[371,721,722],{},"add listener"," calls insert at those points.",[725,726,729,1329,1916,2696,2854,2988,3091,3458,3650,4129,4722,5327,6004,7024,7173,7455],"code-tree",{":expand-all":727,"default-value":728},"true","cmd\u002Fshop\u002Fmain.go",[447,730,733],{"className":731,"code":732,"filename":728,"language":463,"meta":452,"style":452},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com\u002Fgofiber\u002Ffiber\u002Fv3\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\u002Fpg\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fenvconf\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\u002Foutbox\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fserver\u002Ffiberx\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fplatform\u002Fconfig\"\n)\n\nfunc main() {\n    cfg := envconf.MustLoad[config.Config]()\n    ctx := context.Background()\n    pool := pg.MustNewPool(ctx, cfg.DB)\n\n    err := fiberx.Run(ctx, cfg.Server, func(app *fiber.App) error {\n        api := app.Group(\"\u002Fapi\u002Fv1\")\n        deps := shop.Dependencies{\n            DB:         pg.NewDB(pool),\n            Transactor: pg.NewTransactor(pool),\n            Dispatcher: outbox.NewDispatcher(outbox.NewStore(pg.NewDB(pool))),\n        }\n        shop.RegisterApi(api, deps)\n        shop.RegisterAdmin(api, deps)\n        return nil\n    }, fiberx.WithCloser(\"pgxpool\", func(context.Context) error {\n        pool.Close()\n        return nil\n    }))\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n",[371,734,735,743,747,756,766,775,779,788,792,801,810,819,828,833,843,853,859,864,879,910,929,964,969,1027,1055,1073,1098,1119,1160,1166,1188,1208,1217,1256,1269,1276,1282,1299,1317,1323],{"__ignoreMap":452},[456,736,737,740],{"class":458,"line":459},[456,738,739],{"class":626},"package",[456,741,742],{"class":462}," main\n",[456,744,745],{"class":458,"line":492},[456,746,519],{"emptyLinePlaceholder":518},[456,748,749,753],{"class":458,"line":505},[456,750,752],{"class":751},"s7zQu","import",[456,754,755],{"class":626}," (\n",[456,757,758,761,764],{"class":458,"line":515},[456,759,760],{"class":626},"    \"",[456,762,763],{"class":462},"context",[456,765,633],{"class":626},[456,767,768,770,773],{"class":458,"line":522},[456,769,760],{"class":626},[456,771,772],{"class":462},"log",[456,774,633],{"class":626},[456,776,777],{"class":458,"line":541},[456,778,519],{"emptyLinePlaceholder":518},[456,780,781,783,786],{"class":458,"line":560},[456,782,760],{"class":626},[456,784,785],{"class":462},"github.com\u002Fgofiber\u002Ffiber\u002Fv3",[456,787,633],{"class":626},[456,789,790],{"class":458,"line":578},[456,791,519],{"emptyLinePlaceholder":518},[456,793,794,796,799],{"class":458,"line":605},[456,795,760],{"class":626},[456,797,798],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\u002Fpg",[456,800,633],{"class":626},[456,802,803,805,808],{"class":458,"line":636},[456,804,760],{"class":626},[456,806,807],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fenvconf",[456,809,633],{"class":626},[456,811,812,814,817],{"class":458,"line":653},[456,813,760],{"class":626},[456,815,816],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\u002Foutbox",[456,818,633],{"class":626},[456,820,821,823,826],{"class":458,"line":658},[456,822,760],{"class":626},[456,824,825],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fserver\u002Ffiberx",[456,827,633],{"class":626},[456,829,831],{"class":458,"line":830},13,[456,832,519],{"emptyLinePlaceholder":518},[456,834,836,838,841],{"class":458,"line":835},14,[456,837,760],{"class":626},[456,839,840],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop",[456,842,633],{"class":626},[456,844,846,848,851],{"class":458,"line":845},15,[456,847,760],{"class":626},[456,849,850],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fplatform\u002Fconfig",[456,852,633],{"class":626},[456,854,856],{"class":458,"line":855},16,[456,857,858],{"class":626},")\n",[456,860,862],{"class":458,"line":861},17,[456,863,519],{"emptyLinePlaceholder":518},[456,865,867,870,873,876],{"class":458,"line":866},18,[456,868,869],{"class":626},"func",[456,871,872],{"class":508}," main",[456,874,875],{"class":626},"()",[456,877,878],{"class":626}," {\n",[456,880,882,885,888,891,893,896,899,902,904,907],{"class":458,"line":881},19,[456,883,884],{"class":488},"    cfg ",[456,886,887],{"class":626},":=",[456,889,890],{"class":488}," envconf",[456,892,402],{"class":626},[456,894,895],{"class":508},"MustLoad",[456,897,898],{"class":626},"[",[456,900,901],{"class":462},"config",[456,903,402],{"class":626},[456,905,906],{"class":462},"Config",[456,908,909],{"class":626},"]()\n",[456,911,913,916,918,921,923,926],{"class":458,"line":912},20,[456,914,915],{"class":488},"    ctx ",[456,917,887],{"class":626},[456,919,920],{"class":488}," context",[456,922,402],{"class":626},[456,924,925],{"class":508},"Background",[456,927,928],{"class":626},"()\n",[456,930,932,935,937,940,942,945,948,951,954,957,959,962],{"class":458,"line":931},21,[456,933,934],{"class":488},"    pool ",[456,936,887],{"class":626},[456,938,939],{"class":488}," pg",[456,941,402],{"class":626},[456,943,944],{"class":508},"MustNewPool",[456,946,947],{"class":626},"(",[456,949,950],{"class":488},"ctx",[456,952,953],{"class":626},",",[456,955,956],{"class":488}," cfg",[456,958,402],{"class":626},[456,960,961],{"class":488},"DB",[456,963,858],{"class":626},[456,965,967],{"class":458,"line":966},22,[456,968,519],{"emptyLinePlaceholder":518},[456,970,972,975,977,980,982,985,987,989,991,993,995,998,1000,1003,1007,1010,1013,1015,1018,1021,1025],{"class":458,"line":971},23,[456,973,974],{"class":488},"    err ",[456,976,887],{"class":626},[456,978,979],{"class":488}," fiberx",[456,981,402],{"class":626},[456,983,984],{"class":508},"Run",[456,986,947],{"class":626},[456,988,950],{"class":488},[456,990,953],{"class":626},[456,992,956],{"class":488},[456,994,402],{"class":626},[456,996,997],{"class":488},"Server",[456,999,953],{"class":626},[456,1001,1002],{"class":626}," func(",[456,1004,1006],{"class":1005},"sHdIc","app",[456,1008,1009],{"class":626}," *",[456,1011,1012],{"class":462},"fiber",[456,1014,402],{"class":626},[456,1016,1017],{"class":462},"App",[456,1019,1020],{"class":626},")",[456,1022,1024],{"class":1023},"spNyl"," error",[456,1026,878],{"class":626},[456,1028,1030,1033,1035,1038,1040,1043,1045,1048,1051,1053],{"class":458,"line":1029},24,[456,1031,1032],{"class":488},"        api ",[456,1034,887],{"class":626},[456,1036,1037],{"class":488}," app",[456,1039,402],{"class":626},[456,1041,1042],{"class":508},"Group",[456,1044,947],{"class":626},[456,1046,1047],{"class":626},"\"",[456,1049,1050],{"class":466},"\u002Fapi\u002Fv1",[456,1052,1047],{"class":626},[456,1054,858],{"class":626},[456,1056,1058,1061,1063,1065,1067,1070],{"class":458,"line":1057},25,[456,1059,1060],{"class":488},"        deps ",[456,1062,887],{"class":626},[456,1064,479],{"class":462},[456,1066,402],{"class":626},[456,1068,1069],{"class":462},"Dependencies",[456,1071,1072],{"class":626},"{\n",[456,1074,1076,1079,1082,1085,1087,1090,1092,1095],{"class":458,"line":1075},26,[456,1077,1078],{"class":488},"            DB",[456,1080,1081],{"class":626},":",[456,1083,1084],{"class":488},"         pg",[456,1086,402],{"class":626},[456,1088,1089],{"class":508},"NewDB",[456,1091,947],{"class":626},[456,1093,1094],{"class":488},"pool",[456,1096,1097],{"class":626},"),\n",[456,1099,1101,1104,1106,1108,1110,1113,1115,1117],{"class":458,"line":1100},27,[456,1102,1103],{"class":488},"            Transactor",[456,1105,1081],{"class":626},[456,1107,939],{"class":488},[456,1109,402],{"class":626},[456,1111,1112],{"class":508},"NewTransactor",[456,1114,947],{"class":626},[456,1116,1094],{"class":488},[456,1118,1097],{"class":626},[456,1120,1122,1125,1127,1130,1132,1135,1137,1139,1141,1144,1146,1149,1151,1153,1155,1157],{"class":458,"line":1121},28,[456,1123,1124],{"class":488},"            Dispatcher",[456,1126,1081],{"class":626},[456,1128,1129],{"class":488}," outbox",[456,1131,402],{"class":626},[456,1133,1134],{"class":508},"NewDispatcher",[456,1136,947],{"class":626},[456,1138,414],{"class":488},[456,1140,402],{"class":626},[456,1142,1143],{"class":508},"NewStore",[456,1145,947],{"class":626},[456,1147,1148],{"class":488},"pg",[456,1150,402],{"class":626},[456,1152,1089],{"class":508},[456,1154,947],{"class":626},[456,1156,1094],{"class":488},[456,1158,1159],{"class":626},"))),\n",[456,1161,1163],{"class":458,"line":1162},29,[456,1164,1165],{"class":626},"        }\n",[456,1167,1169,1172,1174,1177,1179,1181,1183,1186],{"class":458,"line":1168},30,[456,1170,1171],{"class":488},"        shop",[456,1173,402],{"class":626},[456,1175,1176],{"class":508},"RegisterApi",[456,1178,947],{"class":626},[456,1180,373],{"class":488},[456,1182,953],{"class":626},[456,1184,1185],{"class":488}," deps",[456,1187,858],{"class":626},[456,1189,1191,1193,1195,1198,1200,1202,1204,1206],{"class":458,"line":1190},31,[456,1192,1171],{"class":488},[456,1194,402],{"class":626},[456,1196,1197],{"class":508},"RegisterAdmin",[456,1199,947],{"class":626},[456,1201,373],{"class":488},[456,1203,953],{"class":626},[456,1205,1185],{"class":488},[456,1207,858],{"class":626},[456,1209,1211,1214],{"class":458,"line":1210},32,[456,1212,1213],{"class":751},"        return",[456,1215,1216],{"class":626}," nil\n",[456,1218,1220,1223,1225,1227,1230,1232,1234,1237,1239,1241,1243,1245,1247,1250,1252,1254],{"class":458,"line":1219},33,[456,1221,1222],{"class":626},"    },",[456,1224,979],{"class":488},[456,1226,402],{"class":626},[456,1228,1229],{"class":508},"WithCloser",[456,1231,947],{"class":626},[456,1233,1047],{"class":626},[456,1235,1236],{"class":466},"pgxpool",[456,1238,1047],{"class":626},[456,1240,953],{"class":626},[456,1242,1002],{"class":626},[456,1244,763],{"class":462},[456,1246,402],{"class":626},[456,1248,1249],{"class":462},"Context",[456,1251,1020],{"class":626},[456,1253,1024],{"class":1023},[456,1255,878],{"class":626},[456,1257,1259,1262,1264,1267],{"class":458,"line":1258},34,[456,1260,1261],{"class":488},"        pool",[456,1263,402],{"class":626},[456,1265,1266],{"class":508},"Close",[456,1268,928],{"class":626},[456,1270,1272,1274],{"class":458,"line":1271},35,[456,1273,1213],{"class":751},[456,1275,1216],{"class":626},[456,1277,1279],{"class":458,"line":1278},36,[456,1280,1281],{"class":626},"    }))\n",[456,1283,1285,1288,1291,1294,1297],{"class":458,"line":1284},37,[456,1286,1287],{"class":751},"    if",[456,1289,1290],{"class":488}," err ",[456,1292,1293],{"class":626},"!=",[456,1295,1296],{"class":626}," nil",[456,1298,878],{"class":626},[456,1300,1302,1305,1307,1310,1312,1315],{"class":458,"line":1301},38,[456,1303,1304],{"class":488},"        log",[456,1306,402],{"class":626},[456,1308,1309],{"class":508},"Fatal",[456,1311,947],{"class":626},[456,1313,1314],{"class":488},"err",[456,1316,858],{"class":626},[456,1318,1320],{"class":458,"line":1319},39,[456,1321,1322],{"class":626},"    }\n",[456,1324,1326],{"class":458,"line":1325},40,[456,1327,1328],{"class":626},"}\n",[447,1330,1333],{"className":731,"code":1331,"filename":1332,"language":463,"meta":452,"style":452},"package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\u002Fpg\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fenvconf\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\u002Foutbox\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fscheduler\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fworker\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n    shopjobs \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fjobs\"\n    shoplisteners \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Flisteners\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fplatform\u002Fconfig\"\n)\n\nfunc main() {\n    cfg := envconf.MustLoad[config.Config]()\n    ctx := context.Background()\n    pool := pg.MustNewPool(ctx, cfg.DB)\n    relay := outbox.MustNewRelay(ctx, cfg.Outbox, pool, cfg.Worker.Redis)\n\n    err := worker.Run(ctx, cfg.Worker, func(reg *events.Registry, sched *scheduler.Schedule) error {\n        shopDeps := shop.Dependencies{\n            DB:         pg.NewDB(pool),\n            Transactor: pg.NewTransactor(pool),\n            Dispatcher: outbox.NewDispatcher(outbox.NewStore(pg.NewDB(pool))),\n        }\n        shoplisteners.Register(reg, shopDeps)\n        shopjobs.Register(sched, shopDeps)\n        return nil\n    },\n        worker.WithOutboxRelay(relay),\n        worker.WithCloser(\"pgxpool\", func(context.Context) error {\n            pool.Close()\n            return nil\n        }),\n    )\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n","cmd\u002Fworker\u002Fmain.go",[371,1334,1335,1341,1345,1351,1359,1367,1371,1379,1387,1396,1404,1413,1422,1426,1434,1446,1458,1466,1470,1474,1484,1506,1520,1546,1592,1596,1659,1674,1692,1710,1744,1748,1769,1789,1795,1800,1817,1849,1860,1867,1872,1878,1891,1906,1911],{"__ignoreMap":452},[456,1336,1337,1339],{"class":458,"line":459},[456,1338,739],{"class":626},[456,1340,742],{"class":462},[456,1342,1343],{"class":458,"line":492},[456,1344,519],{"emptyLinePlaceholder":518},[456,1346,1347,1349],{"class":458,"line":505},[456,1348,752],{"class":751},[456,1350,755],{"class":626},[456,1352,1353,1355,1357],{"class":458,"line":515},[456,1354,760],{"class":626},[456,1356,763],{"class":462},[456,1358,633],{"class":626},[456,1360,1361,1363,1365],{"class":458,"line":522},[456,1362,760],{"class":626},[456,1364,772],{"class":462},[456,1366,633],{"class":626},[456,1368,1369],{"class":458,"line":541},[456,1370,519],{"emptyLinePlaceholder":518},[456,1372,1373,1375,1377],{"class":458,"line":560},[456,1374,760],{"class":626},[456,1376,798],{"class":462},[456,1378,633],{"class":626},[456,1380,1381,1383,1385],{"class":458,"line":578},[456,1382,760],{"class":626},[456,1384,807],{"class":462},[456,1386,633],{"class":626},[456,1388,1389,1391,1394],{"class":458,"line":605},[456,1390,760],{"class":626},[456,1392,1393],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents",[456,1395,633],{"class":626},[456,1397,1398,1400,1402],{"class":458,"line":636},[456,1399,760],{"class":626},[456,1401,816],{"class":462},[456,1403,633],{"class":626},[456,1405,1406,1408,1411],{"class":458,"line":653},[456,1407,760],{"class":626},[456,1409,1410],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fscheduler",[456,1412,633],{"class":626},[456,1414,1415,1417,1420],{"class":458,"line":658},[456,1416,760],{"class":626},[456,1418,1419],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fworker",[456,1421,633],{"class":626},[456,1423,1424],{"class":458,"line":830},[456,1425,519],{"emptyLinePlaceholder":518},[456,1427,1428,1430,1432],{"class":458,"line":835},[456,1429,760],{"class":626},[456,1431,840],{"class":462},[456,1433,633],{"class":626},[456,1435,1436,1439,1441,1444],{"class":458,"line":845},[456,1437,1438],{"class":488},"    shopjobs ",[456,1440,1047],{"class":626},[456,1442,1443],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fjobs",[456,1445,633],{"class":626},[456,1447,1448,1451,1453,1456],{"class":458,"line":855},[456,1449,1450],{"class":488},"    shoplisteners ",[456,1452,1047],{"class":626},[456,1454,1455],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Flisteners",[456,1457,633],{"class":626},[456,1459,1460,1462,1464],{"class":458,"line":861},[456,1461,760],{"class":626},[456,1463,850],{"class":462},[456,1465,633],{"class":626},[456,1467,1468],{"class":458,"line":866},[456,1469,858],{"class":626},[456,1471,1472],{"class":458,"line":881},[456,1473,519],{"emptyLinePlaceholder":518},[456,1475,1476,1478,1480,1482],{"class":458,"line":912},[456,1477,869],{"class":626},[456,1479,872],{"class":508},[456,1481,875],{"class":626},[456,1483,878],{"class":626},[456,1485,1486,1488,1490,1492,1494,1496,1498,1500,1502,1504],{"class":458,"line":931},[456,1487,884],{"class":488},[456,1489,887],{"class":626},[456,1491,890],{"class":488},[456,1493,402],{"class":626},[456,1495,895],{"class":508},[456,1497,898],{"class":626},[456,1499,901],{"class":462},[456,1501,402],{"class":626},[456,1503,906],{"class":462},[456,1505,909],{"class":626},[456,1507,1508,1510,1512,1514,1516,1518],{"class":458,"line":966},[456,1509,915],{"class":488},[456,1511,887],{"class":626},[456,1513,920],{"class":488},[456,1515,402],{"class":626},[456,1517,925],{"class":508},[456,1519,928],{"class":626},[456,1521,1522,1524,1526,1528,1530,1532,1534,1536,1538,1540,1542,1544],{"class":458,"line":971},[456,1523,934],{"class":488},[456,1525,887],{"class":626},[456,1527,939],{"class":488},[456,1529,402],{"class":626},[456,1531,944],{"class":508},[456,1533,947],{"class":626},[456,1535,950],{"class":488},[456,1537,953],{"class":626},[456,1539,956],{"class":488},[456,1541,402],{"class":626},[456,1543,961],{"class":488},[456,1545,858],{"class":626},[456,1547,1548,1551,1553,1555,1557,1560,1562,1564,1566,1568,1570,1572,1574,1577,1579,1581,1583,1585,1587,1590],{"class":458,"line":1029},[456,1549,1550],{"class":488},"    relay ",[456,1552,887],{"class":626},[456,1554,1129],{"class":488},[456,1556,402],{"class":626},[456,1558,1559],{"class":508},"MustNewRelay",[456,1561,947],{"class":626},[456,1563,950],{"class":488},[456,1565,953],{"class":626},[456,1567,956],{"class":488},[456,1569,402],{"class":626},[456,1571,182],{"class":488},[456,1573,953],{"class":626},[456,1575,1576],{"class":488}," pool",[456,1578,953],{"class":626},[456,1580,956],{"class":488},[456,1582,402],{"class":626},[456,1584,192],{"class":488},[456,1586,402],{"class":626},[456,1588,1589],{"class":488},"Redis",[456,1591,858],{"class":626},[456,1593,1594],{"class":458,"line":1057},[456,1595,519],{"emptyLinePlaceholder":518},[456,1597,1598,1600,1602,1605,1607,1609,1611,1613,1615,1617,1619,1621,1623,1625,1628,1630,1633,1635,1638,1640,1643,1645,1648,1650,1653,1655,1657],{"class":458,"line":1075},[456,1599,974],{"class":488},[456,1601,887],{"class":626},[456,1603,1604],{"class":488}," worker",[456,1606,402],{"class":626},[456,1608,984],{"class":508},[456,1610,947],{"class":626},[456,1612,950],{"class":488},[456,1614,953],{"class":626},[456,1616,956],{"class":488},[456,1618,402],{"class":626},[456,1620,192],{"class":488},[456,1622,953],{"class":626},[456,1624,1002],{"class":626},[456,1626,1627],{"class":1005},"reg",[456,1629,1009],{"class":626},[456,1631,1632],{"class":462},"events",[456,1634,402],{"class":626},[456,1636,1637],{"class":462},"Registry",[456,1639,953],{"class":626},[456,1641,1642],{"class":1005}," sched",[456,1644,1009],{"class":626},[456,1646,1647],{"class":462},"scheduler",[456,1649,402],{"class":626},[456,1651,1652],{"class":462},"Schedule",[456,1654,1020],{"class":626},[456,1656,1024],{"class":1023},[456,1658,878],{"class":626},[456,1660,1661,1664,1666,1668,1670,1672],{"class":458,"line":1100},[456,1662,1663],{"class":488},"        shopDeps ",[456,1665,887],{"class":626},[456,1667,479],{"class":462},[456,1669,402],{"class":626},[456,1671,1069],{"class":462},[456,1673,1072],{"class":626},[456,1675,1676,1678,1680,1682,1684,1686,1688,1690],{"class":458,"line":1121},[456,1677,1078],{"class":488},[456,1679,1081],{"class":626},[456,1681,1084],{"class":488},[456,1683,402],{"class":626},[456,1685,1089],{"class":508},[456,1687,947],{"class":626},[456,1689,1094],{"class":488},[456,1691,1097],{"class":626},[456,1693,1694,1696,1698,1700,1702,1704,1706,1708],{"class":458,"line":1162},[456,1695,1103],{"class":488},[456,1697,1081],{"class":626},[456,1699,939],{"class":488},[456,1701,402],{"class":626},[456,1703,1112],{"class":508},[456,1705,947],{"class":626},[456,1707,1094],{"class":488},[456,1709,1097],{"class":626},[456,1711,1712,1714,1716,1718,1720,1722,1724,1726,1728,1730,1732,1734,1736,1738,1740,1742],{"class":458,"line":1168},[456,1713,1124],{"class":488},[456,1715,1081],{"class":626},[456,1717,1129],{"class":488},[456,1719,402],{"class":626},[456,1721,1134],{"class":508},[456,1723,947],{"class":626},[456,1725,414],{"class":488},[456,1727,402],{"class":626},[456,1729,1143],{"class":508},[456,1731,947],{"class":626},[456,1733,1148],{"class":488},[456,1735,402],{"class":626},[456,1737,1089],{"class":508},[456,1739,947],{"class":626},[456,1741,1094],{"class":488},[456,1743,1159],{"class":626},[456,1745,1746],{"class":458,"line":1190},[456,1747,1165],{"class":626},[456,1749,1750,1753,1755,1758,1760,1762,1764,1767],{"class":458,"line":1210},[456,1751,1752],{"class":488},"        shoplisteners",[456,1754,402],{"class":626},[456,1756,1757],{"class":508},"Register",[456,1759,947],{"class":626},[456,1761,1627],{"class":488},[456,1763,953],{"class":626},[456,1765,1766],{"class":488}," shopDeps",[456,1768,858],{"class":626},[456,1770,1771,1774,1776,1778,1780,1783,1785,1787],{"class":458,"line":1219},[456,1772,1773],{"class":488},"        shopjobs",[456,1775,402],{"class":626},[456,1777,1757],{"class":508},[456,1779,947],{"class":626},[456,1781,1782],{"class":488},"sched",[456,1784,953],{"class":626},[456,1786,1766],{"class":488},[456,1788,858],{"class":626},[456,1790,1791,1793],{"class":458,"line":1258},[456,1792,1213],{"class":751},[456,1794,1216],{"class":626},[456,1796,1797],{"class":458,"line":1271},[456,1798,1799],{"class":626},"    },\n",[456,1801,1802,1805,1807,1810,1812,1815],{"class":458,"line":1278},[456,1803,1804],{"class":488},"        worker",[456,1806,402],{"class":626},[456,1808,1809],{"class":508},"WithOutboxRelay",[456,1811,947],{"class":626},[456,1813,1814],{"class":488},"relay",[456,1816,1097],{"class":626},[456,1818,1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847],{"class":458,"line":1284},[456,1820,1804],{"class":488},[456,1822,402],{"class":626},[456,1824,1229],{"class":508},[456,1826,947],{"class":626},[456,1828,1047],{"class":626},[456,1830,1236],{"class":466},[456,1832,1047],{"class":626},[456,1834,953],{"class":626},[456,1836,1002],{"class":626},[456,1838,763],{"class":462},[456,1840,402],{"class":626},[456,1842,1249],{"class":462},[456,1844,1020],{"class":626},[456,1846,1024],{"class":1023},[456,1848,878],{"class":626},[456,1850,1851,1854,1856,1858],{"class":458,"line":1301},[456,1852,1853],{"class":488},"            pool",[456,1855,402],{"class":626},[456,1857,1266],{"class":508},[456,1859,928],{"class":626},[456,1861,1862,1865],{"class":458,"line":1319},[456,1863,1864],{"class":751},"            return",[456,1866,1216],{"class":626},[456,1868,1869],{"class":458,"line":1325},[456,1870,1871],{"class":626},"        }),\n",[456,1873,1875],{"class":458,"line":1874},41,[456,1876,1877],{"class":626},"    )\n",[456,1879,1881,1883,1885,1887,1889],{"class":458,"line":1880},42,[456,1882,1287],{"class":751},[456,1884,1290],{"class":488},[456,1886,1293],{"class":626},[456,1888,1296],{"class":626},[456,1890,878],{"class":626},[456,1892,1894,1896,1898,1900,1902,1904],{"class":458,"line":1893},43,[456,1895,1304],{"class":488},[456,1897,402],{"class":626},[456,1899,1309],{"class":508},[456,1901,947],{"class":626},[456,1903,1314],{"class":488},[456,1905,858],{"class":626},[456,1907,1909],{"class":458,"line":1908},44,[456,1910,1322],{"class":626},[456,1912,1914],{"class":458,"line":1913},45,[456,1915,1328],{"class":626},[447,1917,1920],{"className":731,"code":1918,"filename":1919,"language":463,"meta":452,"style":452},"package shop\n\nimport (\n    \"github.com\u002Fgofiber\u002Ffiber\u002Fv3\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fauth\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\u002Fpg\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\"\n    kitpolicy \"github.com\u002Fgp-system\u002Fgpsystem\u002Fpolicy\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Frbac\"\n\n    adminhttp \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fhttp\"\n    shopadmingen \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fhttp\u002Fgen\"\n    adminpolicy \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fpolicy\"\n    adminservice \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fservice\"\n    apihttp \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\"\n    shopapigen \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen\"\n    apipolicy \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy\"\n    apiservice \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fservice\"\n    \u002F\u002F gpsystem:imports\n)\n\ntype Dependencies struct {\n    DB         *pg.DB\n    Transactor dbx.Transactor\n    Dispatcher events.Dispatcher\n    Auth       auth.Config \u002F\u002F JWT_SECRET, JWT_ISSUER, ... from the platform config\n    \u002F\u002F gpsystem:dependencies\n}\n\nfunc RegisterApi(router fiber.Router, deps Dependencies) {\n    apiSvc := apiservice.New(deps)\n    apiHandler := apihttp.New(apiSvc)\n    apiPolicies := apipolicy.New(apiSvc.Orders())\n    apiGroup := router.Group(\"\u002Fshop\")\n    shopapigen.RegisterHandlersWithOptions(apiGroup, shopapigen.NewStrictHandler(apiHandler, []shopapigen.StrictMiddlewareFunc{\n        kitpolicy.FiberEnforcer[shopapigen.StrictHandlerFunc](apiPolicies, shopapigen.PermissionByOperation, shopapigen.PolicyByOperation),\n    }), shopapigen.FiberServerOptions{})\n}\n\nfunc RegisterAdmin(router fiber.Router, deps Dependencies) {\n    adminSvc := adminservice.New(deps)\n    adminHandler := adminhttp.New(adminSvc)\n    adminPolicies := adminpolicy.New()\n    adminGroup := router.Group(\"\u002Fadmin\u002Fshop\")\n    adminGroup.Use(auth.Middleware(deps.Auth), rbac.RequireRole(\"admin\"))\n    shopadmingen.RegisterHandlersWithOptions(adminGroup, shopadmingen.NewStrictHandler(adminHandler, []shopadmingen.StrictMiddlewareFunc{\n        kitpolicy.FiberEnforcer[shopadmingen.StrictHandlerFunc](adminPolicies, shopadmingen.PermissionByOperation, shopadmingen.PolicyByOperation),\n    }), shopadmingen.FiberServerOptions{})\n}\n","internal\u002Fmodules\u002Fshop\u002Fregister.go",[371,1921,1922,1928,1932,1938,1946,1950,1959,1968,1976,1984,1996,2005,2009,2021,2033,2045,2057,2069,2081,2093,2105,2110,2114,2118,2131,2146,2159,2171,2186,2191,2195,2199,2229,2251,2272,2298,2323,2368,2413,2428,2432,2436,2463,2483,2504,2520,2545,2596,2638,2678,2691],{"__ignoreMap":452},[456,1923,1924,1926],{"class":458,"line":459},[456,1925,739],{"class":626},[456,1927,512],{"class":462},[456,1929,1930],{"class":458,"line":492},[456,1931,519],{"emptyLinePlaceholder":518},[456,1933,1934,1936],{"class":458,"line":505},[456,1935,752],{"class":751},[456,1937,755],{"class":626},[456,1939,1940,1942,1944],{"class":458,"line":515},[456,1941,760],{"class":626},[456,1943,785],{"class":462},[456,1945,633],{"class":626},[456,1947,1948],{"class":458,"line":522},[456,1949,519],{"emptyLinePlaceholder":518},[456,1951,1952,1954,1957],{"class":458,"line":541},[456,1953,760],{"class":626},[456,1955,1956],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fauth",[456,1958,633],{"class":626},[456,1960,1961,1963,1966],{"class":458,"line":560},[456,1962,760],{"class":626},[456,1964,1965],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx",[456,1967,633],{"class":626},[456,1969,1970,1972,1974],{"class":458,"line":578},[456,1971,760],{"class":626},[456,1973,798],{"class":462},[456,1975,633],{"class":626},[456,1977,1978,1980,1982],{"class":458,"line":605},[456,1979,760],{"class":626},[456,1981,1393],{"class":462},[456,1983,633],{"class":626},[456,1985,1986,1989,1991,1994],{"class":458,"line":636},[456,1987,1988],{"class":488},"    kitpolicy ",[456,1990,1047],{"class":626},[456,1992,1993],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fpolicy",[456,1995,633],{"class":626},[456,1997,1998,2000,2003],{"class":458,"line":653},[456,1999,760],{"class":626},[456,2001,2002],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Frbac",[456,2004,633],{"class":626},[456,2006,2007],{"class":458,"line":658},[456,2008,519],{"emptyLinePlaceholder":518},[456,2010,2011,2014,2016,2019],{"class":458,"line":830},[456,2012,2013],{"class":488},"    adminhttp ",[456,2015,1047],{"class":626},[456,2017,2018],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fhttp",[456,2020,633],{"class":626},[456,2022,2023,2026,2028,2031],{"class":458,"line":835},[456,2024,2025],{"class":488},"    shopadmingen ",[456,2027,1047],{"class":626},[456,2029,2030],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fhttp\u002Fgen",[456,2032,633],{"class":626},[456,2034,2035,2038,2040,2043],{"class":458,"line":845},[456,2036,2037],{"class":488},"    adminpolicy ",[456,2039,1047],{"class":626},[456,2041,2042],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fpolicy",[456,2044,633],{"class":626},[456,2046,2047,2050,2052,2055],{"class":458,"line":855},[456,2048,2049],{"class":488},"    adminservice ",[456,2051,1047],{"class":626},[456,2053,2054],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fadmin\u002Fservice",[456,2056,633],{"class":626},[456,2058,2059,2062,2064,2067],{"class":458,"line":861},[456,2060,2061],{"class":488},"    apihttp ",[456,2063,1047],{"class":626},[456,2065,2066],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp",[456,2068,633],{"class":626},[456,2070,2071,2074,2076,2079],{"class":458,"line":866},[456,2072,2073],{"class":488},"    shopapigen ",[456,2075,1047],{"class":626},[456,2077,2078],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen",[456,2080,633],{"class":626},[456,2082,2083,2086,2088,2091],{"class":458,"line":881},[456,2084,2085],{"class":488},"    apipolicy ",[456,2087,1047],{"class":626},[456,2089,2090],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy",[456,2092,633],{"class":626},[456,2094,2095,2098,2100,2103],{"class":458,"line":912},[456,2096,2097],{"class":488},"    apiservice ",[456,2099,1047],{"class":626},[456,2101,2102],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fservice",[456,2104,633],{"class":626},[456,2106,2107],{"class":458,"line":931},[456,2108,2109],{"class":501},"    \u002F\u002F gpsystem:imports\n",[456,2111,2112],{"class":458,"line":966},[456,2113,858],{"class":626},[456,2115,2116],{"class":458,"line":971},[456,2117,519],{"emptyLinePlaceholder":518},[456,2119,2120,2123,2126,2129],{"class":458,"line":1029},[456,2121,2122],{"class":626},"type",[456,2124,2125],{"class":462}," Dependencies",[456,2127,2128],{"class":626}," struct",[456,2130,878],{"class":626},[456,2132,2133,2136,2139,2141,2143],{"class":458,"line":1057},[456,2134,2135],{"class":488},"    DB         ",[456,2137,2138],{"class":626},"*",[456,2140,1148],{"class":462},[456,2142,402],{"class":626},[456,2144,2145],{"class":462},"DB\n",[456,2147,2148,2151,2154,2156],{"class":458,"line":1075},[456,2149,2150],{"class":488},"    Transactor ",[456,2152,2153],{"class":462},"dbx",[456,2155,402],{"class":626},[456,2157,2158],{"class":462},"Transactor\n",[456,2160,2161,2164,2166,2168],{"class":458,"line":1100},[456,2162,2163],{"class":488},"    Dispatcher ",[456,2165,1632],{"class":462},[456,2167,402],{"class":626},[456,2169,2170],{"class":462},"Dispatcher\n",[456,2172,2173,2176,2179,2181,2183],{"class":458,"line":1121},[456,2174,2175],{"class":488},"    Auth       ",[456,2177,2178],{"class":462},"auth",[456,2180,402],{"class":626},[456,2182,906],{"class":462},[456,2184,2185],{"class":501}," \u002F\u002F JWT_SECRET, JWT_ISSUER, ... from the platform config\n",[456,2187,2188],{"class":458,"line":1162},[456,2189,2190],{"class":501},"    \u002F\u002F gpsystem:dependencies\n",[456,2192,2193],{"class":458,"line":1168},[456,2194,1328],{"class":626},[456,2196,2197],{"class":458,"line":1190},[456,2198,519],{"emptyLinePlaceholder":518},[456,2200,2201,2203,2206,2208,2211,2214,2216,2219,2221,2223,2225,2227],{"class":458,"line":1210},[456,2202,869],{"class":626},[456,2204,2205],{"class":508}," RegisterApi",[456,2207,947],{"class":626},[456,2209,2210],{"class":1005},"router",[456,2212,2213],{"class":462}," fiber",[456,2215,402],{"class":626},[456,2217,2218],{"class":462},"Router",[456,2220,953],{"class":626},[456,2222,1185],{"class":1005},[456,2224,2125],{"class":462},[456,2226,1020],{"class":626},[456,2228,878],{"class":626},[456,2230,2231,2234,2236,2239,2241,2244,2246,2249],{"class":458,"line":1219},[456,2232,2233],{"class":488},"    apiSvc ",[456,2235,887],{"class":626},[456,2237,2238],{"class":488}," apiservice",[456,2240,402],{"class":626},[456,2242,2243],{"class":508},"New",[456,2245,947],{"class":626},[456,2247,2248],{"class":488},"deps",[456,2250,858],{"class":626},[456,2252,2253,2256,2258,2261,2263,2265,2267,2270],{"class":458,"line":1258},[456,2254,2255],{"class":488},"    apiHandler ",[456,2257,887],{"class":626},[456,2259,2260],{"class":488}," apihttp",[456,2262,402],{"class":626},[456,2264,2243],{"class":508},[456,2266,947],{"class":626},[456,2268,2269],{"class":488},"apiSvc",[456,2271,858],{"class":626},[456,2273,2274,2277,2279,2282,2284,2286,2288,2290,2292,2295],{"class":458,"line":1271},[456,2275,2276],{"class":488},"    apiPolicies ",[456,2278,887],{"class":626},[456,2280,2281],{"class":488}," apipolicy",[456,2283,402],{"class":626},[456,2285,2243],{"class":508},[456,2287,947],{"class":626},[456,2289,2269],{"class":488},[456,2291,402],{"class":626},[456,2293,2294],{"class":508},"Orders",[456,2296,2297],{"class":626},"())\n",[456,2299,2300,2303,2305,2308,2310,2312,2314,2316,2319,2321],{"class":458,"line":1278},[456,2301,2302],{"class":488},"    apiGroup ",[456,2304,887],{"class":626},[456,2306,2307],{"class":488}," router",[456,2309,402],{"class":626},[456,2311,1042],{"class":508},[456,2313,947],{"class":626},[456,2315,1047],{"class":626},[456,2317,2318],{"class":466},"\u002Fshop",[456,2320,1047],{"class":626},[456,2322,858],{"class":626},[456,2324,2325,2328,2330,2333,2335,2338,2340,2343,2345,2348,2350,2353,2355,2358,2361,2363,2366],{"class":458,"line":1284},[456,2326,2327],{"class":488},"    shopapigen",[456,2329,402],{"class":626},[456,2331,2332],{"class":508},"RegisterHandlersWithOptions",[456,2334,947],{"class":626},[456,2336,2337],{"class":488},"apiGroup",[456,2339,953],{"class":626},[456,2341,2342],{"class":488}," shopapigen",[456,2344,402],{"class":626},[456,2346,2347],{"class":508},"NewStrictHandler",[456,2349,947],{"class":626},[456,2351,2352],{"class":488},"apiHandler",[456,2354,953],{"class":626},[456,2356,2357],{"class":626}," []",[456,2359,2360],{"class":462},"shopapigen",[456,2362,402],{"class":626},[456,2364,2365],{"class":462},"StrictMiddlewareFunc",[456,2367,1072],{"class":626},[456,2369,2370,2373,2375,2378,2380,2382,2384,2387,2390,2393,2395,2397,2399,2402,2404,2406,2408,2411],{"class":458,"line":1301},[456,2371,2372],{"class":488},"        kitpolicy",[456,2374,402],{"class":626},[456,2376,2377],{"class":508},"FiberEnforcer",[456,2379,898],{"class":626},[456,2381,2360],{"class":462},[456,2383,402],{"class":626},[456,2385,2386],{"class":462},"StrictHandlerFunc",[456,2388,2389],{"class":626},"](",[456,2391,2392],{"class":488},"apiPolicies",[456,2394,953],{"class":626},[456,2396,2342],{"class":488},[456,2398,402],{"class":626},[456,2400,2401],{"class":488},"PermissionByOperation",[456,2403,953],{"class":626},[456,2405,2342],{"class":488},[456,2407,402],{"class":626},[456,2409,2410],{"class":488},"PolicyByOperation",[456,2412,1097],{"class":626},[456,2414,2415,2418,2420,2422,2425],{"class":458,"line":1319},[456,2416,2417],{"class":626},"    }),",[456,2419,2342],{"class":462},[456,2421,402],{"class":626},[456,2423,2424],{"class":462},"FiberServerOptions",[456,2426,2427],{"class":626},"{})\n",[456,2429,2430],{"class":458,"line":1325},[456,2431,1328],{"class":626},[456,2433,2434],{"class":458,"line":1874},[456,2435,519],{"emptyLinePlaceholder":518},[456,2437,2438,2440,2443,2445,2447,2449,2451,2453,2455,2457,2459,2461],{"class":458,"line":1880},[456,2439,869],{"class":626},[456,2441,2442],{"class":508}," RegisterAdmin",[456,2444,947],{"class":626},[456,2446,2210],{"class":1005},[456,2448,2213],{"class":462},[456,2450,402],{"class":626},[456,2452,2218],{"class":462},[456,2454,953],{"class":626},[456,2456,1185],{"class":1005},[456,2458,2125],{"class":462},[456,2460,1020],{"class":626},[456,2462,878],{"class":626},[456,2464,2465,2468,2470,2473,2475,2477,2479,2481],{"class":458,"line":1893},[456,2466,2467],{"class":488},"    adminSvc ",[456,2469,887],{"class":626},[456,2471,2472],{"class":488}," adminservice",[456,2474,402],{"class":626},[456,2476,2243],{"class":508},[456,2478,947],{"class":626},[456,2480,2248],{"class":488},[456,2482,858],{"class":626},[456,2484,2485,2488,2490,2493,2495,2497,2499,2502],{"class":458,"line":1908},[456,2486,2487],{"class":488},"    adminHandler ",[456,2489,887],{"class":626},[456,2491,2492],{"class":488}," adminhttp",[456,2494,402],{"class":626},[456,2496,2243],{"class":508},[456,2498,947],{"class":626},[456,2500,2501],{"class":488},"adminSvc",[456,2503,858],{"class":626},[456,2505,2506,2509,2511,2514,2516,2518],{"class":458,"line":1913},[456,2507,2508],{"class":488},"    adminPolicies ",[456,2510,887],{"class":626},[456,2512,2513],{"class":488}," adminpolicy",[456,2515,402],{"class":626},[456,2517,2243],{"class":508},[456,2519,928],{"class":626},[456,2521,2523,2526,2528,2530,2532,2534,2536,2538,2541,2543],{"class":458,"line":2522},46,[456,2524,2525],{"class":488},"    adminGroup ",[456,2527,887],{"class":626},[456,2529,2307],{"class":488},[456,2531,402],{"class":626},[456,2533,1042],{"class":508},[456,2535,947],{"class":626},[456,2537,1047],{"class":626},[456,2539,2540],{"class":466},"\u002Fadmin\u002Fshop",[456,2542,1047],{"class":626},[456,2544,858],{"class":626},[456,2546,2548,2551,2553,2556,2558,2560,2562,2565,2567,2569,2571,2574,2577,2580,2582,2585,2587,2589,2591,2593],{"class":458,"line":2547},47,[456,2549,2550],{"class":488},"    adminGroup",[456,2552,402],{"class":626},[456,2554,2555],{"class":508},"Use",[456,2557,947],{"class":626},[456,2559,2178],{"class":488},[456,2561,402],{"class":626},[456,2563,2564],{"class":508},"Middleware",[456,2566,947],{"class":626},[456,2568,2248],{"class":488},[456,2570,402],{"class":626},[456,2572,2573],{"class":488},"Auth",[456,2575,2576],{"class":626},"),",[456,2578,2579],{"class":488}," rbac",[456,2581,402],{"class":626},[456,2583,2584],{"class":508},"RequireRole",[456,2586,947],{"class":626},[456,2588,1047],{"class":626},[456,2590,391],{"class":466},[456,2592,1047],{"class":626},[456,2594,2595],{"class":626},"))\n",[456,2597,2599,2602,2604,2606,2608,2611,2613,2616,2618,2620,2622,2625,2627,2629,2632,2634,2636],{"class":458,"line":2598},48,[456,2600,2601],{"class":488},"    shopadmingen",[456,2603,402],{"class":626},[456,2605,2332],{"class":508},[456,2607,947],{"class":626},[456,2609,2610],{"class":488},"adminGroup",[456,2612,953],{"class":626},[456,2614,2615],{"class":488}," shopadmingen",[456,2617,402],{"class":626},[456,2619,2347],{"class":508},[456,2621,947],{"class":626},[456,2623,2624],{"class":488},"adminHandler",[456,2626,953],{"class":626},[456,2628,2357],{"class":626},[456,2630,2631],{"class":462},"shopadmingen",[456,2633,402],{"class":626},[456,2635,2365],{"class":462},[456,2637,1072],{"class":626},[456,2639,2641,2643,2645,2647,2649,2651,2653,2655,2657,2660,2662,2664,2666,2668,2670,2672,2674,2676],{"class":458,"line":2640},49,[456,2642,2372],{"class":488},[456,2644,402],{"class":626},[456,2646,2377],{"class":508},[456,2648,898],{"class":626},[456,2650,2631],{"class":462},[456,2652,402],{"class":626},[456,2654,2386],{"class":462},[456,2656,2389],{"class":626},[456,2658,2659],{"class":488},"adminPolicies",[456,2661,953],{"class":626},[456,2663,2615],{"class":488},[456,2665,402],{"class":626},[456,2667,2401],{"class":488},[456,2669,953],{"class":626},[456,2671,2615],{"class":488},[456,2673,402],{"class":626},[456,2675,2410],{"class":488},[456,2677,1097],{"class":626},[456,2679,2681,2683,2685,2687,2689],{"class":458,"line":2680},50,[456,2682,2417],{"class":626},[456,2684,2615],{"class":462},[456,2686,402],{"class":626},[456,2688,2424],{"class":462},[456,2690,2427],{"class":626},[456,2692,2694],{"class":458,"line":2693},51,[456,2695,1328],{"class":626},[447,2697,2700],{"className":731,"code":2698,"filename":2699,"language":463,"meta":452,"style":452},"package listeners\n\nimport (\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fqueue\"\n    \u002F\u002F gpsystem:worker-imports\n)\n\nfunc Register(reg *events.Registry, deps shop.Dependencies) {\n    events.Listen(reg, \"sendOrderConfirmation\", sendOrderConfirmation(deps), queue.OnQueue(\"mail\"))\n    \u002F\u002F gpsystem:listeners\n}\n","internal\u002Fmodules\u002Fshop\u002Flisteners\u002Fregister.go",[371,2701,2702,2709,2713,2719,2727,2731,2739,2748,2753,2757,2761,2794,2845,2850],{"__ignoreMap":452},[456,2703,2704,2706],{"class":458,"line":459},[456,2705,739],{"class":626},[456,2707,2708],{"class":462}," listeners\n",[456,2710,2711],{"class":458,"line":492},[456,2712,519],{"emptyLinePlaceholder":518},[456,2714,2715,2717],{"class":458,"line":505},[456,2716,752],{"class":751},[456,2718,755],{"class":626},[456,2720,2721,2723,2725],{"class":458,"line":515},[456,2722,760],{"class":626},[456,2724,840],{"class":462},[456,2726,633],{"class":626},[456,2728,2729],{"class":458,"line":522},[456,2730,519],{"emptyLinePlaceholder":518},[456,2732,2733,2735,2737],{"class":458,"line":541},[456,2734,760],{"class":626},[456,2736,1393],{"class":462},[456,2738,633],{"class":626},[456,2740,2741,2743,2746],{"class":458,"line":560},[456,2742,760],{"class":626},[456,2744,2745],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fqueue",[456,2747,633],{"class":626},[456,2749,2750],{"class":458,"line":578},[456,2751,2752],{"class":501},"    \u002F\u002F gpsystem:worker-imports\n",[456,2754,2755],{"class":458,"line":605},[456,2756,858],{"class":626},[456,2758,2759],{"class":458,"line":636},[456,2760,519],{"emptyLinePlaceholder":518},[456,2762,2763,2765,2768,2770,2772,2774,2776,2778,2780,2782,2784,2786,2788,2790,2792],{"class":458,"line":653},[456,2764,869],{"class":626},[456,2766,2767],{"class":508}," Register",[456,2769,947],{"class":626},[456,2771,1627],{"class":1005},[456,2773,1009],{"class":626},[456,2775,1632],{"class":462},[456,2777,402],{"class":626},[456,2779,1637],{"class":462},[456,2781,953],{"class":626},[456,2783,1185],{"class":1005},[456,2785,479],{"class":462},[456,2787,402],{"class":626},[456,2789,1069],{"class":462},[456,2791,1020],{"class":626},[456,2793,878],{"class":626},[456,2795,2796,2799,2801,2804,2806,2808,2810,2812,2814,2816,2818,2820,2822,2824,2826,2829,2831,2834,2836,2838,2841,2843],{"class":458,"line":658},[456,2797,2798],{"class":488},"    events",[456,2800,402],{"class":626},[456,2802,2803],{"class":508},"Listen",[456,2805,947],{"class":626},[456,2807,1627],{"class":488},[456,2809,953],{"class":626},[456,2811,627],{"class":626},[456,2813,421],{"class":466},[456,2815,1047],{"class":626},[456,2817,953],{"class":626},[456,2819,596],{"class":508},[456,2821,947],{"class":626},[456,2823,2248],{"class":488},[456,2825,2576],{"class":626},[456,2827,2828],{"class":488}," queue",[456,2830,402],{"class":626},[456,2832,2833],{"class":508},"OnQueue",[456,2835,947],{"class":626},[456,2837,1047],{"class":626},[456,2839,2840],{"class":466},"mail",[456,2842,1047],{"class":626},[456,2844,2595],{"class":626},[456,2846,2847],{"class":458,"line":830},[456,2848,2849],{"class":501},"    \u002F\u002F gpsystem:listeners\n",[456,2851,2852],{"class":458,"line":835},[456,2853,1328],{"class":626},[447,2855,2858],{"className":731,"code":2856,"filename":2857,"language":463,"meta":452,"style":452},"package jobs\n\nimport (\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fscheduler\"\n    \u002F\u002F gpsystem:job-imports\n)\n\nfunc Register(sched *scheduler.Schedule, deps shop.Dependencies) {\n    sched.Job(\"shop.nightlySalesReport\", \"0 3 * * *\", nightlySalesReport(deps))\n    \u002F\u002F gpsystem:jobs\n}\n","internal\u002Fmodules\u002Fshop\u002Fjobs\u002Fregister.go",[371,2859,2860,2867,2871,2877,2885,2889,2897,2902,2906,2910,2942,2979,2984],{"__ignoreMap":452},[456,2861,2862,2864],{"class":458,"line":459},[456,2863,739],{"class":626},[456,2865,2866],{"class":462}," jobs\n",[456,2868,2869],{"class":458,"line":492},[456,2870,519],{"emptyLinePlaceholder":518},[456,2872,2873,2875],{"class":458,"line":505},[456,2874,752],{"class":751},[456,2876,755],{"class":626},[456,2878,2879,2881,2883],{"class":458,"line":515},[456,2880,760],{"class":626},[456,2882,840],{"class":462},[456,2884,633],{"class":626},[456,2886,2887],{"class":458,"line":522},[456,2888,519],{"emptyLinePlaceholder":518},[456,2890,2891,2893,2895],{"class":458,"line":541},[456,2892,760],{"class":626},[456,2894,1410],{"class":462},[456,2896,633],{"class":626},[456,2898,2899],{"class":458,"line":560},[456,2900,2901],{"class":501},"    \u002F\u002F gpsystem:job-imports\n",[456,2903,2904],{"class":458,"line":578},[456,2905,858],{"class":626},[456,2907,2908],{"class":458,"line":605},[456,2909,519],{"emptyLinePlaceholder":518},[456,2911,2912,2914,2916,2918,2920,2922,2924,2926,2928,2930,2932,2934,2936,2938,2940],{"class":458,"line":636},[456,2913,869],{"class":626},[456,2915,2767],{"class":508},[456,2917,947],{"class":626},[456,2919,1782],{"class":1005},[456,2921,1009],{"class":626},[456,2923,1647],{"class":462},[456,2925,402],{"class":626},[456,2927,1652],{"class":462},[456,2929,953],{"class":626},[456,2931,1185],{"class":1005},[456,2933,479],{"class":462},[456,2935,402],{"class":626},[456,2937,1069],{"class":462},[456,2939,1020],{"class":626},[456,2941,878],{"class":626},[456,2943,2944,2947,2949,2952,2954,2956,2959,2961,2963,2965,2967,2969,2971,2973,2975,2977],{"class":458,"line":653},[456,2945,2946],{"class":488},"    sched",[456,2948,402],{"class":626},[456,2950,2951],{"class":508},"Job",[456,2953,947],{"class":626},[456,2955,1047],{"class":626},[456,2957,2958],{"class":466},"shop.nightlySalesReport",[456,2960,1047],{"class":626},[456,2962,953],{"class":626},[456,2964,627],{"class":626},[456,2966,630],{"class":466},[456,2968,1047],{"class":626},[456,2970,953],{"class":626},[456,2972,620],{"class":508},[456,2974,947],{"class":626},[456,2976,2248],{"class":488},[456,2978,2595],{"class":626},[456,2980,2981],{"class":458,"line":658},[456,2982,2983],{"class":501},"    \u002F\u002F gpsystem:jobs\n",[456,2985,2986],{"class":458,"line":830},[456,2987,1328],{"class":626},[447,2989,2992],{"className":731,"code":2990,"filename":2991,"language":463,"meta":452,"style":452},"package events\n\ntype OrderPlaced struct {\n    OrderID string `json:\"orderId\"`\n    Email   string `json:\"email\"`\n}\n\nfunc (OrderPlaced) EventName() string { return \"shop.orderPlaced\" }\n","internal\u002Fmodules\u002Fshop\u002Fevents\u002Forder_placed.go",[371,2993,2994,3001,3005,3016,3033,3047,3051,3055],{"__ignoreMap":452},[456,2995,2996,2998],{"class":458,"line":459},[456,2997,739],{"class":626},[456,2999,3000],{"class":462}," events\n",[456,3002,3003],{"class":458,"line":492},[456,3004,519],{"emptyLinePlaceholder":518},[456,3006,3007,3009,3012,3014],{"class":458,"line":505},[456,3008,2122],{"class":626},[456,3010,3011],{"class":462}," OrderPlaced",[456,3013,2128],{"class":626},[456,3015,878],{"class":626},[456,3017,3018,3021,3024,3027,3030],{"class":458,"line":515},[456,3019,3020],{"class":488},"    OrderID ",[456,3022,3023],{"class":1023},"string",[456,3025,3026],{"class":626}," `",[456,3028,3029],{"class":466},"json:\"orderId\"",[456,3031,3032],{"class":626},"`\n",[456,3034,3035,3038,3040,3042,3045],{"class":458,"line":522},[456,3036,3037],{"class":488},"    Email   ",[456,3039,3023],{"class":1023},[456,3041,3026],{"class":626},[456,3043,3044],{"class":466},"json:\"email\"",[456,3046,3032],{"class":626},[456,3048,3049],{"class":458,"line":541},[456,3050,1328],{"class":626},[456,3052,3053],{"class":458,"line":560},[456,3054,519],{"emptyLinePlaceholder":518},[456,3056,3057,3059,3062,3065,3067,3070,3072,3075,3078,3081,3083,3086,3088],{"class":458,"line":578},[456,3058,869],{"class":626},[456,3060,3061],{"class":626}," (",[456,3063,3064],{"class":462},"OrderPlaced",[456,3066,1020],{"class":626},[456,3068,3069],{"class":508}," EventName",[456,3071,875],{"class":626},[456,3073,3074],{"class":1023}," string",[456,3076,3077],{"class":626}," {",[456,3079,3080],{"class":751}," return",[456,3082,627],{"class":626},[456,3084,3085],{"class":466},"shop.orderPlaced",[456,3087,1047],{"class":626},[456,3089,3090],{"class":626}," }\n",[447,3092,3095],{"className":731,"code":3093,"filename":3094,"language":463,"meta":452,"style":452},"package listeners\n\nimport (\n    \"context\"\n    \"embed\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fmail\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fmail\u002Fmjml\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n    shopevents \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fevents\"\n)\n\n\u002F\u002Fgo:embed templates\nvar templates embed.FS\n\nfunc sendOrderConfirmation(deps shop.Dependencies) func(context.Context, shopevents.OrderPlaced) error {\n    return func(ctx context.Context, ev shopevents.OrderPlaced) error {\n        msg := mail.NewMessage().\n            WithTo(ev.Email).\n            WithSubject(\"Your order confirmation, order \"+ev.OrderID).\n            WithBody(mjml.Template(templates, \"templates\u002Forder_confirmation.mjml.tmpl\",\n                map[string]any{\"OrderID\": ev.OrderID}).\n                WithTextTemplate(\"templates\u002Forder_confirmation.txt.tmpl\"))\n        return deps.Mailer.Send(ctx, msg)\n    }\n}\n","internal\u002Fmodules\u002Fshop\u002Flisteners\u002Fsend_order_confirmation.go",[371,3096,3097,3103,3107,3113,3121,3130,3134,3143,3152,3156,3164,3176,3180,3184,3189,3204,3208,3249,3281,3299,3316,3342,3374,3407,3423,3450,3454],{"__ignoreMap":452},[456,3098,3099,3101],{"class":458,"line":459},[456,3100,739],{"class":626},[456,3102,2708],{"class":462},[456,3104,3105],{"class":458,"line":492},[456,3106,519],{"emptyLinePlaceholder":518},[456,3108,3109,3111],{"class":458,"line":505},[456,3110,752],{"class":751},[456,3112,755],{"class":626},[456,3114,3115,3117,3119],{"class":458,"line":515},[456,3116,760],{"class":626},[456,3118,763],{"class":462},[456,3120,633],{"class":626},[456,3122,3123,3125,3128],{"class":458,"line":522},[456,3124,760],{"class":626},[456,3126,3127],{"class":462},"embed",[456,3129,633],{"class":626},[456,3131,3132],{"class":458,"line":541},[456,3133,519],{"emptyLinePlaceholder":518},[456,3135,3136,3138,3141],{"class":458,"line":560},[456,3137,760],{"class":626},[456,3139,3140],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fmail",[456,3142,633],{"class":626},[456,3144,3145,3147,3150],{"class":458,"line":578},[456,3146,760],{"class":626},[456,3148,3149],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fmail\u002Fmjml",[456,3151,633],{"class":626},[456,3153,3154],{"class":458,"line":605},[456,3155,519],{"emptyLinePlaceholder":518},[456,3157,3158,3160,3162],{"class":458,"line":636},[456,3159,760],{"class":626},[456,3161,840],{"class":462},[456,3163,633],{"class":626},[456,3165,3166,3169,3171,3174],{"class":458,"line":653},[456,3167,3168],{"class":488},"    shopevents ",[456,3170,1047],{"class":626},[456,3172,3173],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fevents",[456,3175,633],{"class":626},[456,3177,3178],{"class":458,"line":658},[456,3179,858],{"class":626},[456,3181,3182],{"class":458,"line":830},[456,3183,519],{"emptyLinePlaceholder":518},[456,3185,3186],{"class":458,"line":835},[456,3187,3188],{"class":501},"\u002F\u002Fgo:embed templates\n",[456,3190,3191,3194,3197,3199,3201],{"class":458,"line":845},[456,3192,3193],{"class":626},"var",[456,3195,3196],{"class":488}," templates ",[456,3198,3127],{"class":462},[456,3200,402],{"class":626},[456,3202,3203],{"class":462},"FS\n",[456,3205,3206],{"class":458,"line":855},[456,3207,519],{"emptyLinePlaceholder":518},[456,3209,3210,3212,3214,3216,3218,3220,3222,3224,3226,3228,3230,3232,3234,3236,3239,3241,3243,3245,3247],{"class":458,"line":861},[456,3211,869],{"class":626},[456,3213,596],{"class":508},[456,3215,947],{"class":626},[456,3217,2248],{"class":1005},[456,3219,479],{"class":462},[456,3221,402],{"class":626},[456,3223,1069],{"class":462},[456,3225,1020],{"class":626},[456,3227,1002],{"class":626},[456,3229,763],{"class":462},[456,3231,402],{"class":626},[456,3233,1249],{"class":462},[456,3235,953],{"class":626},[456,3237,3238],{"class":462}," shopevents",[456,3240,402],{"class":626},[456,3242,3064],{"class":462},[456,3244,1020],{"class":626},[456,3246,1024],{"class":1023},[456,3248,878],{"class":626},[456,3250,3251,3254,3256,3258,3260,3262,3264,3266,3269,3271,3273,3275,3277,3279],{"class":458,"line":866},[456,3252,3253],{"class":751},"    return",[456,3255,1002],{"class":626},[456,3257,950],{"class":1005},[456,3259,920],{"class":462},[456,3261,402],{"class":626},[456,3263,1249],{"class":462},[456,3265,953],{"class":626},[456,3267,3268],{"class":1005}," ev",[456,3270,3238],{"class":462},[456,3272,402],{"class":626},[456,3274,3064],{"class":462},[456,3276,1020],{"class":626},[456,3278,1024],{"class":1023},[456,3280,878],{"class":626},[456,3282,3283,3286,3288,3291,3293,3296],{"class":458,"line":881},[456,3284,3285],{"class":488},"        msg ",[456,3287,887],{"class":626},[456,3289,3290],{"class":488}," mail",[456,3292,402],{"class":626},[456,3294,3295],{"class":508},"NewMessage",[456,3297,3298],{"class":626},"().\n",[456,3300,3301,3304,3306,3309,3311,3313],{"class":458,"line":912},[456,3302,3303],{"class":508},"            WithTo",[456,3305,947],{"class":626},[456,3307,3308],{"class":488},"ev",[456,3310,402],{"class":626},[456,3312,252],{"class":488},[456,3314,3315],{"class":626},").\n",[456,3317,3318,3321,3323,3325,3328,3330,3333,3335,3337,3340],{"class":458,"line":931},[456,3319,3320],{"class":508},"            WithSubject",[456,3322,947],{"class":626},[456,3324,1047],{"class":626},[456,3326,3327],{"class":466},"Your order confirmation, order ",[456,3329,1047],{"class":626},[456,3331,3332],{"class":626},"+",[456,3334,3308],{"class":488},[456,3336,402],{"class":626},[456,3338,3339],{"class":488},"OrderID",[456,3341,3315],{"class":626},[456,3343,3344,3347,3349,3352,3354,3357,3359,3362,3364,3366,3369,3371],{"class":458,"line":966},[456,3345,3346],{"class":508},"            WithBody",[456,3348,947],{"class":626},[456,3350,3351],{"class":488},"mjml",[456,3353,402],{"class":626},[456,3355,3356],{"class":508},"Template",[456,3358,947],{"class":626},[456,3360,3361],{"class":488},"templates",[456,3363,953],{"class":626},[456,3365,627],{"class":626},[456,3367,3368],{"class":466},"templates\u002Forder_confirmation.mjml.tmpl",[456,3370,1047],{"class":626},[456,3372,3373],{"class":626},",\n",[456,3375,3376,3379,3381,3384,3387,3390,3392,3394,3396,3398,3400,3402,3404],{"class":458,"line":971},[456,3377,3378],{"class":626},"                map[",[456,3380,3023],{"class":1023},[456,3382,3383],{"class":626},"]",[456,3385,3386],{"class":462},"any",[456,3388,3389],{"class":626},"{",[456,3391,1047],{"class":626},[456,3393,3339],{"class":466},[456,3395,1047],{"class":626},[456,3397,1081],{"class":626},[456,3399,3268],{"class":488},[456,3401,402],{"class":626},[456,3403,3339],{"class":488},[456,3405,3406],{"class":626},"}).\n",[456,3408,3409,3412,3414,3416,3419,3421],{"class":458,"line":1029},[456,3410,3411],{"class":508},"                WithTextTemplate",[456,3413,947],{"class":626},[456,3415,1047],{"class":626},[456,3417,3418],{"class":466},"templates\u002Forder_confirmation.txt.tmpl",[456,3420,1047],{"class":626},[456,3422,2595],{"class":626},[456,3424,3425,3427,3429,3431,3434,3436,3439,3441,3443,3445,3448],{"class":458,"line":1057},[456,3426,1213],{"class":751},[456,3428,1185],{"class":488},[456,3430,402],{"class":626},[456,3432,3433],{"class":488},"Mailer",[456,3435,402],{"class":626},[456,3437,3438],{"class":508},"Send",[456,3440,947],{"class":626},[456,3442,950],{"class":488},[456,3444,953],{"class":626},[456,3446,3447],{"class":488}," msg",[456,3449,858],{"class":626},[456,3451,3452],{"class":458,"line":1075},[456,3453,1322],{"class":626},[456,3455,3456],{"class":458,"line":1100},[456,3457,1328],{"class":626},[447,3459,3462],{"className":731,"code":3460,"filename":3461,"language":463,"meta":452,"style":452},"package jobs\n\nimport (\n    \"context\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n)\n\nfunc nightlySalesReport(deps shop.Dependencies) func(context.Context) error {\n    return func(ctx context.Context) error {\n        report, err := buildSalesReport(ctx, deps.DB)\n        if err != nil {\n            return err\n        }\n        return deps.Mailer.Send(ctx, salesReportMessage(report))\n    }\n}\n","internal\u002Fmodules\u002Fshop\u002Fjobs\u002Fnightly_sales_report.go",[371,3463,3464,3470,3474,3480,3488,3492,3500,3504,3508,3540,3560,3588,3601,3608,3612,3642,3646],{"__ignoreMap":452},[456,3465,3466,3468],{"class":458,"line":459},[456,3467,739],{"class":626},[456,3469,2866],{"class":462},[456,3471,3472],{"class":458,"line":492},[456,3473,519],{"emptyLinePlaceholder":518},[456,3475,3476,3478],{"class":458,"line":505},[456,3477,752],{"class":751},[456,3479,755],{"class":626},[456,3481,3482,3484,3486],{"class":458,"line":515},[456,3483,760],{"class":626},[456,3485,763],{"class":462},[456,3487,633],{"class":626},[456,3489,3490],{"class":458,"line":522},[456,3491,519],{"emptyLinePlaceholder":518},[456,3493,3494,3496,3498],{"class":458,"line":541},[456,3495,760],{"class":626},[456,3497,840],{"class":462},[456,3499,633],{"class":626},[456,3501,3502],{"class":458,"line":560},[456,3503,858],{"class":626},[456,3505,3506],{"class":458,"line":578},[456,3507,519],{"emptyLinePlaceholder":518},[456,3509,3510,3512,3514,3516,3518,3520,3522,3524,3526,3528,3530,3532,3534,3536,3538],{"class":458,"line":605},[456,3511,869],{"class":626},[456,3513,620],{"class":508},[456,3515,947],{"class":626},[456,3517,2248],{"class":1005},[456,3519,479],{"class":462},[456,3521,402],{"class":626},[456,3523,1069],{"class":462},[456,3525,1020],{"class":626},[456,3527,1002],{"class":626},[456,3529,763],{"class":462},[456,3531,402],{"class":626},[456,3533,1249],{"class":462},[456,3535,1020],{"class":626},[456,3537,1024],{"class":1023},[456,3539,878],{"class":626},[456,3541,3542,3544,3546,3548,3550,3552,3554,3556,3558],{"class":458,"line":636},[456,3543,3253],{"class":751},[456,3545,1002],{"class":626},[456,3547,950],{"class":1005},[456,3549,920],{"class":462},[456,3551,402],{"class":626},[456,3553,1249],{"class":462},[456,3555,1020],{"class":626},[456,3557,1024],{"class":1023},[456,3559,878],{"class":626},[456,3561,3562,3565,3567,3569,3571,3574,3576,3578,3580,3582,3584,3586],{"class":458,"line":653},[456,3563,3564],{"class":488},"        report",[456,3566,953],{"class":626},[456,3568,1290],{"class":488},[456,3570,887],{"class":626},[456,3572,3573],{"class":508}," buildSalesReport",[456,3575,947],{"class":626},[456,3577,950],{"class":488},[456,3579,953],{"class":626},[456,3581,1185],{"class":488},[456,3583,402],{"class":626},[456,3585,961],{"class":488},[456,3587,858],{"class":626},[456,3589,3590,3593,3595,3597,3599],{"class":458,"line":658},[456,3591,3592],{"class":751},"        if",[456,3594,1290],{"class":488},[456,3596,1293],{"class":626},[456,3598,1296],{"class":626},[456,3600,878],{"class":626},[456,3602,3603,3605],{"class":458,"line":830},[456,3604,1864],{"class":751},[456,3606,3607],{"class":488}," err\n",[456,3609,3610],{"class":458,"line":835},[456,3611,1165],{"class":626},[456,3613,3614,3616,3618,3620,3622,3624,3626,3628,3630,3632,3635,3637,3640],{"class":458,"line":845},[456,3615,1213],{"class":751},[456,3617,1185],{"class":488},[456,3619,402],{"class":626},[456,3621,3433],{"class":488},[456,3623,402],{"class":626},[456,3625,3438],{"class":508},[456,3627,947],{"class":626},[456,3629,950],{"class":488},[456,3631,953],{"class":626},[456,3633,3634],{"class":508}," salesReportMessage",[456,3636,947],{"class":626},[456,3638,3639],{"class":488},"report",[456,3641,2595],{"class":626},[456,3643,3644],{"class":458,"line":855},[456,3645,1322],{"class":626},[456,3647,3648],{"class":458,"line":861},[456,3649,1328],{"class":626},[447,3651,3654],{"className":731,"code":3652,"filename":3653,"language":463,"meta":452,"style":452},"package http\n\nimport (\n    \"context\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fservice\"\n)\n\ntype Handler struct {\n    svc *service.Service\n}\n\nfunc New(svc *service.Service) *Handler {\n    return &Handler{svc: svc}\n}\n\nfunc (h *Handler) PlaceOrder(ctx context.Context, req gen.PlaceOrderRequest) (gen.PlaceOrderResponse, error) {\n    if err := h.svc.PlaceOrder(ctx, toPlaceOrder(req)); err != nil {\n        return nil, err\n    }\n    return gen.PlaceOrder201Response{}, nil\n}\n\nfunc (h *Handler) ListProducts(ctx context.Context, req gen.ListProductsRequest) (gen.ListProductsResponse, error) {\n    page, err := h.svc.ListProducts(ctx, req.Params.Cursor, req.Params.Limit)\n    if err != nil {\n        return nil, service.ErrListProducts.Wrap(err, \"api: list products\")\n    }\n    return gen.ListProducts200JSONResponse(page), nil\n}\n","internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fhandler.go",[371,3655,3656,3663,3667,3673,3681,3685,3693,3701,3705,3709,3720,3735,3739,3743,3773,3793,3797,3801,3862,3906,3915,3919,3935,3939,3943,4000,4055,4067,4101,4105,4125],{"__ignoreMap":452},[456,3657,3658,3660],{"class":458,"line":459},[456,3659,739],{"class":626},[456,3661,3662],{"class":462}," http\n",[456,3664,3665],{"class":458,"line":492},[456,3666,519],{"emptyLinePlaceholder":518},[456,3668,3669,3671],{"class":458,"line":505},[456,3670,752],{"class":751},[456,3672,755],{"class":626},[456,3674,3675,3677,3679],{"class":458,"line":515},[456,3676,760],{"class":626},[456,3678,763],{"class":462},[456,3680,633],{"class":626},[456,3682,3683],{"class":458,"line":522},[456,3684,519],{"emptyLinePlaceholder":518},[456,3686,3687,3689,3691],{"class":458,"line":541},[456,3688,760],{"class":626},[456,3690,2078],{"class":462},[456,3692,633],{"class":626},[456,3694,3695,3697,3699],{"class":458,"line":560},[456,3696,760],{"class":626},[456,3698,2102],{"class":462},[456,3700,633],{"class":626},[456,3702,3703],{"class":458,"line":578},[456,3704,858],{"class":626},[456,3706,3707],{"class":458,"line":605},[456,3708,519],{"emptyLinePlaceholder":518},[456,3710,3711,3713,3716,3718],{"class":458,"line":636},[456,3712,2122],{"class":626},[456,3714,3715],{"class":462}," Handler",[456,3717,2128],{"class":626},[456,3719,878],{"class":626},[456,3721,3722,3725,3727,3730,3732],{"class":458,"line":653},[456,3723,3724],{"class":488},"    svc ",[456,3726,2138],{"class":626},[456,3728,3729],{"class":462},"service",[456,3731,402],{"class":626},[456,3733,3734],{"class":462},"Service\n",[456,3736,3737],{"class":458,"line":658},[456,3738,1328],{"class":626},[456,3740,3741],{"class":458,"line":830},[456,3742,519],{"emptyLinePlaceholder":518},[456,3744,3745,3747,3750,3752,3755,3757,3759,3761,3764,3766,3768,3771],{"class":458,"line":835},[456,3746,869],{"class":626},[456,3748,3749],{"class":508}," New",[456,3751,947],{"class":626},[456,3753,3754],{"class":1005},"svc",[456,3756,1009],{"class":626},[456,3758,3729],{"class":462},[456,3760,402],{"class":626},[456,3762,3763],{"class":462},"Service",[456,3765,1020],{"class":626},[456,3767,1009],{"class":626},[456,3769,3770],{"class":462},"Handler",[456,3772,878],{"class":626},[456,3774,3775,3777,3780,3782,3784,3786,3788,3791],{"class":458,"line":845},[456,3776,3253],{"class":751},[456,3778,3779],{"class":626}," &",[456,3781,3770],{"class":462},[456,3783,3389],{"class":626},[456,3785,3754],{"class":488},[456,3787,1081],{"class":626},[456,3789,3790],{"class":488}," svc",[456,3792,1328],{"class":626},[456,3794,3795],{"class":458,"line":855},[456,3796,1328],{"class":626},[456,3798,3799],{"class":458,"line":861},[456,3800,519],{"emptyLinePlaceholder":518},[456,3802,3803,3805,3807,3810,3812,3814,3816,3819,3821,3823,3825,3827,3829,3831,3834,3837,3839,3842,3844,3846,3849,3851,3854,3856,3858,3860],{"class":458,"line":866},[456,3804,869],{"class":626},[456,3806,3061],{"class":626},[456,3808,3809],{"class":1005},"h ",[456,3811,2138],{"class":626},[456,3813,3770],{"class":462},[456,3815,1020],{"class":626},[456,3817,3818],{"class":508}," PlaceOrder",[456,3820,947],{"class":626},[456,3822,950],{"class":1005},[456,3824,920],{"class":462},[456,3826,402],{"class":626},[456,3828,1249],{"class":462},[456,3830,953],{"class":626},[456,3832,3833],{"class":1005}," req",[456,3835,3836],{"class":462}," gen",[456,3838,402],{"class":626},[456,3840,3841],{"class":462},"PlaceOrderRequest",[456,3843,1020],{"class":626},[456,3845,3061],{"class":626},[456,3847,3848],{"class":462},"gen",[456,3850,402],{"class":626},[456,3852,3853],{"class":462},"PlaceOrderResponse",[456,3855,953],{"class":626},[456,3857,1024],{"class":1023},[456,3859,1020],{"class":626},[456,3861,878],{"class":626},[456,3863,3864,3866,3868,3870,3873,3875,3877,3879,3881,3883,3885,3887,3890,3892,3895,3898,3900,3902,3904],{"class":458,"line":881},[456,3865,1287],{"class":751},[456,3867,1290],{"class":488},[456,3869,887],{"class":626},[456,3871,3872],{"class":488}," h",[456,3874,402],{"class":626},[456,3876,3754],{"class":488},[456,3878,402],{"class":626},[456,3880,383],{"class":508},[456,3882,947],{"class":626},[456,3884,950],{"class":488},[456,3886,953],{"class":626},[456,3888,3889],{"class":508}," toPlaceOrder",[456,3891,947],{"class":626},[456,3893,3894],{"class":488},"req",[456,3896,3897],{"class":626},"));",[456,3899,1290],{"class":488},[456,3901,1293],{"class":626},[456,3903,1296],{"class":626},[456,3905,878],{"class":626},[456,3907,3908,3910,3913],{"class":458,"line":912},[456,3909,1213],{"class":751},[456,3911,3912],{"class":626}," nil,",[456,3914,3607],{"class":488},[456,3916,3917],{"class":458,"line":931},[456,3918,1322],{"class":626},[456,3920,3921,3923,3925,3927,3930,3933],{"class":458,"line":966},[456,3922,3253],{"class":751},[456,3924,3836],{"class":462},[456,3926,402],{"class":626},[456,3928,3929],{"class":462},"PlaceOrder201Response",[456,3931,3932],{"class":626},"{},",[456,3934,1216],{"class":626},[456,3936,3937],{"class":458,"line":971},[456,3938,1328],{"class":626},[456,3940,3941],{"class":458,"line":1029},[456,3942,519],{"emptyLinePlaceholder":518},[456,3944,3945,3947,3949,3951,3953,3955,3957,3960,3962,3964,3966,3968,3970,3972,3974,3976,3978,3981,3983,3985,3987,3989,3992,3994,3996,3998],{"class":458,"line":1057},[456,3946,869],{"class":626},[456,3948,3061],{"class":626},[456,3950,3809],{"class":1005},[456,3952,2138],{"class":626},[456,3954,3770],{"class":462},[456,3956,1020],{"class":626},[456,3958,3959],{"class":508}," ListProducts",[456,3961,947],{"class":626},[456,3963,950],{"class":1005},[456,3965,920],{"class":462},[456,3967,402],{"class":626},[456,3969,1249],{"class":462},[456,3971,953],{"class":626},[456,3973,3833],{"class":1005},[456,3975,3836],{"class":462},[456,3977,402],{"class":626},[456,3979,3980],{"class":462},"ListProductsRequest",[456,3982,1020],{"class":626},[456,3984,3061],{"class":626},[456,3986,3848],{"class":462},[456,3988,402],{"class":626},[456,3990,3991],{"class":462},"ListProductsResponse",[456,3993,953],{"class":626},[456,3995,1024],{"class":1023},[456,3997,1020],{"class":626},[456,3999,878],{"class":626},[456,4001,4002,4005,4007,4009,4011,4013,4015,4017,4019,4022,4024,4026,4028,4030,4032,4035,4037,4040,4042,4044,4046,4048,4050,4053],{"class":458,"line":1075},[456,4003,4004],{"class":488},"    page",[456,4006,953],{"class":626},[456,4008,1290],{"class":488},[456,4010,887],{"class":626},[456,4012,3872],{"class":488},[456,4014,402],{"class":626},[456,4016,3754],{"class":488},[456,4018,402],{"class":626},[456,4020,4021],{"class":508},"ListProducts",[456,4023,947],{"class":626},[456,4025,950],{"class":488},[456,4027,953],{"class":626},[456,4029,3833],{"class":488},[456,4031,402],{"class":626},[456,4033,4034],{"class":488},"Params",[456,4036,402],{"class":626},[456,4038,4039],{"class":488},"Cursor",[456,4041,953],{"class":626},[456,4043,3833],{"class":488},[456,4045,402],{"class":626},[456,4047,4034],{"class":488},[456,4049,402],{"class":626},[456,4051,4052],{"class":488},"Limit",[456,4054,858],{"class":626},[456,4056,4057,4059,4061,4063,4065],{"class":458,"line":1100},[456,4058,1287],{"class":751},[456,4060,1290],{"class":488},[456,4062,1293],{"class":626},[456,4064,1296],{"class":626},[456,4066,878],{"class":626},[456,4068,4069,4071,4073,4076,4078,4081,4083,4086,4088,4090,4092,4094,4097,4099],{"class":458,"line":1121},[456,4070,1213],{"class":751},[456,4072,3912],{"class":626},[456,4074,4075],{"class":488}," service",[456,4077,402],{"class":626},[456,4079,4080],{"class":488},"ErrListProducts",[456,4082,402],{"class":626},[456,4084,4085],{"class":508},"Wrap",[456,4087,947],{"class":626},[456,4089,1314],{"class":488},[456,4091,953],{"class":626},[456,4093,627],{"class":626},[456,4095,4096],{"class":466},"api: list products",[456,4098,1047],{"class":626},[456,4100,858],{"class":626},[456,4102,4103],{"class":458,"line":1162},[456,4104,1322],{"class":626},[456,4106,4107,4109,4111,4113,4116,4118,4121,4123],{"class":458,"line":1168},[456,4108,3253],{"class":751},[456,4110,3836],{"class":488},[456,4112,402],{"class":626},[456,4114,4115],{"class":508},"ListProducts200JSONResponse",[456,4117,947],{"class":626},[456,4119,4120],{"class":488},"page",[456,4122,2576],{"class":626},[456,4124,1216],{"class":626},[456,4126,4127],{"class":458,"line":1190},[456,4128,1328],{"class":626},[447,4130,4133],{"className":731,"code":4131,"filename":4132,"language":463,"meta":452,"style":452},"package policy\n\nimport (\n    \"context\"\n\n    kitpolicy \"github.com\u002Fgp-system\u002Fgpsystem\u002Fpolicy\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Frbac\"\n\n    gen \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Frepository\"\n)\n\nfunc New(orders *repository.OrderRepo) *kitpolicy.Registry {\n    reg := kitpolicy.NewRegistry()\n    \u002F\u002F gpsystem:policies\n    reg.Register(\"orders.view\", func(ctx context.Context, id *rbac.Identity, req any) error {\n        if id.HasRole(\"admin\") {\n            return nil\n        }\n        r, ok := req.(gen.GetOrderRequest)\n        if !ok {\n            return kitpolicy.Deny(\"unexpected request type\")\n        }\n        order, err := orders.GetByID(ctx, r.OrderId)\n        if err != nil {\n            return err\n        }\n        if order.UserID != id.Subject {\n            return kitpolicy.Deny(\"You can only view your own orders.\")\n        }\n        return nil\n    })\n    reg.Register(\"orders.place\", func(ctx context.Context, id *rbac.Identity, req any) error {\n        r, ok := req.(gen.PlaceOrderRequest)\n        if !ok {\n            return kitpolicy.Deny(\"unexpected request type\")\n        }\n        if r.Body.CustomerId != id.Subject {\n            return kitpolicy.Deny(\"You can only place orders on your own behalf.\")\n        }\n        return nil\n    })\n    return reg\n}\n","internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy\u002Fpolicy.go",[371,4134,4135,4142,4146,4152,4160,4164,4174,4182,4186,4197,4206,4210,4214,4248,4265,4270,4328,4351,4357,4361,4387,4399,4421,4425,4460,4472,4478,4482,4505,4526,4530,4536,4541,4594,4616,4626,4646,4650,4676,4697,4701,4707,4711,4718],{"__ignoreMap":452},[456,4136,4137,4139],{"class":458,"line":459},[456,4138,739],{"class":626},[456,4140,4141],{"class":462}," policy\n",[456,4143,4144],{"class":458,"line":492},[456,4145,519],{"emptyLinePlaceholder":518},[456,4147,4148,4150],{"class":458,"line":505},[456,4149,752],{"class":751},[456,4151,755],{"class":626},[456,4153,4154,4156,4158],{"class":458,"line":515},[456,4155,760],{"class":626},[456,4157,763],{"class":462},[456,4159,633],{"class":626},[456,4161,4162],{"class":458,"line":522},[456,4163,519],{"emptyLinePlaceholder":518},[456,4165,4166,4168,4170,4172],{"class":458,"line":541},[456,4167,1988],{"class":488},[456,4169,1047],{"class":626},[456,4171,1993],{"class":462},[456,4173,633],{"class":626},[456,4175,4176,4178,4180],{"class":458,"line":560},[456,4177,760],{"class":626},[456,4179,2002],{"class":462},[456,4181,633],{"class":626},[456,4183,4184],{"class":458,"line":578},[456,4185,519],{"emptyLinePlaceholder":518},[456,4187,4188,4191,4193,4195],{"class":458,"line":605},[456,4189,4190],{"class":488},"    gen ",[456,4192,1047],{"class":626},[456,4194,2078],{"class":462},[456,4196,633],{"class":626},[456,4198,4199,4201,4204],{"class":458,"line":636},[456,4200,760],{"class":626},[456,4202,4203],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Frepository",[456,4205,633],{"class":626},[456,4207,4208],{"class":458,"line":653},[456,4209,858],{"class":626},[456,4211,4212],{"class":458,"line":658},[456,4213,519],{"emptyLinePlaceholder":518},[456,4215,4216,4218,4220,4222,4225,4227,4230,4232,4235,4237,4239,4242,4244,4246],{"class":458,"line":830},[456,4217,869],{"class":626},[456,4219,3749],{"class":508},[456,4221,947],{"class":626},[456,4223,4224],{"class":1005},"orders",[456,4226,1009],{"class":626},[456,4228,4229],{"class":462},"repository",[456,4231,402],{"class":626},[456,4233,4234],{"class":462},"OrderRepo",[456,4236,1020],{"class":626},[456,4238,1009],{"class":626},[456,4240,4241],{"class":462},"kitpolicy",[456,4243,402],{"class":626},[456,4245,1637],{"class":462},[456,4247,878],{"class":626},[456,4249,4250,4253,4255,4258,4260,4263],{"class":458,"line":835},[456,4251,4252],{"class":488},"    reg ",[456,4254,887],{"class":626},[456,4256,4257],{"class":488}," kitpolicy",[456,4259,402],{"class":626},[456,4261,4262],{"class":508},"NewRegistry",[456,4264,928],{"class":626},[456,4266,4267],{"class":458,"line":845},[456,4268,4269],{"class":501},"    \u002F\u002F gpsystem:policies\n",[456,4271,4272,4275,4277,4279,4281,4283,4286,4288,4290,4292,4294,4296,4298,4300,4302,4305,4307,4310,4312,4315,4317,4319,4322,4324,4326],{"class":458,"line":855},[456,4273,4274],{"class":488},"    reg",[456,4276,402],{"class":626},[456,4278,1757],{"class":508},[456,4280,947],{"class":626},[456,4282,1047],{"class":626},[456,4284,4285],{"class":466},"orders.view",[456,4287,1047],{"class":626},[456,4289,953],{"class":626},[456,4291,1002],{"class":626},[456,4293,950],{"class":1005},[456,4295,920],{"class":462},[456,4297,402],{"class":626},[456,4299,1249],{"class":462},[456,4301,953],{"class":626},[456,4303,4304],{"class":1005}," id",[456,4306,1009],{"class":626},[456,4308,4309],{"class":462},"rbac",[456,4311,402],{"class":626},[456,4313,4314],{"class":462},"Identity",[456,4316,953],{"class":626},[456,4318,3833],{"class":1005},[456,4320,4321],{"class":462}," any",[456,4323,1020],{"class":626},[456,4325,1024],{"class":1023},[456,4327,878],{"class":626},[456,4329,4330,4332,4334,4336,4339,4341,4343,4345,4347,4349],{"class":458,"line":861},[456,4331,3592],{"class":751},[456,4333,4304],{"class":488},[456,4335,402],{"class":626},[456,4337,4338],{"class":508},"HasRole",[456,4340,947],{"class":626},[456,4342,1047],{"class":626},[456,4344,391],{"class":466},[456,4346,1047],{"class":626},[456,4348,1020],{"class":626},[456,4350,878],{"class":626},[456,4352,4353,4355],{"class":458,"line":866},[456,4354,1864],{"class":751},[456,4356,1216],{"class":626},[456,4358,4359],{"class":458,"line":881},[456,4360,1165],{"class":626},[456,4362,4363,4366,4368,4371,4373,4375,4378,4380,4382,4385],{"class":458,"line":912},[456,4364,4365],{"class":488},"        r",[456,4367,953],{"class":626},[456,4369,4370],{"class":488}," ok ",[456,4372,887],{"class":626},[456,4374,3833],{"class":488},[456,4376,4377],{"class":626},".(",[456,4379,3848],{"class":462},[456,4381,402],{"class":626},[456,4383,4384],{"class":462},"GetOrderRequest",[456,4386,858],{"class":626},[456,4388,4389,4391,4394,4397],{"class":458,"line":931},[456,4390,3592],{"class":751},[456,4392,4393],{"class":626}," !",[456,4395,4396],{"class":488},"ok ",[456,4398,1072],{"class":626},[456,4400,4401,4403,4405,4407,4410,4412,4414,4417,4419],{"class":458,"line":966},[456,4402,1864],{"class":751},[456,4404,4257],{"class":488},[456,4406,402],{"class":626},[456,4408,4409],{"class":508},"Deny",[456,4411,947],{"class":626},[456,4413,1047],{"class":626},[456,4415,4416],{"class":466},"unexpected request type",[456,4418,1047],{"class":626},[456,4420,858],{"class":626},[456,4422,4423],{"class":458,"line":971},[456,4424,1165],{"class":626},[456,4426,4427,4430,4432,4434,4436,4439,4441,4444,4446,4448,4450,4453,4455,4458],{"class":458,"line":1029},[456,4428,4429],{"class":488},"        order",[456,4431,953],{"class":626},[456,4433,1290],{"class":488},[456,4435,887],{"class":626},[456,4437,4438],{"class":488}," orders",[456,4440,402],{"class":626},[456,4442,4443],{"class":508},"GetByID",[456,4445,947],{"class":626},[456,4447,950],{"class":488},[456,4449,953],{"class":626},[456,4451,4452],{"class":488}," r",[456,4454,402],{"class":626},[456,4456,4457],{"class":488},"OrderId",[456,4459,858],{"class":626},[456,4461,4462,4464,4466,4468,4470],{"class":458,"line":1057},[456,4463,3592],{"class":751},[456,4465,1290],{"class":488},[456,4467,1293],{"class":626},[456,4469,1296],{"class":626},[456,4471,878],{"class":626},[456,4473,4474,4476],{"class":458,"line":1075},[456,4475,1864],{"class":751},[456,4477,3607],{"class":488},[456,4479,4480],{"class":458,"line":1100},[456,4481,1165],{"class":626},[456,4483,4484,4486,4489,4491,4494,4496,4498,4500,4503],{"class":458,"line":1121},[456,4485,3592],{"class":751},[456,4487,4488],{"class":488}," order",[456,4490,402],{"class":626},[456,4492,4493],{"class":488},"UserID ",[456,4495,1293],{"class":626},[456,4497,4304],{"class":488},[456,4499,402],{"class":626},[456,4501,4502],{"class":488},"Subject ",[456,4504,1072],{"class":626},[456,4506,4507,4509,4511,4513,4515,4517,4519,4522,4524],{"class":458,"line":1162},[456,4508,1864],{"class":751},[456,4510,4257],{"class":488},[456,4512,402],{"class":626},[456,4514,4409],{"class":508},[456,4516,947],{"class":626},[456,4518,1047],{"class":626},[456,4520,4521],{"class":466},"You can only view your own orders.",[456,4523,1047],{"class":626},[456,4525,858],{"class":626},[456,4527,4528],{"class":458,"line":1168},[456,4529,1165],{"class":626},[456,4531,4532,4534],{"class":458,"line":1190},[456,4533,1213],{"class":751},[456,4535,1216],{"class":626},[456,4537,4538],{"class":458,"line":1210},[456,4539,4540],{"class":626},"    })\n",[456,4542,4543,4545,4547,4549,4551,4553,4556,4558,4560,4562,4564,4566,4568,4570,4572,4574,4576,4578,4580,4582,4584,4586,4588,4590,4592],{"class":458,"line":1219},[456,4544,4274],{"class":488},[456,4546,402],{"class":626},[456,4548,1757],{"class":508},[456,4550,947],{"class":626},[456,4552,1047],{"class":626},[456,4554,4555],{"class":466},"orders.place",[456,4557,1047],{"class":626},[456,4559,953],{"class":626},[456,4561,1002],{"class":626},[456,4563,950],{"class":1005},[456,4565,920],{"class":462},[456,4567,402],{"class":626},[456,4569,1249],{"class":462},[456,4571,953],{"class":626},[456,4573,4304],{"class":1005},[456,4575,1009],{"class":626},[456,4577,4309],{"class":462},[456,4579,402],{"class":626},[456,4581,4314],{"class":462},[456,4583,953],{"class":626},[456,4585,3833],{"class":1005},[456,4587,4321],{"class":462},[456,4589,1020],{"class":626},[456,4591,1024],{"class":1023},[456,4593,878],{"class":626},[456,4595,4596,4598,4600,4602,4604,4606,4608,4610,4612,4614],{"class":458,"line":1258},[456,4597,4365],{"class":488},[456,4599,953],{"class":626},[456,4601,4370],{"class":488},[456,4603,887],{"class":626},[456,4605,3833],{"class":488},[456,4607,4377],{"class":626},[456,4609,3848],{"class":462},[456,4611,402],{"class":626},[456,4613,3841],{"class":462},[456,4615,858],{"class":626},[456,4617,4618,4620,4622,4624],{"class":458,"line":1271},[456,4619,3592],{"class":751},[456,4621,4393],{"class":626},[456,4623,4396],{"class":488},[456,4625,1072],{"class":626},[456,4627,4628,4630,4632,4634,4636,4638,4640,4642,4644],{"class":458,"line":1278},[456,4629,1864],{"class":751},[456,4631,4257],{"class":488},[456,4633,402],{"class":626},[456,4635,4409],{"class":508},[456,4637,947],{"class":626},[456,4639,1047],{"class":626},[456,4641,4416],{"class":466},[456,4643,1047],{"class":626},[456,4645,858],{"class":626},[456,4647,4648],{"class":458,"line":1284},[456,4649,1165],{"class":626},[456,4651,4652,4654,4656,4658,4661,4663,4666,4668,4670,4672,4674],{"class":458,"line":1301},[456,4653,3592],{"class":751},[456,4655,4452],{"class":488},[456,4657,402],{"class":626},[456,4659,4660],{"class":488},"Body",[456,4662,402],{"class":626},[456,4664,4665],{"class":488},"CustomerId ",[456,4667,1293],{"class":626},[456,4669,4304],{"class":488},[456,4671,402],{"class":626},[456,4673,4502],{"class":488},[456,4675,1072],{"class":626},[456,4677,4678,4680,4682,4684,4686,4688,4690,4693,4695],{"class":458,"line":1319},[456,4679,1864],{"class":751},[456,4681,4257],{"class":488},[456,4683,402],{"class":626},[456,4685,4409],{"class":508},[456,4687,947],{"class":626},[456,4689,1047],{"class":626},[456,4691,4692],{"class":466},"You can only place orders on your own behalf.",[456,4694,1047],{"class":626},[456,4696,858],{"class":626},[456,4698,4699],{"class":458,"line":1325},[456,4700,1165],{"class":626},[456,4702,4703,4705],{"class":458,"line":1874},[456,4704,1213],{"class":751},[456,4706,1216],{"class":626},[456,4708,4709],{"class":458,"line":1880},[456,4710,4540],{"class":626},[456,4712,4713,4715],{"class":458,"line":1893},[456,4714,3253],{"class":751},[456,4716,4717],{"class":488}," reg\n",[456,4719,4720],{"class":458,"line":1908},[456,4721,1328],{"class":626},[447,4723,4726],{"className":731,"code":4724,"filename":4725,"language":463,"meta":452,"style":452},"\u002F\u002F Package core holds the shop module's shared business logic: the ordering\n\u002F\u002F rule is written once, and every surface (api today, maybe a partner\n\u002F\u002F surface tomorrow) calls it from here. Import direction:\n\u002F\u002F http → service → core → repository.\npackage core\n\nimport (\n    \"context\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\"\n\n    shopevents \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fevents\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Frepository\"\n)\n\ntype PlaceOrderInput struct {\n    CustomerID string\n    ProductID  string\n    Qty        int\n    Email      string\n}\n\ntype Service struct {\n    orders     *repository.OrderRepo\n    products   *repository.Products\n    tx         dbx.Transactor\n    dispatcher events.Dispatcher\n}\n\nfunc New(orders *repository.OrderRepo, products *repository.Products, tx dbx.Transactor, dispatcher events.Dispatcher) *Service {\n    return &Service{orders: orders, products: products, tx: tx, dispatcher: dispatcher}\n}\n\nfunc (c *Service) PlaceOrder(ctx context.Context, in PlaceOrderInput) error {\n    return c.tx.WithinTransaction(ctx, func(ctx context.Context) error {\n        order, err := c.orders.Insert(ctx, in)\n        if err != nil {\n            return err\n        }\n        if err := c.products.DecrementStock(ctx, in.ProductID, in.Qty); err != nil {\n            return err\n        }\n        return c.dispatcher.Dispatch(ctx, shopevents.OrderPlaced{\n            OrderID: order.ID,\n            Email:   order.Email,\n        })\n    })\n}\n","internal\u002Fmodules\u002Fshop\u002Fcore\u002Fcore.go",[371,4727,4728,4733,4738,4743,4748,4755,4759,4765,4773,4777,4785,4793,4797,4807,4815,4819,4823,4834,4842,4849,4857,4864,4868,4872,4883,4897,4911,4922,4933,4937,4941,5007,5049,5053,5057,5097,5136,5167,5179,5185,5189,5242,5248,5252,5282,5298,5314,5319,5323],{"__ignoreMap":452},[456,4729,4730],{"class":458,"line":459},[456,4731,4732],{"class":501},"\u002F\u002F Package core holds the shop module's shared business logic: the ordering\n",[456,4734,4735],{"class":458,"line":492},[456,4736,4737],{"class":501},"\u002F\u002F rule is written once, and every surface (api today, maybe a partner\n",[456,4739,4740],{"class":458,"line":505},[456,4741,4742],{"class":501},"\u002F\u002F surface tomorrow) calls it from here. Import direction:\n",[456,4744,4745],{"class":458,"line":515},[456,4746,4747],{"class":501},"\u002F\u002F http → service → core → repository.\n",[456,4749,4750,4752],{"class":458,"line":522},[456,4751,739],{"class":626},[456,4753,4754],{"class":462}," core\n",[456,4756,4757],{"class":458,"line":541},[456,4758,519],{"emptyLinePlaceholder":518},[456,4760,4761,4763],{"class":458,"line":560},[456,4762,752],{"class":751},[456,4764,755],{"class":626},[456,4766,4767,4769,4771],{"class":458,"line":578},[456,4768,760],{"class":626},[456,4770,763],{"class":462},[456,4772,633],{"class":626},[456,4774,4775],{"class":458,"line":605},[456,4776,519],{"emptyLinePlaceholder":518},[456,4778,4779,4781,4783],{"class":458,"line":636},[456,4780,760],{"class":626},[456,4782,1965],{"class":462},[456,4784,633],{"class":626},[456,4786,4787,4789,4791],{"class":458,"line":653},[456,4788,760],{"class":626},[456,4790,1393],{"class":462},[456,4792,633],{"class":626},[456,4794,4795],{"class":458,"line":658},[456,4796,519],{"emptyLinePlaceholder":518},[456,4798,4799,4801,4803,4805],{"class":458,"line":830},[456,4800,3168],{"class":488},[456,4802,1047],{"class":626},[456,4804,3173],{"class":462},[456,4806,633],{"class":626},[456,4808,4809,4811,4813],{"class":458,"line":835},[456,4810,760],{"class":626},[456,4812,4203],{"class":462},[456,4814,633],{"class":626},[456,4816,4817],{"class":458,"line":845},[456,4818,858],{"class":626},[456,4820,4821],{"class":458,"line":855},[456,4822,519],{"emptyLinePlaceholder":518},[456,4824,4825,4827,4830,4832],{"class":458,"line":861},[456,4826,2122],{"class":626},[456,4828,4829],{"class":462}," PlaceOrderInput",[456,4831,2128],{"class":626},[456,4833,878],{"class":626},[456,4835,4836,4839],{"class":458,"line":866},[456,4837,4838],{"class":488},"    CustomerID ",[456,4840,4841],{"class":1023},"string\n",[456,4843,4844,4847],{"class":458,"line":881},[456,4845,4846],{"class":488},"    ProductID  ",[456,4848,4841],{"class":1023},[456,4850,4851,4854],{"class":458,"line":912},[456,4852,4853],{"class":488},"    Qty        ",[456,4855,4856],{"class":1023},"int\n",[456,4858,4859,4862],{"class":458,"line":931},[456,4860,4861],{"class":488},"    Email      ",[456,4863,4841],{"class":1023},[456,4865,4866],{"class":458,"line":966},[456,4867,1328],{"class":626},[456,4869,4870],{"class":458,"line":971},[456,4871,519],{"emptyLinePlaceholder":518},[456,4873,4874,4876,4879,4881],{"class":458,"line":1029},[456,4875,2122],{"class":626},[456,4877,4878],{"class":462}," Service",[456,4880,2128],{"class":626},[456,4882,878],{"class":626},[456,4884,4885,4888,4890,4892,4894],{"class":458,"line":1057},[456,4886,4887],{"class":488},"    orders     ",[456,4889,2138],{"class":626},[456,4891,4229],{"class":462},[456,4893,402],{"class":626},[456,4895,4896],{"class":462},"OrderRepo\n",[456,4898,4899,4902,4904,4906,4908],{"class":458,"line":1075},[456,4900,4901],{"class":488},"    products   ",[456,4903,2138],{"class":626},[456,4905,4229],{"class":462},[456,4907,402],{"class":626},[456,4909,4910],{"class":462},"Products\n",[456,4912,4913,4916,4918,4920],{"class":458,"line":1100},[456,4914,4915],{"class":488},"    tx         ",[456,4917,2153],{"class":462},[456,4919,402],{"class":626},[456,4921,2158],{"class":462},[456,4923,4924,4927,4929,4931],{"class":458,"line":1121},[456,4925,4926],{"class":488},"    dispatcher ",[456,4928,1632],{"class":462},[456,4930,402],{"class":626},[456,4932,2170],{"class":462},[456,4934,4935],{"class":458,"line":1162},[456,4936,1328],{"class":626},[456,4938,4939],{"class":458,"line":1168},[456,4940,519],{"emptyLinePlaceholder":518},[456,4942,4943,4945,4947,4949,4951,4953,4955,4957,4959,4961,4964,4966,4968,4970,4973,4975,4978,4981,4983,4986,4988,4991,4994,4996,4999,5001,5003,5005],{"class":458,"line":1190},[456,4944,869],{"class":626},[456,4946,3749],{"class":508},[456,4948,947],{"class":626},[456,4950,4224],{"class":1005},[456,4952,1009],{"class":626},[456,4954,4229],{"class":462},[456,4956,402],{"class":626},[456,4958,4234],{"class":462},[456,4960,953],{"class":626},[456,4962,4963],{"class":1005}," products",[456,4965,1009],{"class":626},[456,4967,4229],{"class":462},[456,4969,402],{"class":626},[456,4971,4972],{"class":462},"Products",[456,4974,953],{"class":626},[456,4976,4977],{"class":1005}," tx",[456,4979,4980],{"class":462}," dbx",[456,4982,402],{"class":626},[456,4984,4985],{"class":462},"Transactor",[456,4987,953],{"class":626},[456,4989,4990],{"class":1005}," dispatcher",[456,4992,4993],{"class":462}," events",[456,4995,402],{"class":626},[456,4997,4998],{"class":462},"Dispatcher",[456,5000,1020],{"class":626},[456,5002,1009],{"class":626},[456,5004,3763],{"class":462},[456,5006,878],{"class":626},[456,5008,5009,5011,5013,5015,5017,5019,5021,5023,5025,5027,5029,5031,5033,5035,5037,5039,5041,5043,5045,5047],{"class":458,"line":1210},[456,5010,3253],{"class":751},[456,5012,3779],{"class":626},[456,5014,3763],{"class":462},[456,5016,3389],{"class":626},[456,5018,4224],{"class":488},[456,5020,1081],{"class":626},[456,5022,4438],{"class":488},[456,5024,953],{"class":626},[456,5026,4963],{"class":488},[456,5028,1081],{"class":626},[456,5030,4963],{"class":488},[456,5032,953],{"class":626},[456,5034,4977],{"class":488},[456,5036,1081],{"class":626},[456,5038,4977],{"class":488},[456,5040,953],{"class":626},[456,5042,4990],{"class":488},[456,5044,1081],{"class":626},[456,5046,4990],{"class":488},[456,5048,1328],{"class":626},[456,5050,5051],{"class":458,"line":1219},[456,5052,1328],{"class":626},[456,5054,5055],{"class":458,"line":1258},[456,5056,519],{"emptyLinePlaceholder":518},[456,5058,5059,5061,5063,5066,5068,5070,5072,5074,5076,5078,5080,5082,5084,5086,5089,5091,5093,5095],{"class":458,"line":1271},[456,5060,869],{"class":626},[456,5062,3061],{"class":626},[456,5064,5065],{"class":1005},"c ",[456,5067,2138],{"class":626},[456,5069,3763],{"class":462},[456,5071,1020],{"class":626},[456,5073,3818],{"class":508},[456,5075,947],{"class":626},[456,5077,950],{"class":1005},[456,5079,920],{"class":462},[456,5081,402],{"class":626},[456,5083,1249],{"class":462},[456,5085,953],{"class":626},[456,5087,5088],{"class":1005}," in",[456,5090,4829],{"class":462},[456,5092,1020],{"class":626},[456,5094,1024],{"class":1023},[456,5096,878],{"class":626},[456,5098,5099,5101,5104,5106,5109,5111,5114,5116,5118,5120,5122,5124,5126,5128,5130,5132,5134],{"class":458,"line":1278},[456,5100,3253],{"class":751},[456,5102,5103],{"class":488}," c",[456,5105,402],{"class":626},[456,5107,5108],{"class":488},"tx",[456,5110,402],{"class":626},[456,5112,5113],{"class":508},"WithinTransaction",[456,5115,947],{"class":626},[456,5117,950],{"class":488},[456,5119,953],{"class":626},[456,5121,1002],{"class":626},[456,5123,950],{"class":1005},[456,5125,920],{"class":462},[456,5127,402],{"class":626},[456,5129,1249],{"class":462},[456,5131,1020],{"class":626},[456,5133,1024],{"class":1023},[456,5135,878],{"class":626},[456,5137,5138,5140,5142,5144,5146,5148,5150,5152,5154,5157,5159,5161,5163,5165],{"class":458,"line":1284},[456,5139,4429],{"class":488},[456,5141,953],{"class":626},[456,5143,1290],{"class":488},[456,5145,887],{"class":626},[456,5147,5103],{"class":488},[456,5149,402],{"class":626},[456,5151,4224],{"class":488},[456,5153,402],{"class":626},[456,5155,5156],{"class":508},"Insert",[456,5158,947],{"class":626},[456,5160,950],{"class":488},[456,5162,953],{"class":626},[456,5164,5088],{"class":488},[456,5166,858],{"class":626},[456,5168,5169,5171,5173,5175,5177],{"class":458,"line":1301},[456,5170,3592],{"class":751},[456,5172,1290],{"class":488},[456,5174,1293],{"class":626},[456,5176,1296],{"class":626},[456,5178,878],{"class":626},[456,5180,5181,5183],{"class":458,"line":1319},[456,5182,1864],{"class":751},[456,5184,3607],{"class":488},[456,5186,5187],{"class":458,"line":1325},[456,5188,1165],{"class":626},[456,5190,5191,5193,5195,5197,5199,5201,5204,5206,5209,5211,5213,5215,5217,5219,5222,5224,5226,5228,5231,5234,5236,5238,5240],{"class":458,"line":1874},[456,5192,3592],{"class":751},[456,5194,1290],{"class":488},[456,5196,887],{"class":626},[456,5198,5103],{"class":488},[456,5200,402],{"class":626},[456,5202,5203],{"class":488},"products",[456,5205,402],{"class":626},[456,5207,5208],{"class":508},"DecrementStock",[456,5210,947],{"class":626},[456,5212,950],{"class":488},[456,5214,953],{"class":626},[456,5216,5088],{"class":488},[456,5218,402],{"class":626},[456,5220,5221],{"class":488},"ProductID",[456,5223,953],{"class":626},[456,5225,5088],{"class":488},[456,5227,402],{"class":626},[456,5229,5230],{"class":488},"Qty",[456,5232,5233],{"class":626},");",[456,5235,1290],{"class":488},[456,5237,1293],{"class":626},[456,5239,1296],{"class":626},[456,5241,878],{"class":626},[456,5243,5244,5246],{"class":458,"line":1880},[456,5245,1864],{"class":751},[456,5247,3607],{"class":488},[456,5249,5250],{"class":458,"line":1893},[456,5251,1165],{"class":626},[456,5253,5254,5256,5258,5260,5263,5265,5268,5270,5272,5274,5276,5278,5280],{"class":458,"line":1908},[456,5255,1213],{"class":751},[456,5257,5103],{"class":488},[456,5259,402],{"class":626},[456,5261,5262],{"class":488},"dispatcher",[456,5264,402],{"class":626},[456,5266,5267],{"class":508},"Dispatch",[456,5269,947],{"class":626},[456,5271,950],{"class":488},[456,5273,953],{"class":626},[456,5275,3238],{"class":462},[456,5277,402],{"class":626},[456,5279,3064],{"class":462},[456,5281,1072],{"class":626},[456,5283,5284,5287,5289,5291,5293,5296],{"class":458,"line":1913},[456,5285,5286],{"class":488},"            OrderID",[456,5288,1081],{"class":626},[456,5290,4488],{"class":488},[456,5292,402],{"class":626},[456,5294,5295],{"class":488},"ID",[456,5297,3373],{"class":626},[456,5299,5300,5303,5305,5308,5310,5312],{"class":458,"line":2522},[456,5301,5302],{"class":488},"            Email",[456,5304,1081],{"class":626},[456,5306,5307],{"class":488},"   order",[456,5309,402],{"class":626},[456,5311,252],{"class":488},[456,5313,3373],{"class":626},[456,5315,5316],{"class":458,"line":2547},[456,5317,5318],{"class":626},"        })\n",[456,5320,5321],{"class":458,"line":2598},[456,5322,4540],{"class":626},[456,5324,5325],{"class":458,"line":2640},[456,5326,1328],{"class":626},[447,5328,5331],{"className":731,"code":5329,"filename":5330,"language":463,"meta":452,"style":452},"package service\n\nimport (\n    \"context\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fpaginate\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fcore\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Frepository\"\n)\n\nconst productSort = \"created_at DESC, id DESC\" \u002F\u002F must match the repository's ORDER BY\n\n\u002F\u002F Aliased so handlers and mappers only ever import their own surface's service package.\ntype (\n    PlaceOrderInput = core.PlaceOrderInput\n    Product         = repository.Product\n)\n\ntype Service struct {\n    core     *core.Service\n    orders   *repository.OrderRepo\n    products *repository.Products\n}\n\nfunc New(deps shop.Dependencies) *Service {\n    orders := repository.NewOrderRepo(deps.DB)\n    products := repository.NewProducts(deps.DB)\n    return &Service{\n        core:     core.New(orders, products, deps.Transactor, deps.Dispatcher),\n        orders:   orders,\n        products: products,\n    }\n}\n\nfunc (s *Service) Orders() *repository.OrderRepo { return s.orders }\n\n\u002F\u002F PlaceOrder delegates to the module's shared rule: the transaction, the\n\u002F\u002F stock decrement and the event dispatch live in core, written once.\nfunc (s *Service) PlaceOrder(ctx context.Context, in PlaceOrderInput) error {\n    return s.core.PlaceOrder(ctx, in)\n}\n\n\u002F\u002F ListProducts concerns only this surface, so it stays in the seam.\nfunc (s *Service) ListProducts(ctx context.Context, cursor *string, limit *int) (paginate.CursorPage[Product], error) {\n    p, err := paginate.NormalizeCursor(cursor, limit, productSort)\n    if err != nil {\n        return paginate.CursorPage[Product]{}, err \u002F\u002F ErrInvalidCursor → HTTP 400\n    }\n    return s.products.List(ctx, p)\n}\n","internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fservice\u002Fservice.go",[371,5332,5333,5340,5344,5350,5358,5362,5371,5375,5383,5392,5400,5404,5408,5429,5433,5438,5444,5460,5476,5480,5484,5494,5508,5521,5534,5538,5542,5566,5590,5613,5623,5663,5675,5686,5690,5694,5698,5740,5744,5749,5754,5792,5816,5820,5824,5829,5900,5935,5947,5969,5973,5999],{"__ignoreMap":452},[456,5334,5335,5337],{"class":458,"line":459},[456,5336,739],{"class":626},[456,5338,5339],{"class":462}," service\n",[456,5341,5342],{"class":458,"line":492},[456,5343,519],{"emptyLinePlaceholder":518},[456,5345,5346,5348],{"class":458,"line":505},[456,5347,752],{"class":751},[456,5349,755],{"class":626},[456,5351,5352,5354,5356],{"class":458,"line":515},[456,5353,760],{"class":626},[456,5355,763],{"class":462},[456,5357,633],{"class":626},[456,5359,5360],{"class":458,"line":522},[456,5361,519],{"emptyLinePlaceholder":518},[456,5363,5364,5366,5369],{"class":458,"line":541},[456,5365,760],{"class":626},[456,5367,5368],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fpaginate",[456,5370,633],{"class":626},[456,5372,5373],{"class":458,"line":560},[456,5374,519],{"emptyLinePlaceholder":518},[456,5376,5377,5379,5381],{"class":458,"line":578},[456,5378,760],{"class":626},[456,5380,840],{"class":462},[456,5382,633],{"class":626},[456,5384,5385,5387,5390],{"class":458,"line":605},[456,5386,760],{"class":626},[456,5388,5389],{"class":462},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fcore",[456,5391,633],{"class":626},[456,5393,5394,5396,5398],{"class":458,"line":636},[456,5395,760],{"class":626},[456,5397,4203],{"class":462},[456,5399,633],{"class":626},[456,5401,5402],{"class":458,"line":653},[456,5403,858],{"class":626},[456,5405,5406],{"class":458,"line":658},[456,5407,519],{"emptyLinePlaceholder":518},[456,5409,5410,5413,5416,5419,5421,5424,5426],{"class":458,"line":830},[456,5411,5412],{"class":626},"const",[456,5414,5415],{"class":488}," productSort ",[456,5417,5418],{"class":626},"=",[456,5420,627],{"class":626},[456,5422,5423],{"class":466},"created_at DESC, id DESC",[456,5425,1047],{"class":626},[456,5427,5428],{"class":501}," \u002F\u002F must match the repository's ORDER BY\n",[456,5430,5431],{"class":458,"line":835},[456,5432,519],{"emptyLinePlaceholder":518},[456,5434,5435],{"class":458,"line":845},[456,5436,5437],{"class":501},"\u002F\u002F Aliased so handlers and mappers only ever import their own surface's service package.\n",[456,5439,5440,5442],{"class":458,"line":855},[456,5441,2122],{"class":626},[456,5443,755],{"class":626},[456,5445,5446,5449,5452,5455,5457],{"class":458,"line":861},[456,5447,5448],{"class":462},"    PlaceOrderInput",[456,5450,5451],{"class":626}," =",[456,5453,5454],{"class":462}," core",[456,5456,402],{"class":626},[456,5458,5459],{"class":462},"PlaceOrderInput\n",[456,5461,5462,5465,5468,5471,5473],{"class":458,"line":866},[456,5463,5464],{"class":462},"    Product",[456,5466,5467],{"class":626},"         =",[456,5469,5470],{"class":462}," repository",[456,5472,402],{"class":626},[456,5474,5475],{"class":462},"Product\n",[456,5477,5478],{"class":458,"line":881},[456,5479,858],{"class":626},[456,5481,5482],{"class":458,"line":912},[456,5483,519],{"emptyLinePlaceholder":518},[456,5485,5486,5488,5490,5492],{"class":458,"line":931},[456,5487,2122],{"class":626},[456,5489,4878],{"class":462},[456,5491,2128],{"class":626},[456,5493,878],{"class":626},[456,5495,5496,5499,5501,5504,5506],{"class":458,"line":966},[456,5497,5498],{"class":488},"    core     ",[456,5500,2138],{"class":626},[456,5502,5503],{"class":462},"core",[456,5505,402],{"class":626},[456,5507,3734],{"class":462},[456,5509,5510,5513,5515,5517,5519],{"class":458,"line":971},[456,5511,5512],{"class":488},"    orders   ",[456,5514,2138],{"class":626},[456,5516,4229],{"class":462},[456,5518,402],{"class":626},[456,5520,4896],{"class":462},[456,5522,5523,5526,5528,5530,5532],{"class":458,"line":1029},[456,5524,5525],{"class":488},"    products ",[456,5527,2138],{"class":626},[456,5529,4229],{"class":462},[456,5531,402],{"class":626},[456,5533,4910],{"class":462},[456,5535,5536],{"class":458,"line":1057},[456,5537,1328],{"class":626},[456,5539,5540],{"class":458,"line":1075},[456,5541,519],{"emptyLinePlaceholder":518},[456,5543,5544,5546,5548,5550,5552,5554,5556,5558,5560,5562,5564],{"class":458,"line":1100},[456,5545,869],{"class":626},[456,5547,3749],{"class":508},[456,5549,947],{"class":626},[456,5551,2248],{"class":1005},[456,5553,479],{"class":462},[456,5555,402],{"class":626},[456,5557,1069],{"class":462},[456,5559,1020],{"class":626},[456,5561,1009],{"class":626},[456,5563,3763],{"class":462},[456,5565,878],{"class":626},[456,5567,5568,5571,5573,5575,5577,5580,5582,5584,5586,5588],{"class":458,"line":1121},[456,5569,5570],{"class":488},"    orders ",[456,5572,887],{"class":626},[456,5574,5470],{"class":488},[456,5576,402],{"class":626},[456,5578,5579],{"class":508},"NewOrderRepo",[456,5581,947],{"class":626},[456,5583,2248],{"class":488},[456,5585,402],{"class":626},[456,5587,961],{"class":488},[456,5589,858],{"class":626},[456,5591,5592,5594,5596,5598,5600,5603,5605,5607,5609,5611],{"class":458,"line":1162},[456,5593,5525],{"class":488},[456,5595,887],{"class":626},[456,5597,5470],{"class":488},[456,5599,402],{"class":626},[456,5601,5602],{"class":508},"NewProducts",[456,5604,947],{"class":626},[456,5606,2248],{"class":488},[456,5608,402],{"class":626},[456,5610,961],{"class":488},[456,5612,858],{"class":626},[456,5614,5615,5617,5619,5621],{"class":458,"line":1168},[456,5616,3253],{"class":751},[456,5618,3779],{"class":626},[456,5620,3763],{"class":462},[456,5622,1072],{"class":626},[456,5624,5625,5628,5630,5633,5635,5637,5639,5641,5643,5645,5647,5649,5651,5653,5655,5657,5659,5661],{"class":458,"line":1190},[456,5626,5627],{"class":488},"        core",[456,5629,1081],{"class":626},[456,5631,5632],{"class":488},"     core",[456,5634,402],{"class":626},[456,5636,2243],{"class":508},[456,5638,947],{"class":626},[456,5640,4224],{"class":488},[456,5642,953],{"class":626},[456,5644,4963],{"class":488},[456,5646,953],{"class":626},[456,5648,1185],{"class":488},[456,5650,402],{"class":626},[456,5652,4985],{"class":488},[456,5654,953],{"class":626},[456,5656,1185],{"class":488},[456,5658,402],{"class":626},[456,5660,4998],{"class":488},[456,5662,1097],{"class":626},[456,5664,5665,5668,5670,5673],{"class":458,"line":1210},[456,5666,5667],{"class":488},"        orders",[456,5669,1081],{"class":626},[456,5671,5672],{"class":488},"   orders",[456,5674,3373],{"class":626},[456,5676,5677,5680,5682,5684],{"class":458,"line":1219},[456,5678,5679],{"class":488},"        products",[456,5681,1081],{"class":626},[456,5683,4963],{"class":488},[456,5685,3373],{"class":626},[456,5687,5688],{"class":458,"line":1258},[456,5689,1322],{"class":626},[456,5691,5692],{"class":458,"line":1271},[456,5693,1328],{"class":626},[456,5695,5696],{"class":458,"line":1278},[456,5697,519],{"emptyLinePlaceholder":518},[456,5699,5700,5702,5704,5707,5709,5711,5713,5716,5718,5720,5722,5724,5726,5728,5730,5733,5735,5738],{"class":458,"line":1284},[456,5701,869],{"class":626},[456,5703,3061],{"class":626},[456,5705,5706],{"class":1005},"s ",[456,5708,2138],{"class":626},[456,5710,3763],{"class":462},[456,5712,1020],{"class":626},[456,5714,5715],{"class":508}," Orders",[456,5717,875],{"class":626},[456,5719,1009],{"class":626},[456,5721,4229],{"class":462},[456,5723,402],{"class":626},[456,5725,4234],{"class":462},[456,5727,3077],{"class":626},[456,5729,3080],{"class":751},[456,5731,5732],{"class":488}," s",[456,5734,402],{"class":626},[456,5736,5737],{"class":488},"orders ",[456,5739,1328],{"class":626},[456,5741,5742],{"class":458,"line":1301},[456,5743,519],{"emptyLinePlaceholder":518},[456,5745,5746],{"class":458,"line":1319},[456,5747,5748],{"class":501},"\u002F\u002F PlaceOrder delegates to the module's shared rule: the transaction, the\n",[456,5750,5751],{"class":458,"line":1325},[456,5752,5753],{"class":501},"\u002F\u002F stock decrement and the event dispatch live in core, written once.\n",[456,5755,5756,5758,5760,5762,5764,5766,5768,5770,5772,5774,5776,5778,5780,5782,5784,5786,5788,5790],{"class":458,"line":1874},[456,5757,869],{"class":626},[456,5759,3061],{"class":626},[456,5761,5706],{"class":1005},[456,5763,2138],{"class":626},[456,5765,3763],{"class":462},[456,5767,1020],{"class":626},[456,5769,3818],{"class":508},[456,5771,947],{"class":626},[456,5773,950],{"class":1005},[456,5775,920],{"class":462},[456,5777,402],{"class":626},[456,5779,1249],{"class":462},[456,5781,953],{"class":626},[456,5783,5088],{"class":1005},[456,5785,4829],{"class":462},[456,5787,1020],{"class":626},[456,5789,1024],{"class":1023},[456,5791,878],{"class":626},[456,5793,5794,5796,5798,5800,5802,5804,5806,5808,5810,5812,5814],{"class":458,"line":1880},[456,5795,3253],{"class":751},[456,5797,5732],{"class":488},[456,5799,402],{"class":626},[456,5801,5503],{"class":488},[456,5803,402],{"class":626},[456,5805,383],{"class":508},[456,5807,947],{"class":626},[456,5809,950],{"class":488},[456,5811,953],{"class":626},[456,5813,5088],{"class":488},[456,5815,858],{"class":626},[456,5817,5818],{"class":458,"line":1893},[456,5819,1328],{"class":626},[456,5821,5822],{"class":458,"line":1908},[456,5823,519],{"emptyLinePlaceholder":518},[456,5825,5826],{"class":458,"line":1913},[456,5827,5828],{"class":501},"\u002F\u002F ListProducts concerns only this surface, so it stays in the seam.\n",[456,5830,5831,5833,5835,5837,5839,5841,5843,5845,5847,5849,5851,5853,5855,5857,5860,5862,5864,5866,5869,5871,5874,5876,5878,5881,5883,5886,5888,5891,5894,5896,5898],{"class":458,"line":2522},[456,5832,869],{"class":626},[456,5834,3061],{"class":626},[456,5836,5706],{"class":1005},[456,5838,2138],{"class":626},[456,5840,3763],{"class":462},[456,5842,1020],{"class":626},[456,5844,3959],{"class":508},[456,5846,947],{"class":626},[456,5848,950],{"class":1005},[456,5850,920],{"class":462},[456,5852,402],{"class":626},[456,5854,1249],{"class":462},[456,5856,953],{"class":626},[456,5858,5859],{"class":1005}," cursor",[456,5861,1009],{"class":626},[456,5863,3023],{"class":1023},[456,5865,953],{"class":626},[456,5867,5868],{"class":1005}," limit",[456,5870,1009],{"class":626},[456,5872,5873],{"class":1023},"int",[456,5875,1020],{"class":626},[456,5877,3061],{"class":626},[456,5879,5880],{"class":462},"paginate",[456,5882,402],{"class":626},[456,5884,5885],{"class":462},"CursorPage",[456,5887,898],{"class":626},[456,5889,5890],{"class":462},"Product",[456,5892,5893],{"class":626},"],",[456,5895,1024],{"class":1023},[456,5897,1020],{"class":626},[456,5899,878],{"class":626},[456,5901,5902,5905,5907,5909,5911,5914,5916,5919,5921,5924,5926,5928,5930,5933],{"class":458,"line":2547},[456,5903,5904],{"class":488},"    p",[456,5906,953],{"class":626},[456,5908,1290],{"class":488},[456,5910,887],{"class":626},[456,5912,5913],{"class":488}," paginate",[456,5915,402],{"class":626},[456,5917,5918],{"class":508},"NormalizeCursor",[456,5920,947],{"class":626},[456,5922,5923],{"class":488},"cursor",[456,5925,953],{"class":626},[456,5927,5868],{"class":488},[456,5929,953],{"class":626},[456,5931,5932],{"class":488}," productSort",[456,5934,858],{"class":626},[456,5936,5937,5939,5941,5943,5945],{"class":458,"line":2598},[456,5938,1287],{"class":751},[456,5940,1290],{"class":488},[456,5942,1293],{"class":626},[456,5944,1296],{"class":626},[456,5946,878],{"class":626},[456,5948,5949,5951,5953,5955,5957,5959,5961,5964,5966],{"class":458,"line":2640},[456,5950,1213],{"class":751},[456,5952,5913],{"class":462},[456,5954,402],{"class":626},[456,5956,5885],{"class":462},[456,5958,898],{"class":626},[456,5960,5890],{"class":462},[456,5962,5963],{"class":626},"]{},",[456,5965,1290],{"class":488},[456,5967,5968],{"class":501},"\u002F\u002F ErrInvalidCursor → HTTP 400\n",[456,5970,5971],{"class":458,"line":2680},[456,5972,1322],{"class":626},[456,5974,5975,5977,5979,5981,5983,5985,5988,5990,5992,5994,5997],{"class":458,"line":2693},[456,5976,3253],{"class":751},[456,5978,5732],{"class":488},[456,5980,402],{"class":626},[456,5982,5203],{"class":488},[456,5984,402],{"class":626},[456,5986,5987],{"class":508},"List",[456,5989,947],{"class":626},[456,5991,950],{"class":488},[456,5993,953],{"class":626},[456,5995,5996],{"class":488}," p",[456,5998,858],{"class":626},[456,6000,6002],{"class":458,"line":6001},52,[456,6003,1328],{"class":626},[447,6005,6008],{"className":731,"code":6006,"filename":6007,"language":463,"meta":452,"style":452},"package repository\n\nimport (\n    \"context\"\n    \"time\"\n\n    \"github.com\u002Fjackc\u002Fpgx\u002Fv5\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\u002Fpg\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Ferrs\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fpaginate\"\n)\n\ntype Product struct {\n    ID         string\n    Name       string\n    PriceCents int64\n    Stock      int\n    CreatedAt  time.Time\n}\n\ntype Products struct {\n    db pg.DBTX\n}\n\nfunc NewProducts(db pg.DBTX) *Products {\n    return &Products{db: db}\n}\n\nfunc (r *Products) List(ctx context.Context, p paginate.CursorParams) (paginate.CursorPage[Product], error) {\n    query := `SELECT id, name, price_cents, stock, created_at FROM products`\n    args := []any{p.FetchLimit()}\n\n    if p.HasCursor() {\n        var createdAt time.Time\n        var id string\n        if err := p.DecodeKey(&createdAt, &id); err != nil {\n            return paginate.CursorPage[Product]{}, err\n        }\n        query += ` WHERE (created_at, id) \u003C ($2, $3)`\n        args = append(args, createdAt, id)\n    }\n    query += ` ORDER BY created_at DESC, id DESC LIMIT $1`\n\n    rows, err := r.db.Query(ctx, query, args...)\n    if err != nil {\n        return paginate.CursorPage[Product]{}, errs.Wrap(err, \"products: list\")\n    }\n    products, err := pgx.CollectRows(rows, pgx.RowToStructByName[Product])\n    if err != nil {\n        return paginate.CursorPage[Product]{}, errs.Wrap(err, \"products: scan\")\n    }\n\n    return paginate.NewCursorPage(products, p, func(last Product) []any {\n        return []any{last.CreatedAt, last.ID}\n    })\n}\n\nfunc (r *Products) DecrementStock(ctx context.Context, productID string, qty int) error {\n    tag, err := r.db.Exec(ctx,\n        `UPDATE products SET stock = stock - $2 WHERE id = $1 AND stock >= $2`,\n        productID, qty)\n    if err != nil {\n        return errs.Wrap(err, \"products: decrement stock\")\n    }\n    if tag.RowsAffected() == 0 {\n        return errs.New(\"insufficient stock\",\n            errs.Code(\"insufficient_stock\"), errs.Public(\"The product is out of stock.\"))\n    }\n    return nil\n}\n","internal\u002Fmodules\u002Fshop\u002Frepository\u002Fproducts.go",[371,6009,6010,6017,6021,6027,6035,6044,6048,6057,6061,6069,6078,6086,6090,6094,6105,6112,6119,6127,6134,6146,6150,6154,6165,6177,6181,6185,6212,6231,6235,6239,6300,6314,6337,6341,6356,6370,6379,6417,6435,6439,6454,6480,6484,6497,6501,6540,6552,6590,6594,6634,6646,6683,6687,6692,6729,6758,6763,6768,6773,6822,6851,6865,6877,6890,6916,6921,6945,6967,7007,7012,7019],{"__ignoreMap":452},[456,6011,6012,6014],{"class":458,"line":459},[456,6013,739],{"class":626},[456,6015,6016],{"class":462}," repository\n",[456,6018,6019],{"class":458,"line":492},[456,6020,519],{"emptyLinePlaceholder":518},[456,6022,6023,6025],{"class":458,"line":505},[456,6024,752],{"class":751},[456,6026,755],{"class":626},[456,6028,6029,6031,6033],{"class":458,"line":515},[456,6030,760],{"class":626},[456,6032,763],{"class":462},[456,6034,633],{"class":626},[456,6036,6037,6039,6042],{"class":458,"line":522},[456,6038,760],{"class":626},[456,6040,6041],{"class":462},"time",[456,6043,633],{"class":626},[456,6045,6046],{"class":458,"line":541},[456,6047,519],{"emptyLinePlaceholder":518},[456,6049,6050,6052,6055],{"class":458,"line":560},[456,6051,760],{"class":626},[456,6053,6054],{"class":462},"github.com\u002Fjackc\u002Fpgx\u002Fv5",[456,6056,633],{"class":626},[456,6058,6059],{"class":458,"line":578},[456,6060,519],{"emptyLinePlaceholder":518},[456,6062,6063,6065,6067],{"class":458,"line":605},[456,6064,760],{"class":626},[456,6066,798],{"class":462},[456,6068,633],{"class":626},[456,6070,6071,6073,6076],{"class":458,"line":636},[456,6072,760],{"class":626},[456,6074,6075],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Ferrs",[456,6077,633],{"class":626},[456,6079,6080,6082,6084],{"class":458,"line":653},[456,6081,760],{"class":626},[456,6083,5368],{"class":462},[456,6085,633],{"class":626},[456,6087,6088],{"class":458,"line":658},[456,6089,858],{"class":626},[456,6091,6092],{"class":458,"line":830},[456,6093,519],{"emptyLinePlaceholder":518},[456,6095,6096,6098,6101,6103],{"class":458,"line":835},[456,6097,2122],{"class":626},[456,6099,6100],{"class":462}," Product",[456,6102,2128],{"class":626},[456,6104,878],{"class":626},[456,6106,6107,6110],{"class":458,"line":845},[456,6108,6109],{"class":488},"    ID         ",[456,6111,4841],{"class":1023},[456,6113,6114,6117],{"class":458,"line":855},[456,6115,6116],{"class":488},"    Name       ",[456,6118,4841],{"class":1023},[456,6120,6121,6124],{"class":458,"line":861},[456,6122,6123],{"class":488},"    PriceCents ",[456,6125,6126],{"class":1023},"int64\n",[456,6128,6129,6132],{"class":458,"line":866},[456,6130,6131],{"class":488},"    Stock      ",[456,6133,4856],{"class":1023},[456,6135,6136,6139,6141,6143],{"class":458,"line":881},[456,6137,6138],{"class":488},"    CreatedAt  ",[456,6140,6041],{"class":462},[456,6142,402],{"class":626},[456,6144,6145],{"class":462},"Time\n",[456,6147,6148],{"class":458,"line":912},[456,6149,1328],{"class":626},[456,6151,6152],{"class":458,"line":931},[456,6153,519],{"emptyLinePlaceholder":518},[456,6155,6156,6158,6161,6163],{"class":458,"line":966},[456,6157,2122],{"class":626},[456,6159,6160],{"class":462}," Products",[456,6162,2128],{"class":626},[456,6164,878],{"class":626},[456,6166,6167,6170,6172,6174],{"class":458,"line":971},[456,6168,6169],{"class":488},"    db ",[456,6171,1148],{"class":462},[456,6173,402],{"class":626},[456,6175,6176],{"class":462},"DBTX\n",[456,6178,6179],{"class":458,"line":1029},[456,6180,1328],{"class":626},[456,6182,6183],{"class":458,"line":1057},[456,6184,519],{"emptyLinePlaceholder":518},[456,6186,6187,6189,6192,6194,6197,6199,6201,6204,6206,6208,6210],{"class":458,"line":1075},[456,6188,869],{"class":626},[456,6190,6191],{"class":508}," NewProducts",[456,6193,947],{"class":626},[456,6195,6196],{"class":1005},"db",[456,6198,939],{"class":462},[456,6200,402],{"class":626},[456,6202,6203],{"class":462},"DBTX",[456,6205,1020],{"class":626},[456,6207,1009],{"class":626},[456,6209,4972],{"class":462},[456,6211,878],{"class":626},[456,6213,6214,6216,6218,6220,6222,6224,6226,6229],{"class":458,"line":1100},[456,6215,3253],{"class":751},[456,6217,3779],{"class":626},[456,6219,4972],{"class":462},[456,6221,3389],{"class":626},[456,6223,6196],{"class":488},[456,6225,1081],{"class":626},[456,6227,6228],{"class":488}," db",[456,6230,1328],{"class":626},[456,6232,6233],{"class":458,"line":1121},[456,6234,1328],{"class":626},[456,6236,6237],{"class":458,"line":1162},[456,6238,519],{"emptyLinePlaceholder":518},[456,6240,6241,6243,6245,6248,6250,6252,6254,6257,6259,6261,6263,6265,6267,6269,6271,6273,6275,6278,6280,6282,6284,6286,6288,6290,6292,6294,6296,6298],{"class":458,"line":1168},[456,6242,869],{"class":626},[456,6244,3061],{"class":626},[456,6246,6247],{"class":1005},"r ",[456,6249,2138],{"class":626},[456,6251,4972],{"class":462},[456,6253,1020],{"class":626},[456,6255,6256],{"class":508}," List",[456,6258,947],{"class":626},[456,6260,950],{"class":1005},[456,6262,920],{"class":462},[456,6264,402],{"class":626},[456,6266,1249],{"class":462},[456,6268,953],{"class":626},[456,6270,5996],{"class":1005},[456,6272,5913],{"class":462},[456,6274,402],{"class":626},[456,6276,6277],{"class":462},"CursorParams",[456,6279,1020],{"class":626},[456,6281,3061],{"class":626},[456,6283,5880],{"class":462},[456,6285,402],{"class":626},[456,6287,5885],{"class":462},[456,6289,898],{"class":626},[456,6291,5890],{"class":462},[456,6293,5893],{"class":626},[456,6295,1024],{"class":1023},[456,6297,1020],{"class":626},[456,6299,878],{"class":626},[456,6301,6302,6305,6307,6309,6312],{"class":458,"line":1190},[456,6303,6304],{"class":488},"    query ",[456,6306,887],{"class":626},[456,6308,3026],{"class":626},[456,6310,6311],{"class":466},"SELECT id, name, price_cents, stock, created_at FROM products",[456,6313,3032],{"class":626},[456,6315,6316,6319,6321,6323,6325,6327,6329,6331,6334],{"class":458,"line":1210},[456,6317,6318],{"class":488},"    args ",[456,6320,887],{"class":626},[456,6322,2357],{"class":626},[456,6324,3386],{"class":462},[456,6326,3389],{"class":626},[456,6328,348],{"class":488},[456,6330,402],{"class":626},[456,6332,6333],{"class":508},"FetchLimit",[456,6335,6336],{"class":626},"()}\n",[456,6338,6339],{"class":458,"line":1219},[456,6340,519],{"emptyLinePlaceholder":518},[456,6342,6343,6345,6347,6349,6352,6354],{"class":458,"line":1258},[456,6344,1287],{"class":751},[456,6346,5996],{"class":488},[456,6348,402],{"class":626},[456,6350,6351],{"class":508},"HasCursor",[456,6353,875],{"class":626},[456,6355,878],{"class":626},[456,6357,6358,6361,6364,6366,6368],{"class":458,"line":1271},[456,6359,6360],{"class":626},"        var",[456,6362,6363],{"class":488}," createdAt ",[456,6365,6041],{"class":462},[456,6367,402],{"class":626},[456,6369,6145],{"class":462},[456,6371,6372,6374,6377],{"class":458,"line":1278},[456,6373,6360],{"class":626},[456,6375,6376],{"class":488}," id ",[456,6378,4841],{"class":1023},[456,6380,6381,6383,6385,6387,6389,6391,6394,6397,6400,6402,6404,6407,6409,6411,6413,6415],{"class":458,"line":1284},[456,6382,3592],{"class":751},[456,6384,1290],{"class":488},[456,6386,887],{"class":626},[456,6388,5996],{"class":488},[456,6390,402],{"class":626},[456,6392,6393],{"class":508},"DecodeKey",[456,6395,6396],{"class":626},"(&",[456,6398,6399],{"class":488},"createdAt",[456,6401,953],{"class":626},[456,6403,3779],{"class":626},[456,6405,6406],{"class":488},"id",[456,6408,5233],{"class":626},[456,6410,1290],{"class":488},[456,6412,1293],{"class":626},[456,6414,1296],{"class":626},[456,6416,878],{"class":626},[456,6418,6419,6421,6423,6425,6427,6429,6431,6433],{"class":458,"line":1301},[456,6420,1864],{"class":751},[456,6422,5913],{"class":462},[456,6424,402],{"class":626},[456,6426,5885],{"class":462},[456,6428,898],{"class":626},[456,6430,5890],{"class":462},[456,6432,5963],{"class":626},[456,6434,3607],{"class":488},[456,6436,6437],{"class":458,"line":1319},[456,6438,1165],{"class":626},[456,6440,6441,6444,6447,6449,6452],{"class":458,"line":1325},[456,6442,6443],{"class":488},"        query ",[456,6445,6446],{"class":626},"+=",[456,6448,3026],{"class":626},[456,6450,6451],{"class":466}," WHERE (created_at, id) \u003C ($2, $3)",[456,6453,3032],{"class":626},[456,6455,6456,6459,6461,6464,6466,6469,6471,6474,6476,6478],{"class":458,"line":1874},[456,6457,6458],{"class":488},"        args ",[456,6460,5418],{"class":626},[456,6462,6463],{"class":508}," append",[456,6465,947],{"class":626},[456,6467,6468],{"class":488},"args",[456,6470,953],{"class":626},[456,6472,6473],{"class":488}," createdAt",[456,6475,953],{"class":626},[456,6477,4304],{"class":488},[456,6479,858],{"class":626},[456,6481,6482],{"class":458,"line":1880},[456,6483,1322],{"class":626},[456,6485,6486,6488,6490,6492,6495],{"class":458,"line":1893},[456,6487,6304],{"class":488},[456,6489,6446],{"class":626},[456,6491,3026],{"class":626},[456,6493,6494],{"class":466}," ORDER BY created_at DESC, id DESC LIMIT $1",[456,6496,3032],{"class":626},[456,6498,6499],{"class":458,"line":1908},[456,6500,519],{"emptyLinePlaceholder":518},[456,6502,6503,6506,6508,6510,6512,6514,6516,6518,6520,6523,6525,6527,6529,6532,6534,6537],{"class":458,"line":1913},[456,6504,6505],{"class":488},"    rows",[456,6507,953],{"class":626},[456,6509,1290],{"class":488},[456,6511,887],{"class":626},[456,6513,4452],{"class":488},[456,6515,402],{"class":626},[456,6517,6196],{"class":488},[456,6519,402],{"class":626},[456,6521,6522],{"class":508},"Query",[456,6524,947],{"class":626},[456,6526,950],{"class":488},[456,6528,953],{"class":626},[456,6530,6531],{"class":488}," query",[456,6533,953],{"class":626},[456,6535,6536],{"class":488}," args",[456,6538,6539],{"class":626},"...)\n",[456,6541,6542,6544,6546,6548,6550],{"class":458,"line":2522},[456,6543,1287],{"class":751},[456,6545,1290],{"class":488},[456,6547,1293],{"class":626},[456,6549,1296],{"class":626},[456,6551,878],{"class":626},[456,6553,6554,6556,6558,6560,6562,6564,6566,6568,6571,6573,6575,6577,6579,6581,6583,6586,6588],{"class":458,"line":2547},[456,6555,1213],{"class":751},[456,6557,5913],{"class":462},[456,6559,402],{"class":626},[456,6561,5885],{"class":462},[456,6563,898],{"class":626},[456,6565,5890],{"class":462},[456,6567,5963],{"class":626},[456,6569,6570],{"class":488}," errs",[456,6572,402],{"class":626},[456,6574,4085],{"class":508},[456,6576,947],{"class":626},[456,6578,1314],{"class":488},[456,6580,953],{"class":626},[456,6582,627],{"class":626},[456,6584,6585],{"class":466},"products: list",[456,6587,1047],{"class":626},[456,6589,858],{"class":626},[456,6591,6592],{"class":458,"line":2598},[456,6593,1322],{"class":626},[456,6595,6596,6599,6601,6603,6605,6608,6610,6613,6615,6618,6620,6622,6624,6627,6629,6631],{"class":458,"line":2640},[456,6597,6598],{"class":488},"    products",[456,6600,953],{"class":626},[456,6602,1290],{"class":488},[456,6604,887],{"class":626},[456,6606,6607],{"class":488}," pgx",[456,6609,402],{"class":626},[456,6611,6612],{"class":508},"CollectRows",[456,6614,947],{"class":626},[456,6616,6617],{"class":488},"rows",[456,6619,953],{"class":626},[456,6621,6607],{"class":488},[456,6623,402],{"class":626},[456,6625,6626],{"class":488},"RowToStructByName",[456,6628,898],{"class":626},[456,6630,5890],{"class":488},[456,6632,6633],{"class":626},"])\n",[456,6635,6636,6638,6640,6642,6644],{"class":458,"line":2680},[456,6637,1287],{"class":751},[456,6639,1290],{"class":488},[456,6641,1293],{"class":626},[456,6643,1296],{"class":626},[456,6645,878],{"class":626},[456,6647,6648,6650,6652,6654,6656,6658,6660,6662,6664,6666,6668,6670,6672,6674,6676,6679,6681],{"class":458,"line":2693},[456,6649,1213],{"class":751},[456,6651,5913],{"class":462},[456,6653,402],{"class":626},[456,6655,5885],{"class":462},[456,6657,898],{"class":626},[456,6659,5890],{"class":462},[456,6661,5963],{"class":626},[456,6663,6570],{"class":488},[456,6665,402],{"class":626},[456,6667,4085],{"class":508},[456,6669,947],{"class":626},[456,6671,1314],{"class":488},[456,6673,953],{"class":626},[456,6675,627],{"class":626},[456,6677,6678],{"class":466},"products: scan",[456,6680,1047],{"class":626},[456,6682,858],{"class":626},[456,6684,6685],{"class":458,"line":6001},[456,6686,1322],{"class":626},[456,6688,6690],{"class":458,"line":6689},53,[456,6691,519],{"emptyLinePlaceholder":518},[456,6693,6695,6697,6699,6701,6704,6706,6708,6710,6712,6714,6716,6719,6721,6723,6725,6727],{"class":458,"line":6694},54,[456,6696,3253],{"class":751},[456,6698,5913],{"class":488},[456,6700,402],{"class":626},[456,6702,6703],{"class":508},"NewCursorPage",[456,6705,947],{"class":626},[456,6707,5203],{"class":488},[456,6709,953],{"class":626},[456,6711,5996],{"class":488},[456,6713,953],{"class":626},[456,6715,1002],{"class":626},[456,6717,6718],{"class":1005},"last",[456,6720,6100],{"class":462},[456,6722,1020],{"class":626},[456,6724,2357],{"class":626},[456,6726,3386],{"class":462},[456,6728,878],{"class":626},[456,6730,6732,6734,6736,6738,6740,6742,6744,6747,6749,6752,6754,6756],{"class":458,"line":6731},55,[456,6733,1213],{"class":751},[456,6735,2357],{"class":626},[456,6737,3386],{"class":462},[456,6739,3389],{"class":626},[456,6741,6718],{"class":488},[456,6743,402],{"class":626},[456,6745,6746],{"class":488},"CreatedAt",[456,6748,953],{"class":626},[456,6750,6751],{"class":488}," last",[456,6753,402],{"class":626},[456,6755,5295],{"class":488},[456,6757,1328],{"class":626},[456,6759,6761],{"class":458,"line":6760},56,[456,6762,4540],{"class":626},[456,6764,6766],{"class":458,"line":6765},57,[456,6767,1328],{"class":626},[456,6769,6771],{"class":458,"line":6770},58,[456,6772,519],{"emptyLinePlaceholder":518},[456,6774,6776,6778,6780,6782,6784,6786,6788,6791,6793,6795,6797,6799,6801,6803,6806,6808,6810,6813,6816,6818,6820],{"class":458,"line":6775},59,[456,6777,869],{"class":626},[456,6779,3061],{"class":626},[456,6781,6247],{"class":1005},[456,6783,2138],{"class":626},[456,6785,4972],{"class":462},[456,6787,1020],{"class":626},[456,6789,6790],{"class":508}," DecrementStock",[456,6792,947],{"class":626},[456,6794,950],{"class":1005},[456,6796,920],{"class":462},[456,6798,402],{"class":626},[456,6800,1249],{"class":462},[456,6802,953],{"class":626},[456,6804,6805],{"class":1005}," productID",[456,6807,3074],{"class":1023},[456,6809,953],{"class":626},[456,6811,6812],{"class":1005}," qty",[456,6814,6815],{"class":1023}," int",[456,6817,1020],{"class":626},[456,6819,1024],{"class":1023},[456,6821,878],{"class":626},[456,6823,6825,6828,6830,6832,6834,6836,6838,6840,6842,6845,6847,6849],{"class":458,"line":6824},60,[456,6826,6827],{"class":488},"    tag",[456,6829,953],{"class":626},[456,6831,1290],{"class":488},[456,6833,887],{"class":626},[456,6835,4452],{"class":488},[456,6837,402],{"class":626},[456,6839,6196],{"class":488},[456,6841,402],{"class":626},[456,6843,6844],{"class":508},"Exec",[456,6846,947],{"class":626},[456,6848,950],{"class":488},[456,6850,3373],{"class":626},[456,6852,6854,6857,6860,6863],{"class":458,"line":6853},61,[456,6855,6856],{"class":626},"        `",[456,6858,6859],{"class":466},"UPDATE products SET stock = stock - $2 WHERE id = $1 AND stock >= $2",[456,6861,6862],{"class":626},"`",[456,6864,3373],{"class":626},[456,6866,6868,6871,6873,6875],{"class":458,"line":6867},62,[456,6869,6870],{"class":488},"        productID",[456,6872,953],{"class":626},[456,6874,6812],{"class":488},[456,6876,858],{"class":626},[456,6878,6880,6882,6884,6886,6888],{"class":458,"line":6879},63,[456,6881,1287],{"class":751},[456,6883,1290],{"class":488},[456,6885,1293],{"class":626},[456,6887,1296],{"class":626},[456,6889,878],{"class":626},[456,6891,6893,6895,6897,6899,6901,6903,6905,6907,6909,6912,6914],{"class":458,"line":6892},64,[456,6894,1213],{"class":751},[456,6896,6570],{"class":488},[456,6898,402],{"class":626},[456,6900,4085],{"class":508},[456,6902,947],{"class":626},[456,6904,1314],{"class":488},[456,6906,953],{"class":626},[456,6908,627],{"class":626},[456,6910,6911],{"class":466},"products: decrement stock",[456,6913,1047],{"class":626},[456,6915,858],{"class":626},[456,6917,6919],{"class":458,"line":6918},65,[456,6920,1322],{"class":626},[456,6922,6924,6926,6929,6931,6934,6936,6939,6943],{"class":458,"line":6923},66,[456,6925,1287],{"class":751},[456,6927,6928],{"class":488}," tag",[456,6930,402],{"class":626},[456,6932,6933],{"class":508},"RowsAffected",[456,6935,875],{"class":626},[456,6937,6938],{"class":626}," ==",[456,6940,6942],{"class":6941},"sbssI"," 0",[456,6944,878],{"class":626},[456,6946,6948,6950,6952,6954,6956,6958,6960,6963,6965],{"class":458,"line":6947},67,[456,6949,1213],{"class":751},[456,6951,6570],{"class":488},[456,6953,402],{"class":626},[456,6955,2243],{"class":508},[456,6957,947],{"class":626},[456,6959,1047],{"class":626},[456,6961,6962],{"class":466},"insufficient stock",[456,6964,1047],{"class":626},[456,6966,3373],{"class":626},[456,6968,6970,6973,6975,6978,6980,6982,6985,6987,6989,6991,6993,6996,6998,7000,7003,7005],{"class":458,"line":6969},68,[456,6971,6972],{"class":488},"            errs",[456,6974,402],{"class":626},[456,6976,6977],{"class":508},"Code",[456,6979,947],{"class":626},[456,6981,1047],{"class":626},[456,6983,6984],{"class":466},"insufficient_stock",[456,6986,1047],{"class":626},[456,6988,2576],{"class":626},[456,6990,6570],{"class":488},[456,6992,402],{"class":626},[456,6994,6995],{"class":508},"Public",[456,6997,947],{"class":626},[456,6999,1047],{"class":626},[456,7001,7002],{"class":466},"The product is out of stock.",[456,7004,1047],{"class":626},[456,7006,2595],{"class":626},[456,7008,7010],{"class":458,"line":7009},69,[456,7011,1322],{"class":626},[456,7013,7015,7017],{"class":458,"line":7014},70,[456,7016,3253],{"class":751},[456,7018,1216],{"class":626},[456,7020,7022],{"class":458,"line":7021},71,[456,7023,1328],{"class":626},[447,7025,7028],{"className":731,"code":7026,"filename":7027,"language":463,"meta":452,"style":452},"package config\n\nimport (\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\u002Foutbox\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fserver\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fworker\"\n    \u002F\u002F gpsystem:imports\n)\n\ntype Config struct {\n    Server server.Config\n    DB     dbx.Config `envPrefix:\"DB_\"`\n    Worker worker.Config\n    Outbox outbox.Config `envPrefix:\"OUTBOX_\"`\n    \u002F\u002F gpsystem:config\n}\n","internal\u002Fplatform\u002Fconfig\u002Fconfig.go",[371,7029,7030,7037,7041,7047,7055,7063,7072,7080,7084,7088,7092,7103,7116,7134,7146,7164,7169],{"__ignoreMap":452},[456,7031,7032,7034],{"class":458,"line":459},[456,7033,739],{"class":626},[456,7035,7036],{"class":462}," config\n",[456,7038,7039],{"class":458,"line":492},[456,7040,519],{"emptyLinePlaceholder":518},[456,7042,7043,7045],{"class":458,"line":505},[456,7044,752],{"class":751},[456,7046,755],{"class":626},[456,7048,7049,7051,7053],{"class":458,"line":515},[456,7050,760],{"class":626},[456,7052,1965],{"class":462},[456,7054,633],{"class":626},[456,7056,7057,7059,7061],{"class":458,"line":522},[456,7058,760],{"class":626},[456,7060,816],{"class":462},[456,7062,633],{"class":626},[456,7064,7065,7067,7070],{"class":458,"line":541},[456,7066,760],{"class":626},[456,7068,7069],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fserver",[456,7071,633],{"class":626},[456,7073,7074,7076,7078],{"class":458,"line":560},[456,7075,760],{"class":626},[456,7077,1419],{"class":462},[456,7079,633],{"class":626},[456,7081,7082],{"class":458,"line":578},[456,7083,2109],{"class":501},[456,7085,7086],{"class":458,"line":605},[456,7087,858],{"class":626},[456,7089,7090],{"class":458,"line":636},[456,7091,519],{"emptyLinePlaceholder":518},[456,7093,7094,7096,7099,7101],{"class":458,"line":653},[456,7095,2122],{"class":626},[456,7097,7098],{"class":462}," Config",[456,7100,2128],{"class":626},[456,7102,878],{"class":626},[456,7104,7105,7108,7111,7113],{"class":458,"line":658},[456,7106,7107],{"class":488},"    Server ",[456,7109,7110],{"class":462},"server",[456,7112,402],{"class":626},[456,7114,7115],{"class":462},"Config\n",[456,7117,7118,7121,7123,7125,7127,7129,7132],{"class":458,"line":830},[456,7119,7120],{"class":488},"    DB     ",[456,7122,2153],{"class":462},[456,7124,402],{"class":626},[456,7126,906],{"class":462},[456,7128,3026],{"class":626},[456,7130,7131],{"class":466},"envPrefix:\"DB_\"",[456,7133,3032],{"class":626},[456,7135,7136,7139,7142,7144],{"class":458,"line":835},[456,7137,7138],{"class":488},"    Worker ",[456,7140,7141],{"class":462},"worker",[456,7143,402],{"class":626},[456,7145,7115],{"class":462},[456,7147,7148,7151,7153,7155,7157,7159,7162],{"class":458,"line":845},[456,7149,7150],{"class":488},"    Outbox ",[456,7152,414],{"class":462},[456,7154,402],{"class":626},[456,7156,906],{"class":462},[456,7158,3026],{"class":626},[456,7160,7161],{"class":466},"envPrefix:\"OUTBOX_\"",[456,7163,3032],{"class":626},[456,7165,7166],{"class":458,"line":855},[456,7167,7168],{"class":501},"    \u002F\u002F gpsystem:config\n",[456,7170,7171],{"class":458,"line":861},[456,7172,1328],{"class":626},[447,7174,7179],{"className":7175,"code":7176,"filename":7177,"language":7178,"meta":452,"style":452},"language-tsp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@tag(\"shop\")\ninterface ShopApi {\n  \u002F\u002F gpsystem:operations\n  @get\n  @route(\"\u002Fproducts\")\n  @operationId(\"ListProducts\")\n  @summary(\"List products\")\n  listProducts(...CursorQuery): CursorPage\u003CProduct>;\n\n  @post\n  @route(\"\u002Forders\")\n  @operationId(\"PlaceOrder\")\n  @permission(\"orders.place\")   \u002F\u002F coarse filter: do they hold the right\n  @policy(\"orders.place\")       \u002F\u002F fine filter: are they ordering on their own behalf\n  placeOrder(@body body: PlaceOrderInput): Order | Unauthorized | Forbidden;\n\n  @get\n  @route(\"\u002Forders\u002F{orderId}\")\n  @operationId(\"GetOrder\")\n  @policy(\"orders.view\")        \u002F\u002F owner or admin\n  getOrder(@path orderId: string): Order | NotFound | Unauthorized | Forbidden;\n}\n","spec\u002Ftypespec\u002Fmodules\u002Fshop\u002Fapi.tsp","tsp",[371,7180,7181,7194,7204,7209,7214,7226,7238,7250,7275,7279,7284,7295,7306,7321,7335,7371,7375,7379,7390,7401,7415,7451],{"__ignoreMap":452},[456,7182,7183,7187,7189,7192],{"class":458,"line":459},[456,7184,7186],{"class":7185},"swJcz","@tag",[456,7188,947],{"class":626},[456,7190,7191],{"class":466},"\"shop\"",[456,7193,858],{"class":626},[456,7195,7196,7199,7202],{"class":458,"line":492},[456,7197,7198],{"class":6941},"interface",[456,7200,7201],{"class":462}," ShopApi",[456,7203,878],{"class":626},[456,7205,7206],{"class":458,"line":505},[456,7207,7208],{"class":501},"  \u002F\u002F gpsystem:operations\n",[456,7210,7211],{"class":458,"line":515},[456,7212,7213],{"class":7185},"  @get\n",[456,7215,7216,7219,7221,7224],{"class":458,"line":522},[456,7217,7218],{"class":7185},"  @route",[456,7220,947],{"class":626},[456,7222,7223],{"class":466},"\"\u002Fproducts\"",[456,7225,858],{"class":626},[456,7227,7228,7231,7233,7236],{"class":458,"line":541},[456,7229,7230],{"class":7185},"  @operationId",[456,7232,947],{"class":626},[456,7234,7235],{"class":466},"\"ListProducts\"",[456,7237,858],{"class":626},[456,7239,7240,7243,7245,7248],{"class":458,"line":560},[456,7241,7242],{"class":7185},"  @summary",[456,7244,947],{"class":626},[456,7246,7247],{"class":466},"\"List products\"",[456,7249,858],{"class":626},[456,7251,7252,7255,7258,7261,7264,7267,7270,7272],{"class":458,"line":578},[456,7253,7254],{"class":508},"  listProducts",[456,7256,7257],{"class":626},"(...",[456,7259,7260],{"class":462},"CursorQuery",[456,7262,7263],{"class":626},"):",[456,7265,7266],{"class":462}," CursorPage",[456,7268,7269],{"class":626},"\u003C",[456,7271,5890],{"class":462},[456,7273,7274],{"class":626},">;\n",[456,7276,7277],{"class":458,"line":605},[456,7278,519],{"emptyLinePlaceholder":518},[456,7280,7281],{"class":458,"line":636},[456,7282,7283],{"class":7185},"  @post\n",[456,7285,7286,7288,7290,7293],{"class":458,"line":653},[456,7287,7218],{"class":7185},[456,7289,947],{"class":626},[456,7291,7292],{"class":466},"\"\u002Forders\"",[456,7294,858],{"class":626},[456,7296,7297,7299,7301,7304],{"class":458,"line":658},[456,7298,7230],{"class":7185},[456,7300,947],{"class":626},[456,7302,7303],{"class":466},"\"PlaceOrder\"",[456,7305,858],{"class":626},[456,7307,7308,7311,7313,7316,7318],{"class":458,"line":830},[456,7309,7310],{"class":7185},"  @permission",[456,7312,947],{"class":626},[456,7314,7315],{"class":466},"\"orders.place\"",[456,7317,1020],{"class":626},[456,7319,7320],{"class":501},"   \u002F\u002F coarse filter: do they hold the right\n",[456,7322,7323,7326,7328,7330,7332],{"class":458,"line":835},[456,7324,7325],{"class":7185},"  @policy",[456,7327,947],{"class":626},[456,7329,7315],{"class":466},[456,7331,1020],{"class":626},[456,7333,7334],{"class":501},"       \u002F\u002F fine filter: are they ordering on their own behalf\n",[456,7336,7337,7340,7342,7345,7348,7350,7352,7354,7357,7360,7363,7365,7368],{"class":458,"line":845},[456,7338,7339],{"class":508},"  placeOrder",[456,7341,947],{"class":626},[456,7343,7344],{"class":7185},"@body",[456,7346,7347],{"class":488}," body",[456,7349,1081],{"class":626},[456,7351,4829],{"class":462},[456,7353,7263],{"class":626},[456,7355,7356],{"class":462}," Order",[456,7358,7359],{"class":488}," | ",[456,7361,7362],{"class":462},"Unauthorized",[456,7364,7359],{"class":488},[456,7366,7367],{"class":462},"Forbidden",[456,7369,7370],{"class":626},";\n",[456,7372,7373],{"class":458,"line":855},[456,7374,519],{"emptyLinePlaceholder":518},[456,7376,7377],{"class":458,"line":861},[456,7378,7213],{"class":7185},[456,7380,7381,7383,7385,7388],{"class":458,"line":866},[456,7382,7218],{"class":7185},[456,7384,947],{"class":626},[456,7386,7387],{"class":466},"\"\u002Forders\u002F{orderId}\"",[456,7389,858],{"class":626},[456,7391,7392,7394,7396,7399],{"class":458,"line":881},[456,7393,7230],{"class":7185},[456,7395,947],{"class":626},[456,7397,7398],{"class":466},"\"GetOrder\"",[456,7400,858],{"class":626},[456,7402,7403,7405,7407,7410,7412],{"class":458,"line":912},[456,7404,7325],{"class":7185},[456,7406,947],{"class":626},[456,7408,7409],{"class":466},"\"orders.view\"",[456,7411,1020],{"class":626},[456,7413,7414],{"class":501},"        \u002F\u002F owner or admin\n",[456,7416,7417,7420,7422,7425,7428,7430,7432,7434,7436,7438,7441,7443,7445,7447,7449],{"class":458,"line":931},[456,7418,7419],{"class":508},"  getOrder",[456,7421,947],{"class":626},[456,7423,7424],{"class":7185},"@path",[456,7426,7427],{"class":488}," orderId",[456,7429,1081],{"class":626},[456,7431,3074],{"class":462},[456,7433,7263],{"class":626},[456,7435,7356],{"class":462},[456,7437,7359],{"class":488},[456,7439,7440],{"class":462},"NotFound",[456,7442,7359],{"class":488},[456,7444,7362],{"class":462},[456,7446,7359],{"class":488},[456,7448,7367],{"class":462},[456,7450,7370],{"class":626},[456,7452,7453],{"class":458,"line":966},[456,7454,1328],{"class":626},[447,7456,7461],{"className":7457,"code":7458,"filename":7459,"language":7460,"meta":452,"style":452},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","-- +goose Up\n-- +goose StatementBegin\nCREATE TABLE products (\n    id          bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n    name        text        NOT NULL,\n    price_cents bigint      NOT NULL,\n    stock       int         NOT NULL DEFAULT 0,\n    created_at  timestamptz NOT NULL DEFAULT now()\n);\n\nCREATE TABLE orders (\n    id          bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n    user_id     text        NOT NULL,\n    product_id  bigint      NOT NULL REFERENCES products (id),\n    qty         int         NOT NULL,\n    email       text        NOT NULL,\n    created_at  timestamptz NOT NULL DEFAULT now()\n);\n-- +goose StatementEnd\n\n-- +goose Down\n-- +goose StatementBegin\nDROP TABLE orders;\nDROP TABLE products;\n-- +goose StatementEnd\n","migrations\u002F20260720143012_create_products_and_orders.sql","sql",[371,7462,7463,7468,7473,7485,7510,7523,7535,7552,7570,7575,7579,7589,7607,7619,7634,7645,7656,7670,7674,7679,7683,7688,7692,7702,7711],{"__ignoreMap":452},[456,7464,7465],{"class":458,"line":459},[456,7466,7467],{"class":501},"-- +goose Up\n",[456,7469,7470],{"class":458,"line":492},[456,7471,7472],{"class":501},"-- +goose StatementBegin\n",[456,7474,7475,7478,7481,7483],{"class":458,"line":505},[456,7476,7477],{"class":6941},"CREATE",[456,7479,7480],{"class":6941}," TABLE",[456,7482,4963],{"class":508},[456,7484,755],{"class":488},[456,7486,7487,7490,7493,7496,7499,7502,7505,7508],{"class":458,"line":515},[456,7488,7489],{"class":488},"    id          ",[456,7491,7492],{"class":1023},"bigint",[456,7494,7495],{"class":6941}," GENERATED",[456,7497,7498],{"class":6941}," ALWAYS",[456,7500,7501],{"class":6941}," AS",[456,7503,7504],{"class":6941}," IDENTITY",[456,7506,7507],{"class":1023}," PRIMARY KEY",[456,7509,3373],{"class":488},[456,7511,7512,7515,7518,7521],{"class":458,"line":522},[456,7513,7514],{"class":6941},"    name",[456,7516,7517],{"class":1023},"        text",[456,7519,7520],{"class":6941},"        NOT NULL",[456,7522,3373],{"class":488},[456,7524,7525,7528,7530,7533],{"class":458,"line":541},[456,7526,7527],{"class":488},"    price_cents ",[456,7529,7492],{"class":1023},[456,7531,7532],{"class":6941},"      NOT NULL",[456,7534,3373],{"class":488},[456,7536,7537,7540,7542,7545,7548,7550],{"class":458,"line":560},[456,7538,7539],{"class":488},"    stock       ",[456,7541,5873],{"class":1023},[456,7543,7544],{"class":6941},"         NOT NULL",[456,7546,7547],{"class":1023}," DEFAULT",[456,7549,6942],{"class":6941},[456,7551,3373],{"class":488},[456,7553,7554,7557,7560,7563,7565,7568],{"class":458,"line":578},[456,7555,7556],{"class":488},"    created_at  ",[456,7558,7559],{"class":1023},"timestamptz",[456,7561,7562],{"class":6941}," NOT NULL",[456,7564,7547],{"class":1023},[456,7566,7567],{"class":6941}," now",[456,7569,928],{"class":626},[456,7571,7572],{"class":458,"line":605},[456,7573,7574],{"class":488},");\n",[456,7576,7577],{"class":458,"line":636},[456,7578,519],{"emptyLinePlaceholder":518},[456,7580,7581,7583,7585,7587],{"class":458,"line":653},[456,7582,7477],{"class":6941},[456,7584,7480],{"class":6941},[456,7586,4438],{"class":508},[456,7588,755],{"class":488},[456,7590,7591,7593,7595,7597,7599,7601,7603,7605],{"class":458,"line":658},[456,7592,7489],{"class":488},[456,7594,7492],{"class":1023},[456,7596,7495],{"class":6941},[456,7598,7498],{"class":6941},[456,7600,7501],{"class":6941},[456,7602,7504],{"class":6941},[456,7604,7507],{"class":1023},[456,7606,3373],{"class":488},[456,7608,7609,7612,7615,7617],{"class":458,"line":830},[456,7610,7611],{"class":488},"    user_id     ",[456,7613,7614],{"class":1023},"text",[456,7616,7520],{"class":6941},[456,7618,3373],{"class":488},[456,7620,7621,7624,7626,7628,7631],{"class":458,"line":835},[456,7622,7623],{"class":488},"    product_id  ",[456,7625,7492],{"class":1023},[456,7627,7532],{"class":6941},[456,7629,7630],{"class":1023}," REFERENCES",[456,7632,7633],{"class":488}," products (id),\n",[456,7635,7636,7639,7641,7643],{"class":458,"line":845},[456,7637,7638],{"class":488},"    qty         ",[456,7640,5873],{"class":1023},[456,7642,7544],{"class":6941},[456,7644,3373],{"class":488},[456,7646,7647,7650,7652,7654],{"class":458,"line":855},[456,7648,7649],{"class":488},"    email       ",[456,7651,7614],{"class":1023},[456,7653,7520],{"class":6941},[456,7655,3373],{"class":488},[456,7657,7658,7660,7662,7664,7666,7668],{"class":458,"line":861},[456,7659,7556],{"class":488},[456,7661,7559],{"class":1023},[456,7663,7562],{"class":6941},[456,7665,7547],{"class":1023},[456,7667,7567],{"class":6941},[456,7669,928],{"class":626},[456,7671,7672],{"class":458,"line":866},[456,7673,7574],{"class":488},[456,7675,7676],{"class":458,"line":881},[456,7677,7678],{"class":501},"-- +goose StatementEnd\n",[456,7680,7681],{"class":458,"line":912},[456,7682,519],{"emptyLinePlaceholder":518},[456,7684,7685],{"class":458,"line":931},[456,7686,7687],{"class":501},"-- +goose Down\n",[456,7689,7690],{"class":458,"line":966},[456,7691,7472],{"class":501},[456,7693,7694,7697,7699],{"class":458,"line":971},[456,7695,7696],{"class":6941},"DROP",[456,7698,7480],{"class":6941},[456,7700,7701],{"class":488}," orders;\n",[456,7703,7704,7706,7708],{"class":458,"line":1029},[456,7705,7696],{"class":6941},[456,7707,7480],{"class":6941},[456,7709,7710],{"class":488}," products;\n",[456,7712,7713],{"class":458,"line":1057},[456,7714,7678],{"class":501},[348,7716,369,7717,7719,7720,7723,7724,7727,7728,7731],{},[371,7718,728],{}," above uses the Fiber engine (the default). With ",[371,7721,7722],{},"--engine chi",", only the HTTP entry point and the wiring inside ",[371,7725,7726],{},"register.go","'s ",[371,7729,7730],{},"Register\u003CSurface>"," functions change; everything else in the tree is identical:",[447,7733,7736],{"className":731,"code":7734,"filename":7735,"language":463,"meta":452,"style":452},"package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com\u002Fgo-chi\u002Fchi\u002Fv5\"\n\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fdbx\u002Fpg\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fenvconf\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fevents\u002Foutbox\"\n    \"github.com\u002Fgp-system\u002Fgpsystem\u002Fserver\u002Fchix\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fplatform\u002Fconfig\"\n)\n\nfunc main() {\n    cfg := envconf.MustLoad[config.Config]()\n    ctx := context.Background()\n    pool := pg.MustNewPool(ctx, cfg.DB)\n\n    err := chix.Run(ctx, cfg.Server, func(r chi.Router) error {\n        api := chi.NewRouter()\n        deps := shop.Dependencies{\n            DB:         pg.NewDB(pool),\n            Transactor: pg.NewTransactor(pool),\n            Dispatcher: outbox.NewDispatcher(outbox.NewStore(pg.NewDB(pool))),\n        }\n        shop.RegisterApi(api, deps)\n        shop.RegisterAdmin(api, deps)\n        r.Mount(\"\u002Fapi\u002Fv1\", api)\n        return nil\n    }, chix.WithCloser(\"pgxpool\", func(context.Context) error {\n        pool.Close()\n        return nil\n    }))\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n","cmd\u002Fshop\u002Fmain.go (chi)",[371,7737,7738,7744,7748,7754,7762,7770,7774,7783,7787,7795,7803,7811,7820,7824,7832,7840,7844,7848,7858,7880,7894,7920,7924,7969,7984,7998,8016,8034,8068,8072,8090,8108,8132,8138,8172,8182,8188,8192,8204,8218,8222],{"__ignoreMap":452},[456,7739,7740,7742],{"class":458,"line":459},[456,7741,739],{"class":626},[456,7743,742],{"class":462},[456,7745,7746],{"class":458,"line":492},[456,7747,519],{"emptyLinePlaceholder":518},[456,7749,7750,7752],{"class":458,"line":505},[456,7751,752],{"class":751},[456,7753,755],{"class":626},[456,7755,7756,7758,7760],{"class":458,"line":515},[456,7757,760],{"class":626},[456,7759,763],{"class":462},[456,7761,633],{"class":626},[456,7763,7764,7766,7768],{"class":458,"line":522},[456,7765,760],{"class":626},[456,7767,772],{"class":462},[456,7769,633],{"class":626},[456,7771,7772],{"class":458,"line":541},[456,7773,519],{"emptyLinePlaceholder":518},[456,7775,7776,7778,7781],{"class":458,"line":560},[456,7777,760],{"class":626},[456,7779,7780],{"class":462},"github.com\u002Fgo-chi\u002Fchi\u002Fv5",[456,7782,633],{"class":626},[456,7784,7785],{"class":458,"line":578},[456,7786,519],{"emptyLinePlaceholder":518},[456,7788,7789,7791,7793],{"class":458,"line":605},[456,7790,760],{"class":626},[456,7792,798],{"class":462},[456,7794,633],{"class":626},[456,7796,7797,7799,7801],{"class":458,"line":636},[456,7798,760],{"class":626},[456,7800,807],{"class":462},[456,7802,633],{"class":626},[456,7804,7805,7807,7809],{"class":458,"line":653},[456,7806,760],{"class":626},[456,7808,816],{"class":462},[456,7810,633],{"class":626},[456,7812,7813,7815,7818],{"class":458,"line":658},[456,7814,760],{"class":626},[456,7816,7817],{"class":462},"github.com\u002Fgp-system\u002Fgpsystem\u002Fserver\u002Fchix",[456,7819,633],{"class":626},[456,7821,7822],{"class":458,"line":830},[456,7823,519],{"emptyLinePlaceholder":518},[456,7825,7826,7828,7830],{"class":458,"line":835},[456,7827,760],{"class":626},[456,7829,840],{"class":462},[456,7831,633],{"class":626},[456,7833,7834,7836,7838],{"class":458,"line":845},[456,7835,760],{"class":626},[456,7837,850],{"class":462},[456,7839,633],{"class":626},[456,7841,7842],{"class":458,"line":855},[456,7843,858],{"class":626},[456,7845,7846],{"class":458,"line":861},[456,7847,519],{"emptyLinePlaceholder":518},[456,7849,7850,7852,7854,7856],{"class":458,"line":866},[456,7851,869],{"class":626},[456,7853,872],{"class":508},[456,7855,875],{"class":626},[456,7857,878],{"class":626},[456,7859,7860,7862,7864,7866,7868,7870,7872,7874,7876,7878],{"class":458,"line":881},[456,7861,884],{"class":488},[456,7863,887],{"class":626},[456,7865,890],{"class":488},[456,7867,402],{"class":626},[456,7869,895],{"class":508},[456,7871,898],{"class":626},[456,7873,901],{"class":462},[456,7875,402],{"class":626},[456,7877,906],{"class":462},[456,7879,909],{"class":626},[456,7881,7882,7884,7886,7888,7890,7892],{"class":458,"line":912},[456,7883,915],{"class":488},[456,7885,887],{"class":626},[456,7887,920],{"class":488},[456,7889,402],{"class":626},[456,7891,925],{"class":508},[456,7893,928],{"class":626},[456,7895,7896,7898,7900,7902,7904,7906,7908,7910,7912,7914,7916,7918],{"class":458,"line":931},[456,7897,934],{"class":488},[456,7899,887],{"class":626},[456,7901,939],{"class":488},[456,7903,402],{"class":626},[456,7905,944],{"class":508},[456,7907,947],{"class":626},[456,7909,950],{"class":488},[456,7911,953],{"class":626},[456,7913,956],{"class":488},[456,7915,402],{"class":626},[456,7917,961],{"class":488},[456,7919,858],{"class":626},[456,7921,7922],{"class":458,"line":966},[456,7923,519],{"emptyLinePlaceholder":518},[456,7925,7926,7928,7930,7933,7935,7937,7939,7941,7943,7945,7947,7949,7951,7953,7956,7959,7961,7963,7965,7967],{"class":458,"line":971},[456,7927,974],{"class":488},[456,7929,887],{"class":626},[456,7931,7932],{"class":488}," chix",[456,7934,402],{"class":626},[456,7936,984],{"class":508},[456,7938,947],{"class":626},[456,7940,950],{"class":488},[456,7942,953],{"class":626},[456,7944,956],{"class":488},[456,7946,402],{"class":626},[456,7948,997],{"class":488},[456,7950,953],{"class":626},[456,7952,1002],{"class":626},[456,7954,7955],{"class":1005},"r",[456,7957,7958],{"class":462}," chi",[456,7960,402],{"class":626},[456,7962,2218],{"class":462},[456,7964,1020],{"class":626},[456,7966,1024],{"class":1023},[456,7968,878],{"class":626},[456,7970,7971,7973,7975,7977,7979,7982],{"class":458,"line":1029},[456,7972,1032],{"class":488},[456,7974,887],{"class":626},[456,7976,7958],{"class":488},[456,7978,402],{"class":626},[456,7980,7981],{"class":508},"NewRouter",[456,7983,928],{"class":626},[456,7985,7986,7988,7990,7992,7994,7996],{"class":458,"line":1057},[456,7987,1060],{"class":488},[456,7989,887],{"class":626},[456,7991,479],{"class":462},[456,7993,402],{"class":626},[456,7995,1069],{"class":462},[456,7997,1072],{"class":626},[456,7999,8000,8002,8004,8006,8008,8010,8012,8014],{"class":458,"line":1075},[456,8001,1078],{"class":488},[456,8003,1081],{"class":626},[456,8005,1084],{"class":488},[456,8007,402],{"class":626},[456,8009,1089],{"class":508},[456,8011,947],{"class":626},[456,8013,1094],{"class":488},[456,8015,1097],{"class":626},[456,8017,8018,8020,8022,8024,8026,8028,8030,8032],{"class":458,"line":1100},[456,8019,1103],{"class":488},[456,8021,1081],{"class":626},[456,8023,939],{"class":488},[456,8025,402],{"class":626},[456,8027,1112],{"class":508},[456,8029,947],{"class":626},[456,8031,1094],{"class":488},[456,8033,1097],{"class":626},[456,8035,8036,8038,8040,8042,8044,8046,8048,8050,8052,8054,8056,8058,8060,8062,8064,8066],{"class":458,"line":1121},[456,8037,1124],{"class":488},[456,8039,1081],{"class":626},[456,8041,1129],{"class":488},[456,8043,402],{"class":626},[456,8045,1134],{"class":508},[456,8047,947],{"class":626},[456,8049,414],{"class":488},[456,8051,402],{"class":626},[456,8053,1143],{"class":508},[456,8055,947],{"class":626},[456,8057,1148],{"class":488},[456,8059,402],{"class":626},[456,8061,1089],{"class":508},[456,8063,947],{"class":626},[456,8065,1094],{"class":488},[456,8067,1159],{"class":626},[456,8069,8070],{"class":458,"line":1162},[456,8071,1165],{"class":626},[456,8073,8074,8076,8078,8080,8082,8084,8086,8088],{"class":458,"line":1168},[456,8075,1171],{"class":488},[456,8077,402],{"class":626},[456,8079,1176],{"class":508},[456,8081,947],{"class":626},[456,8083,373],{"class":488},[456,8085,953],{"class":626},[456,8087,1185],{"class":488},[456,8089,858],{"class":626},[456,8091,8092,8094,8096,8098,8100,8102,8104,8106],{"class":458,"line":1190},[456,8093,1171],{"class":488},[456,8095,402],{"class":626},[456,8097,1197],{"class":508},[456,8099,947],{"class":626},[456,8101,373],{"class":488},[456,8103,953],{"class":626},[456,8105,1185],{"class":488},[456,8107,858],{"class":626},[456,8109,8110,8112,8114,8117,8119,8121,8123,8125,8127,8130],{"class":458,"line":1210},[456,8111,4365],{"class":488},[456,8113,402],{"class":626},[456,8115,8116],{"class":508},"Mount",[456,8118,947],{"class":626},[456,8120,1047],{"class":626},[456,8122,1050],{"class":466},[456,8124,1047],{"class":626},[456,8126,953],{"class":626},[456,8128,8129],{"class":488}," api",[456,8131,858],{"class":626},[456,8133,8134,8136],{"class":458,"line":1219},[456,8135,1213],{"class":751},[456,8137,1216],{"class":626},[456,8139,8140,8142,8144,8146,8148,8150,8152,8154,8156,8158,8160,8162,8164,8166,8168,8170],{"class":458,"line":1258},[456,8141,1222],{"class":626},[456,8143,7932],{"class":488},[456,8145,402],{"class":626},[456,8147,1229],{"class":508},[456,8149,947],{"class":626},[456,8151,1047],{"class":626},[456,8153,1236],{"class":466},[456,8155,1047],{"class":626},[456,8157,953],{"class":626},[456,8159,1002],{"class":626},[456,8161,763],{"class":462},[456,8163,402],{"class":626},[456,8165,1249],{"class":462},[456,8167,1020],{"class":626},[456,8169,1024],{"class":1023},[456,8171,878],{"class":626},[456,8173,8174,8176,8178,8180],{"class":458,"line":1271},[456,8175,1261],{"class":488},[456,8177,402],{"class":626},[456,8179,1266],{"class":508},[456,8181,928],{"class":626},[456,8183,8184,8186],{"class":458,"line":1278},[456,8185,1213],{"class":751},[456,8187,1216],{"class":626},[456,8189,8190],{"class":458,"line":1284},[456,8191,1281],{"class":626},[456,8193,8194,8196,8198,8200,8202],{"class":458,"line":1301},[456,8195,1287],{"class":751},[456,8197,1290],{"class":488},[456,8199,1293],{"class":626},[456,8201,1296],{"class":626},[456,8203,878],{"class":626},[456,8205,8206,8208,8210,8212,8214,8216],{"class":458,"line":1319},[456,8207,1304],{"class":488},[456,8209,402],{"class":626},[456,8211,1309],{"class":508},[456,8213,947],{"class":626},[456,8215,1314],{"class":488},[456,8217,858],{"class":626},[456,8219,8220],{"class":458,"line":1325},[456,8221,1322],{"class":626},[456,8223,8224],{"class":458,"line":1874},[456,8225,1328],{"class":626},[348,8227,8228,8229,8232,8233,8236,8237,8239],{},"See the ",[377,8230,8231],{"href":109},"Fiber"," and ",[377,8234,8235],{"href":114},"chi"," pages for the two ",[371,8238,7726],{}," wiring variants.",[357,8241,8243],{"id":8242},"follow-the-order","Follow the order",[348,8245,8246,8247,8250],{},"The path of a ",[371,8248,8249],{},"POST \u002Fapi\u002Fv1\u002Fshop\u002Forders"," request through the system, step by step, with the page that documents each hop:",[8252,8253,8254,8270],"table",{},[8255,8256,8257],"thead",{},[8258,8259,8260,8264,8267],"tr",{},[8261,8262,8263],"th",{},"#",[8261,8265,8266],{},"What happens",[8261,8268,8269],{},"Documented at",[8271,8272,8273,8286,8301,8319,8334,8354,8366],"tbody",{},[8258,8274,8275,8279,8282],{},[8276,8277,8278],"td",{},"1",[8276,8280,8281],{},"The generated code binds and validates the request",[8276,8283,8284],{},[377,8285,123],{"href":124},[8258,8287,8288,8291,8297],{},[8276,8289,8290],{},"2",[8276,8292,8293,8294,8296],{},"The enforcer middleware evaluates the ",[371,8295,4555],{}," permission and policy",[8276,8298,8299],{},[377,8300,213],{"href":214},[8258,8302,8303,8306,8312],{},[8276,8304,8305],{},"3",[8276,8307,8308,8309,8311],{},"The service delegates to the module core; inside ",[371,8310,5113],{},": order insert + stock decrement + outbox row",[8276,8313,8314,8316,8317],{},[377,8315,152],{"href":153},", ",[377,8318,182],{"href":183},[8258,8320,8321,8324,8330],{},[8276,8322,8323],{},"4",[8276,8325,8326,8327,8329],{},"The relay forwards the ",[371,8328,409],{}," event to the Redis queue",[8276,8331,8332],{},[377,8333,173],{"href":174},[8258,8335,8336,8339,8345],{},[8276,8337,8338],{},"5",[8276,8340,8341,8342,8344],{},"The worker fans out to listeners; ",[371,8343,421],{}," sends the e-mail",[8276,8346,8347,8316,8349,8316,8351],{},[377,8348,192],{"href":193},[377,8350,177],{"href":178},[377,8352,8353],{"href":253},"Mail",[8258,8355,8356,8359,8362],{},[8276,8357,8358],{},"6",[8276,8360,8361],{},"The whole path is a single trace, from the HTTP request to the e-mail",[8276,8363,8364],{},[377,8365,232],{"href":233},[8258,8367,8368,8371,8378],{},[8276,8369,8370],{},"7",[8276,8372,8373,8374,8377],{},"On failure: the ",[371,8375,8376],{},"errs"," chain → problem+json to the client, stack to Sentry",[8276,8379,8380,8316,8382],{},[377,8381,78],{"href":79},[377,8383,237],{"href":238},[348,8385,8386,8387,8390],{},"Next step: ",[377,8388,8389],{"href":31},"your first module",", the same journey, sitting at your own machine.",[8392,8393,8394],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}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 .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 .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}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":452,"searchDepth":492,"depth":492,"links":8396},[8397,8398,8399,8400],{"id":359,"depth":492,"text":360},{"id":441,"depth":492,"text":442},{"id":673,"depth":492,"text":674},{"id":8242,"depth":492,"text":8243},"A single worked example project, every code sample in the docs builds on it.","md",null,{},{"icon":43},{"title":40,"description":8401},"V13KLlhZB2-O1IryjPhTAoUEwQJ_JCunJKKibUzxB6k",[8409,8411],{"title":35,"path":36,"stem":37,"description":8410,"icon":38,"children":-1},"The layout of a generated consumer project and the rules behind it.",{"title":52,"path":53,"stem":54,"description":8412,"icon":55,"children":-1},"Every environment variable of every kit config struct, grouped.",1784668705602]