[{"data":1,"prerenderedAt":1740},["ShallowReactive",2],{"navigation_docs_en":3,"-en-cli-new-project":342,"-en-cli-new-project-surround":1735},[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":304,"body":344,"description":1728,"extension":1729,"links":1730,"meta":1731,"navigation":1732,"path":305,"seo":1733,"stem":306,"__hash__":1734},"docs_en\u002Fen\u002F9.cli\u002F2.new-project.md",{"type":345,"value":346,"toc":1713},"minimark",[347,403,412,439,444,574,585,592,604,608,632,637,640,729,754,758,763,1116,1138,1142,1311,1328,1332,1371,1382,1386,1486,1492,1500,1539,1542,1546,1570,1574,1699,1709],[348,349,354],"pre",{"className":350,"code":351,"language":352,"meta":353,"style":353},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","gpsystem new project \u003Cname> --module-path \u003Cgo-module-path> [flags]\n","sh","",[355,356,357],"code",{"__ignoreMap":353},[358,359,362,366,370,373,377,380,384,387,390,392,395,398,400],"span",{"class":360,"line":361},"line",1,[358,363,365],{"class":364},"sBMFI","gpsystem",[358,367,369],{"class":368},"sfazB"," new",[358,371,372],{"class":368}," project",[358,374,376],{"class":375},"sMK4o"," \u003C",[358,378,379],{"class":368},"nam",[358,381,383],{"class":382},"sTEyZ","e",[358,385,386],{"class":375},">",[358,388,389],{"class":368}," --module-path",[358,391,376],{"class":375},[358,393,394],{"class":368},"go-module-pat",[358,396,397],{"class":382},"h",[358,399,386],{"class":375},[358,401,402],{"class":382}," [flags]\n",[404,405,406,407,411],"p",{},"This is how the ",[408,409,410],"a",{"href":41},"shop sample app"," was created too:",[348,413,415],{"className":350,"code":414,"language":352,"meta":353,"style":353},"gpsystem new project shop --module-path github.com\u002Facme\u002Fshop --dir .\u002Fshop\n",[355,416,417],{"__ignoreMap":353},[358,418,419,421,423,425,428,430,433,436],{"class":360,"line":361},[358,420,365],{"class":364},[358,422,369],{"class":368},[358,424,372],{"class":368},[358,426,427],{"class":368}," shop",[358,429,389],{"class":368},[358,431,432],{"class":368}," github.com\u002Facme\u002Fshop",[358,434,435],{"class":368}," --dir",[358,437,438],{"class":368}," .\u002Fshop\n",[440,441,443],"h2",{"id":442},"flags","Flags",[445,446,447,466],"table",{},[448,449,450],"thead",{},[451,452,453,457,460,463],"tr",{},[454,455,456],"th",{},"Flag",[454,458,459],{},"Required",[454,461,462],{},"Default",[454,464,465],{},"Meaning",[467,468,469,490,508,531,551],"tbody",{},[451,470,471,477,480,483],{},[472,473,474],"td",{},[355,475,476],{},"--module-path",[472,478,479],{},"yes",[472,481,482],{},"none",[472,484,485,486,489],{},"the project's Go module path: baked into ",[355,487,488],{},"go.mod"," and every generated import",[451,491,492,497,500,505],{},[472,493,494],{},[355,495,496],{},"--dir",[472,498,499],{},"no",[472,501,502],{},[355,503,504],{},".\u002F\u003Cname>",[472,506,507],{},"target directory",[451,509,510,515,517,522],{},[472,511,512],{},[355,513,514],{},"--engine",[472,516,499],{},[472,518,519],{},[355,520,521],{},"fiber",[472,523,524,525,527,528],{},"HTTP engine of the generated backend: ",[355,526,521],{}," or ",[355,529,530],{},"chi",[451,532,533,538,540,544],{},[472,534,535],{},[355,536,537],{},"--db",[472,539,499],{},[472,541,542],{},[355,543,143],{},[472,545,546,547,527,549],{},"database stack of the generated backend: ",[355,548,143],{},[355,550,148],{},[451,552,553,558,560,562],{},[472,554,555],{},[355,556,557],{},"--kit-replace",[472,559,499],{},[472,561,482],{},[472,563,564,565,568,569,571,572],{},"write a ",[355,566,567],{},"replace"," directive into ",[355,570,488],{}," pointing the kit at a local checkout (a relative path is made absolute); see ",[408,573,25],{"href":26},[404,575,576,577,580,581,584],{},"The global ",[355,578,579],{},"--dry-run"," (print the plan, write nothing) and ",[355,582,583],{},"--force"," (overwrite existing files) flags work here too, as on every subcommand.",[404,586,587,588,591],{},"The project ",[355,589,590],{},"\u003Cname>"," must be lowercase letters\u002Fdigits starting with a letter. It seeds TypeSpec namespaces and appears in generated configs.",[593,594,595,596,598,599,603],"warning",{},"Treat ",[355,597,476],{}," as ",[600,601,602],"strong",{},"permanent",": every generated import builds on it, and every later generator writes it into new files. Changing it afterwards means rewriting all imports, so choose it up front.",[440,605,607],{"id":606},"engine-and-database-choice","Engine and database choice",[404,609,610,611,614,615,618,619,622,623,618,625,618,627,618,629,631],{},"Both decisions are ",[600,612,613],{},"per-project and final",": the manifest records them (",[355,616,617],{},"engine:",", ",[355,620,621],{},"db:","), and every later generator (",[355,624,309],{},[355,626,314],{},[355,628,324],{},[355,630,338],{},") follows them: you pass the flag only once, here.",[633,634,636],"h3",{"id":635},"what-differs-per-engine","What differs per engine",[404,638,639],{},"Business code (handler\u002Fservice\u002Frepository) is identical for both engines; the difference concentrates in three places:",[641,642,643,683,696],"ul",{},[644,645,646,649,650,653,654,656,657,660,661,664,665,668,669,672,673,676,677,618,680,682],"li",{},[600,647,648],{},"The module entry point"," (",[355,651,652],{},"cmd\u002F\u003Cmodule>\u002Fmain.go",", generated by ",[355,655,309],{},"): with Fiber it's ",[355,658,659],{},"fiberx.Run(...)"," and ",[355,662,663],{},"app.Group(\"\u002Fapi\u002Fv1\")","; with chi it's ",[355,666,667],{},"chix.Run(...)",", a sub-router, and ",[355,670,671],{},"r.Mount(\"\u002Fapi\u002Fv1\", api)"," (see ",[408,674,675],{"href":104},"the server lifecycle"," and the two engine pages: ",[408,678,679],{"href":109},"Fiber",[408,681,530],{"href":114},").",[644,684,685,649,688,691,692,695],{},[600,686,687],{},"The oapi-codegen template set",[355,689,690],{},"api\u002Foapi-codegen\u002Ftemplates\u002F","): for Fiber it's the kit's full Fiber v3 template set (upstream oapi-codegen doesn't know v3); for chi it's only a minimal strict override, with routing coming from oapi-codegen's built-in ",[355,693,694],{},"chi-server"," templates.",[644,697,698,705,706,709,710,712,713,716,717,720,721,724,725,728],{},[600,699,700,701,704],{},"The generated ",[355,702,703],{},"gen\u002F"," package and the registration wiring",": the ",[355,707,708],{},"Register\u003CSurface>"," function inserted by ",[355,711,314],{}," takes a ",[355,714,715],{},"fiber.Router"," or a ",[355,718,719],{},"chi.Router",", and the enforcer\u002Fvalidator middleware chain is engine-specific too. The strict handler interface you implement is ",[600,722,723],{},"the same"," for both engines (",[355,726,727],{},"context.Context"," + request object), which is what keeps business code portable.",[404,730,731,732,735,736,738,739,742,743,746,747,746,750,753],{},"Manifests generated before this flag existed (with a ",[355,733,734],{},"router:"," field, or none at all) keep working: ",[355,737,514],{}," used to be called ",[355,740,741],{},"--router",", before the ",[355,744,745],{},"server"," \u002F ",[355,748,749],{},"server\u002Ffiberx",[355,751,752],{},"server\u002Fchix"," split.",[633,755,757],{"id":756},"what-differs-per-database","What differs per database",[404,759,760,762],{},[355,761,537],{}," decides the stack under the repository layer; the pool is pgx in both cases:",[764,765,766,958],"code-group",{},[348,767,772],{"className":768,"code":769,"filename":770,"language":771,"meta":353,"style":353},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F cmd\u002F\u003Cmodule>\u002Fmain.go: deps init\npool := pg.MustNewPool(ctx, cfg.DB)\n\ndeps := shop.Dependencies{\n    DB:         pg.NewDB(pool),\n    Transactor: pg.NewTransactor(pool),\n}\n\n\u002F\u002F register.go\ntype Dependencies struct {\n    DB         *pg.DB\n    Transactor dbx.Transactor\n}\n","pgx (default)","go",[355,773,774,780,819,826,844,869,890,896,901,907,922,939,953],{"__ignoreMap":353},[358,775,776],{"class":360,"line":361},[358,777,779],{"class":778},"sHwdD","\u002F\u002F cmd\u002F\u003Cmodule>\u002Fmain.go: deps init\n",[358,781,783,786,789,792,795,799,802,805,808,811,813,816],{"class":360,"line":782},2,[358,784,785],{"class":382},"pool ",[358,787,788],{"class":375},":=",[358,790,791],{"class":382}," pg",[358,793,794],{"class":375},".",[358,796,798],{"class":797},"s2Zo4","MustNewPool",[358,800,801],{"class":375},"(",[358,803,804],{"class":382},"ctx",[358,806,807],{"class":375},",",[358,809,810],{"class":382}," cfg",[358,812,794],{"class":375},[358,814,815],{"class":382},"DB",[358,817,818],{"class":375},")\n",[358,820,822],{"class":360,"line":821},3,[358,823,825],{"emptyLinePlaceholder":824},true,"\n",[358,827,829,832,834,836,838,841],{"class":360,"line":828},4,[358,830,831],{"class":382},"deps ",[358,833,788],{"class":375},[358,835,427],{"class":364},[358,837,794],{"class":375},[358,839,840],{"class":364},"Dependencies",[358,842,843],{"class":375},"{\n",[358,845,847,850,853,856,858,861,863,866],{"class":360,"line":846},5,[358,848,849],{"class":382},"    DB",[358,851,852],{"class":375},":",[358,854,855],{"class":382},"         pg",[358,857,794],{"class":375},[358,859,860],{"class":797},"NewDB",[358,862,801],{"class":375},[358,864,865],{"class":382},"pool",[358,867,868],{"class":375},"),\n",[358,870,872,875,877,879,881,884,886,888],{"class":360,"line":871},6,[358,873,874],{"class":382},"    Transactor",[358,876,852],{"class":375},[358,878,791],{"class":382},[358,880,794],{"class":375},[358,882,883],{"class":797},"NewTransactor",[358,885,801],{"class":375},[358,887,865],{"class":382},[358,889,868],{"class":375},[358,891,893],{"class":360,"line":892},7,[358,894,895],{"class":375},"}\n",[358,897,899],{"class":360,"line":898},8,[358,900,825],{"emptyLinePlaceholder":824},[358,902,904],{"class":360,"line":903},9,[358,905,906],{"class":778},"\u002F\u002F register.go\n",[358,908,910,913,916,919],{"class":360,"line":909},10,[358,911,912],{"class":375},"type",[358,914,915],{"class":364}," Dependencies",[358,917,918],{"class":375}," struct",[358,920,921],{"class":375}," {\n",[358,923,925,928,931,934,936],{"class":360,"line":924},11,[358,926,927],{"class":382},"    DB         ",[358,929,930],{"class":375},"*",[358,932,933],{"class":364},"pg",[358,935,794],{"class":375},[358,937,938],{"class":364},"DB\n",[358,940,942,945,948,950],{"class":360,"line":941},12,[358,943,944],{"class":382},"    Transactor ",[358,946,947],{"class":364},"dbx",[358,949,794],{"class":375},[358,951,952],{"class":364},"Transactor\n",[358,954,956],{"class":360,"line":955},13,[358,957,895],{"class":375},[348,959,961],{"className":768,"code":960,"filename":148,"language":771,"meta":353,"style":353},"\u002F\u002F cmd\u002F\u003Cmodule>\u002Fmain.go: deps init\npool := pg.MustNewPool(ctx, cfg.DB)\nbunDB := bunx.Open(pool) \u002F\u002F bun query builder over the pgx pool\n\ndeps := shop.Dependencies{\n    DB:         bunDB,\n    Transactor: bunx.NewTransactor(bunDB),\n}\n\n\u002F\u002F register.go\ntype Dependencies struct {\n    DB         *bun.DB\n    Transactor dbx.Transactor\n}\n",[355,962,963,967,993,1018,1022,1036,1048,1067,1071,1075,1079,1089,1101,1111],{"__ignoreMap":353},[358,964,965],{"class":360,"line":361},[358,966,779],{"class":778},[358,968,969,971,973,975,977,979,981,983,985,987,989,991],{"class":360,"line":782},[358,970,785],{"class":382},[358,972,788],{"class":375},[358,974,791],{"class":382},[358,976,794],{"class":375},[358,978,798],{"class":797},[358,980,801],{"class":375},[358,982,804],{"class":382},[358,984,807],{"class":375},[358,986,810],{"class":382},[358,988,794],{"class":375},[358,990,815],{"class":382},[358,992,818],{"class":375},[358,994,995,998,1000,1003,1005,1008,1010,1012,1015],{"class":360,"line":821},[358,996,997],{"class":382},"bunDB ",[358,999,788],{"class":375},[358,1001,1002],{"class":382}," bunx",[358,1004,794],{"class":375},[358,1006,1007],{"class":797},"Open",[358,1009,801],{"class":375},[358,1011,865],{"class":382},[358,1013,1014],{"class":375},")",[358,1016,1017],{"class":778}," \u002F\u002F bun query builder over the pgx pool\n",[358,1019,1020],{"class":360,"line":828},[358,1021,825],{"emptyLinePlaceholder":824},[358,1023,1024,1026,1028,1030,1032,1034],{"class":360,"line":846},[358,1025,831],{"class":382},[358,1027,788],{"class":375},[358,1029,427],{"class":364},[358,1031,794],{"class":375},[358,1033,840],{"class":364},[358,1035,843],{"class":375},[358,1037,1038,1040,1042,1045],{"class":360,"line":871},[358,1039,849],{"class":382},[358,1041,852],{"class":375},[358,1043,1044],{"class":382},"         bunDB",[358,1046,1047],{"class":375},",\n",[358,1049,1050,1052,1054,1056,1058,1060,1062,1065],{"class":360,"line":892},[358,1051,874],{"class":382},[358,1053,852],{"class":375},[358,1055,1002],{"class":382},[358,1057,794],{"class":375},[358,1059,883],{"class":797},[358,1061,801],{"class":375},[358,1063,1064],{"class":382},"bunDB",[358,1066,868],{"class":375},[358,1068,1069],{"class":360,"line":898},[358,1070,895],{"class":375},[358,1072,1073],{"class":360,"line":903},[358,1074,825],{"emptyLinePlaceholder":824},[358,1076,1077],{"class":360,"line":909},[358,1078,906],{"class":778},[358,1080,1081,1083,1085,1087],{"class":360,"line":924},[358,1082,912],{"class":375},[358,1084,915],{"class":364},[358,1086,918],{"class":375},[358,1088,921],{"class":375},[358,1090,1091,1093,1095,1097,1099],{"class":360,"line":941},[358,1092,927],{"class":382},[358,1094,930],{"class":375},[358,1096,148],{"class":364},[358,1098,794],{"class":375},[358,1100,938],{"class":364},[358,1102,1103,1105,1107,1109],{"class":360,"line":955},[358,1104,944],{"class":382},[358,1106,947],{"class":364},[358,1108,794],{"class":375},[358,1110,952],{"class":364},[358,1112,1114],{"class":360,"line":1113},14,[358,1115,895],{"class":375},[404,1117,1118,1119,1122,1123,649,1126,1129,1130,1133,1134,660,1136,682],{},"The same difference shows up in ",[355,1120,1121],{},"cmd\u002Fworker\u002Fmain.go"," and in the outbox store wired by ",[355,1124,1125],{},"add event",[355,1127,1128],{},"outbox.NewStore(pg.NewDB(pool))"," ↔ ",[355,1131,1132],{},"outbox\u002Fbunx.NewStore(bunDB)","). The repository templates emit SQL with pgx and query-builder calls with bun (see ",[408,1135,143],{"href":144},[408,1137,148],{"href":149},[440,1139,1141],{"id":1140},"what-it-generates","What it generates",[641,1143,1144,1161,1170,1188,1194,1214,1227,1244],{},[644,1145,1146,1149,1150,1153,1154,618,1157,1160],{},[355,1147,1148],{},"gpsystem.yaml"," ",[408,1151,1152],{"href":272},"manifest"," (name, module path, ",[355,1155,1156],{},"engine",[355,1158,1159],{},"db",", kit version, template checksum)",[644,1162,1163,1165,1166,1169],{},[355,1164,488],{}," with the kit dependency and ",[355,1167,1168],{},"tool"," directives (gpsystem, oapi-codegen), so every teammate runs the same CLI version",[644,1171,1172,1173,618,1176,1179,1180,1183,1184,1187],{},"TypeSpec workspace: ",[355,1174,1175],{},"spec\u002Ftypespec\u002F{main.tsp, shared\u002Ferrors.tsp, shared\u002Fpaginator.tsp, lib\u002Fpolicy.tsp}",[355,1177,1178],{},"tspconfig.yaml"," (pinned to OpenAPI 3.0, output to ",[355,1181,1182],{},"api\u002Fopenapi\u002F","), ",[355,1185,1186],{},"package.json"," with a pinned TypeSpec compiler",[644,1189,1190,1191,1193],{},"The kit's oapi-codegen templates at ",[355,1192,690],{}," (per engine, see above)",[644,1195,1196,1199,1200,1203,1204,1203,1206,1203,1208,1210,1211],{},[355,1197,1198],{},"internal\u002Fplatform\u002Fconfig\u002Fconfig.go",": composed env config (",[355,1201,1202],{},"Server"," + ",[355,1205,815],{},[355,1207,192],{},[355,1209,182],{},"), loaded with ",[408,1212,1213],{"href":83},"envconf",[644,1215,1216,1218,1219,1222,1223,1226],{},[355,1217,1121],{},": the background-processing binary (",[408,1220,1221],{"href":193},"worker","); ",[355,1224,1225],{},"cmd\u002Fmigrate\u002Fmain.go",": the migration runner",[644,1228,1229,1232,1233,1203,1236,1239,1240,1243],{},[355,1230,1231],{},"migrations\u002F",": embedded, timestamp-prefixed goose SQL, starting with ",[355,1234,1235],{},"20200101000000_init.sql",[355,1237,1238],{},"20200101000100_outbox.sql"," (the ",[408,1241,1242],{"href":183},"outbox"," table)",[644,1245,1246,1249,1250,618,1253,618,1256,618,1259,618,1262,618,1265,618,1268,618,1271,618,1273,618,1276,618,1279,618,1282,618,1285,1183,1288,1291,1292,618,1295,1298,1299,618,1302,618,1305,618,1308],{},[355,1247,1248],{},"mise.toml"," tasks (",[355,1251,1252],{},"setup",[355,1254,1255],{},"spec",[355,1257,1258],{},"generate",[355,1260,1261],{},"dev",[355,1263,1264],{},"dev:deps",[355,1266,1267],{},"restart",[355,1269,1270],{},"dev:down",[355,1272,1221],{},[355,1274,1275],{},"migrate",[355,1277,1278],{},"logs",[355,1280,1281],{},"build",[355,1283,1284],{},"test",[355,1286,1287],{},"lint",[355,1289,1290],{},"Dockerfile"," (multi-stage, see below), ",[355,1293,1294],{},".dockerignore",[355,1296,1297],{},"compose.yml"," (the full dev stack, see below), ",[355,1300,1301],{},".env.example",[355,1303,1304],{},".golangci.yml",[355,1306,1307],{},".gitignore",[355,1309,1310],{},"README.md",[404,1312,1313,1314,1316,1317,1319,1320,1324,1325,1327],{},"The HTTP-side entry point (",[355,1315,652],{},") is created not by ",[355,1318,304],{}," but by the first ",[408,1321,1322],{"href":310},[355,1323,309],{},": one binary per module, and ",[355,1326,309],{}," inserts its compose service too.",[440,1329,1331],{"id":1330},"the-compose-dev-stack","The compose dev stack",[404,1333,700,1334,1336,1337,1340,1341,1343,1344,1346,1347,1349,1350,1356,1357,1360,1361,1343,1364,1367,1368,682],{},[355,1335,1297],{}," is a full, containerized dev stack (",[600,1338,1339],{},"zero published ports","): postgres, redis, mailpit, rustfs (S3-compatible object storage), and the ",[355,1342,1275],{},"\u002F",[355,1345,1221],{},"\u002Fmodule binaries, all built from the project's ",[355,1348,1290],{},", all exposed via ",[408,1351,1355],{"href":1352,"rel":1353},"https:\u002F\u002Ftraefik.io",[1354],"nofollow","Traefik"," labels on the external ",[355,1358,1359],{},"proxynet"," network (dual ",[355,1362,1363],{},"web",[355,1365,1366],{},"websecure"," routers, ",[355,1369,1370],{},"tls.certresolver=letsEncrypt",[404,1372,1373,1374,1377,1378,1381],{},"Prerequisite: ",[355,1375,1376],{},"docker network create proxynet"," (one-time, shared across the workspace), docker compose ≥ 2.17 + BuildKit (for ",[355,1379,1380],{},"additional_contexts"," and the cache mounts).",[633,1383,1385],{"id":1384},"dockerfile-four-stages","Dockerfile: four stages",[641,1387,1388,1403,1456,1472],{},[644,1389,1390,1395,1396,1399,1400,794],{},[600,1391,1392],{},[355,1393,1394],{},"base",": ",[355,1397,1398],{},"golang:1.25-alpine",", just the ",[355,1401,1402],{},"WORKDIR",[644,1404,1405,1410,1411,1414,1415,1343,1418,1421,1422,1425,1426,1183,1429,1432,1433,1440,1441,1444,1445,1448,1449,1343,1452,1455],{},[600,1406,1407],{},[355,1408,1409],{},"development",": what compose builds (",[355,1412,1413],{},"target: development","); a host-matched UID\u002FGID user (",[355,1416,1417],{},"USER_ID",[355,1419,1420],{},"GROUP_ID"," build args from ",[355,1423,1424],{},".env","), the source bind-mounted (",[355,1427,1428],{},".:\u002Fsrc",[355,1430,1431],{},"CMD [\"sh\", \"-c\", \"exec go run .\u002Fcmd\u002F${CMD}\"]",". ",[600,1434,1435,1436,1439],{},"No source copy, no ",[355,1437,1438],{},"go mod download"," at build time",": after a code change, ",[355,1442,1443],{},"docker compose restart \u003Cservice>"," is enough, ",[355,1446,1447],{},"go run"," recompiles from the mounted source; the module caches (",[355,1450,1451],{},"gomodcache",[355,1453,1454],{},"gocache",") live on named volumes so the restart-recompile stays fast.",[644,1457,1458,1395,1462,1203,1465,1468,1469,682],{},[600,1459,1460],{},[355,1461,1281],{},[355,1463,1464],{},"ARG CMD",[355,1466,1467],{},"go build .\u002Fcmd\u002F${CMD}",", with cache mounts; the prod image is built from this (",[355,1470,1471],{},"docker build --target production --build-arg CMD=\u003Cx> .",[644,1473,1474,1395,1479,618,1482,1485],{},[600,1475,1476],{},[355,1477,1478],{},"production",[355,1480,1481],{},"alpine:3.22",[355,1483,1484],{},"USER nobody",", just the compiled binary.",[633,1487,1489,1491],{"id":1488},"kit-replace-in-compose",[355,1490,557],{}," in compose",[404,1493,1494,1495,1149,1497,1499],{},"A ",[355,1496,488],{},[355,1498,567],{}," directive is invisible to the build context: two separate mechanisms handle it:",[641,1501,1502,1517],{},[644,1503,1504,1509,1510,1512,1513,1516],{},[600,1505,1506,1508],{},[355,1507,1409],{}," target",": the kit checkout is bind-mounted too, at the same absolute path the ",[355,1511,488],{}," points at (",[355,1514,1515],{},"\u003Ckit-checkout>:\u003Ckit-checkout>:ro","), a runtime mount, no build-time copy; editing the kit only needs a restart too.",[644,1518,1519,1525,1526,1529,1530,1532,1533,1536,1537,794],{},[600,1520,1521,1343,1523,1508],{},[355,1522,1281],{},[355,1524,1478],{},": compose ",[355,1527,1528],{},"additional_contexts: {kit: \u003Cpath>}",", the Dockerfile's ",[355,1531,1281],{}," stage does ",[355,1534,1535],{},"COPY --from=kit \u002F \u003Cpath>"," before ",[355,1538,1438],{},[404,1540,1541],{},"Neither block is generated for a non-replace (published-kit) project.",[633,1543,1545],{"id":1544},"module-routing-path-based-not-subdomain","Module routing: path-based, not subdomain",[404,1547,1548,1549,1552,1553,1556,1557,1560,1561,1564,1565,1569],{},"The module service's Traefik rule is ",[355,1550,1551],{},"Host(`${APP_HOST}`) && PathRegexp(`^\u002Fapi\u002Fv1\u002F([a-z0-9-]+\u002F)?\u003Cmodule>(\u002F|$)`)","; this covers both the ",[355,1554,1555],{},"api"," surface's ",[355,1558,1559],{},"\u002Fapi\u002Fv1\u002F\u003Cmodule>"," and every other surface's ",[355,1562,1563],{},"\u002Fapi\u002Fv1\u002F\u003Csurface>\u002F\u003Cmodule>"," route, so ",[408,1566,1567],{"href":315},[355,1568,314],{}," never needs to touch it.",[440,1571,1573],{"id":1572},"after-generation","After generation",[348,1575,1577],{"className":350,"code":1576,"language":352,"meta":353,"style":353},"cd \u003Cname>\ngo mod tidy        # resolves deps + tool directives\nmise run setup     # TypeSpec toolchain (npm)\ngo tool gpsystem new module \u003Cfirst-module>\nmise run generate  # tsp → OpenAPI → server code → build\ncp .env.example .env               # set USER_ID\u002FGROUP_ID to id -u \u002F id -g\ndocker network create proxynet     # one-time\nmise run dev                       # build + start the full dev stack\n",[355,1578,1579,1593,1606,1620,1644,1656,1670,1687],{"__ignoreMap":353},[358,1580,1581,1584,1586,1588,1590],{"class":360,"line":361},[358,1582,1583],{"class":797},"cd",[358,1585,376],{"class":375},[358,1587,379],{"class":368},[358,1589,383],{"class":382},[358,1591,1592],{"class":375},">\n",[358,1594,1595,1597,1600,1603],{"class":360,"line":782},[358,1596,771],{"class":364},[358,1598,1599],{"class":368}," mod",[358,1601,1602],{"class":368}," tidy",[358,1604,1605],{"class":778},"        # resolves deps + tool directives\n",[358,1607,1608,1611,1614,1617],{"class":360,"line":821},[358,1609,1610],{"class":364},"mise",[358,1612,1613],{"class":368}," run",[358,1615,1616],{"class":368}," setup",[358,1618,1619],{"class":778},"     # TypeSpec toolchain (npm)\n",[358,1621,1622,1624,1627,1630,1632,1635,1637,1640,1642],{"class":360,"line":828},[358,1623,771],{"class":364},[358,1625,1626],{"class":368}," tool",[358,1628,1629],{"class":368}," gpsystem",[358,1631,369],{"class":368},[358,1633,1634],{"class":368}," module",[358,1636,376],{"class":375},[358,1638,1639],{"class":368},"first-modul",[358,1641,383],{"class":382},[358,1643,1592],{"class":375},[358,1645,1646,1648,1650,1653],{"class":360,"line":846},[358,1647,1610],{"class":364},[358,1649,1613],{"class":368},[358,1651,1652],{"class":368}," generate",[358,1654,1655],{"class":778},"  # tsp → OpenAPI → server code → build\n",[358,1657,1658,1661,1664,1667],{"class":360,"line":871},[358,1659,1660],{"class":364},"cp",[358,1662,1663],{"class":368}," .env.example",[358,1665,1666],{"class":368}," .env",[358,1668,1669],{"class":778},"               # set USER_ID\u002FGROUP_ID to id -u \u002F id -g\n",[358,1671,1672,1675,1678,1681,1684],{"class":360,"line":892},[358,1673,1674],{"class":364},"docker",[358,1676,1677],{"class":368}," network",[358,1679,1680],{"class":368}," create",[358,1682,1683],{"class":368}," proxynet",[358,1685,1686],{"class":778},"     # one-time\n",[358,1688,1689,1691,1693,1696],{"class":360,"line":898},[358,1690,1610],{"class":364},[358,1692,1613],{"class":368},[358,1694,1695],{"class":368}," dev",[358,1697,1698],{"class":778},"                       # build + start the full dev stack\n",[404,1700,1701,1702,1705,1706,1708],{},"From here the CLI runs as the version pinned into the project (",[355,1703,1704],{},"go tool gpsystem","), and the ",[408,1707,1152],{"href":272}," tells it which engine and database to generate for.",[1710,1711,1712],"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .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 .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}",{"title":353,"searchDepth":782,"depth":782,"links":1714},[1715,1716,1720,1721,1727],{"id":442,"depth":782,"text":443},{"id":606,"depth":782,"text":607,"children":1717},[1718,1719],{"id":635,"depth":821,"text":636},{"id":756,"depth":821,"text":757},{"id":1140,"depth":782,"text":1141},{"id":1330,"depth":782,"text":1331,"children":1722},[1723,1724,1726],{"id":1384,"depth":821,"text":1385},{"id":1488,"depth":821,"text":1725},"--kit-replace in compose",{"id":1544,"depth":821,"text":1545},{"id":1572,"depth":782,"text":1573},"Generate a complete consumer project skeleton, with engine and database choices.","md",null,{},{"icon":307},{"title":304,"description":1728},"Tp87RnctsWD-EAXHpm-YnDULPHh_SoHdfOwimDdiESI",[1736,1738],{"title":300,"path":301,"stem":302,"description":1737,"icon":165,"children":-1},"Add a seeder to the project's central seeds\u002F package, registered automatically.",{"title":309,"path":310,"stem":311,"description":1739,"icon":312,"children":-1},"Generate a module (entry point, first surface, contract) into the current project.",1784668713145]