[{"data":1,"prerenderedAt":666},["ShallowReactive",2],{"navigation_docs_en":3,"-en-cli-new-migration":342,"-en-cli-new-migration-surround":661},[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":329,"body":344,"description":654,"extension":655,"links":656,"meta":657,"navigation":658,"path":330,"seo":659,"stem":331,"__hash__":660},"docs_en\u002Fen\u002F9.cli\u002F7.new-migration.md",{"type":345,"value":346,"toc":648},"minimark",[347,393,413,418,421,467,471,489,513,524,528,535,591,602,606,617,635,644],[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","go tool gpsystem new migration \u003Cname>\n","sh","",[355,356,357],"code",{"__ignoreMap":353},[358,359,362,366,370,373,376,379,383,386,390],"span",{"class":360,"line":361},"line",1,[358,363,365],{"class":364},"sBMFI","go",[358,367,369],{"class":368},"sfazB"," tool",[358,371,372],{"class":368}," gpsystem",[358,374,375],{"class":368}," new",[358,377,378],{"class":368}," migration",[358,380,382],{"class":381},"sMK4o"," \u003C",[358,384,385],{"class":368},"nam",[358,387,389],{"class":388},"sTEyZ","e",[358,391,392],{"class":381},">\n",[394,395,396,397,400,401,404,405,412],"p",{},"Run inside a project (the CLI walks up to ",[355,398,399],{},"gpsystem.yaml","). It creates a migration file under ",[355,402,403],{},"migrations\u002F",", stamped with the current time, with an empty goose skeleton: you write the SQL, and the project's ",[406,407,409],"a",{"href":408},"\u002Fen\u002Fdatabase\u002Fmigrations#the-cmdmigrate-binary",[355,410,411],{},"cmd\u002Fmigrate"," binary takes care of running it.",[414,415,417],"h2",{"id":416},"naming","Naming",[394,419,420],{},"The CLI normalizes the name to snake_case: it lowercases and unifies hyphens, underscores and spaces into underscores. The normalized name must consist of lowercase letter\u002Fdigit words (no path separators, dots or a leading digit); anything that does not comply is rejected with an error.",[348,422,424],{"className":350,"code":423,"language":352,"meta":353,"style":353},"go tool gpsystem new migration create_products_and_orders\ngo tool gpsystem new migration \"add index to orders\"   # -> add_index_to_orders\n",[355,425,426,441],{"__ignoreMap":353},[358,427,428,430,432,434,436,438],{"class":360,"line":361},[358,429,365],{"class":364},[358,431,369],{"class":368},[358,433,372],{"class":368},[358,435,375],{"class":368},[358,437,378],{"class":368},[358,439,440],{"class":368}," create_products_and_orders\n",[358,442,444,446,448,450,452,454,457,460,463],{"class":360,"line":443},2,[358,445,365],{"class":364},[358,447,369],{"class":368},[358,449,372],{"class":368},[358,451,375],{"class":368},[358,453,378],{"class":368},[358,455,456],{"class":381}," \"",[358,458,459],{"class":368},"add index to orders",[358,461,462],{"class":381},"\"",[358,464,466],{"class":465},"sHwdD","   # -> add_index_to_orders\n",[414,468,470],{"id":469},"timestamp","Timestamp",[394,472,473,474,477,478,480,481,484,485,488],{},"The command derives a 14-digit ",[355,475,476],{},"YYYYMMDDHHMMSS"," prefix (goose's timestamp scheme) from the current UTC time and puts it in front of the filename. Because it captures the moment of generation, it is guaranteed to sort after everything already in ",[355,479,403],{},", and it never collides across branches. If the directory already has a migration for the exact same second, the command steps forward one second at a time until it finds a free prefix. Generated projects ship with ",[355,482,483],{},"20200101000000_init.sql"," and ",[355,486,487],{},"20200101000100_outbox.sql"," (a fixed, early timestamp), so your first own migration always sorts after them, at the actual time you created it:",[348,490,492],{"className":350,"code":491,"language":352,"meta":353,"style":353},"go tool gpsystem new migration create_products_and_orders\n# Migration created: migrations\u002F20260720143012_create_products_and_orders.sql\n",[355,493,494,508],{"__ignoreMap":353},[358,495,496,498,500,502,504,506],{"class":360,"line":361},[358,497,365],{"class":364},[358,499,369],{"class":368},[358,501,372],{"class":368},[358,503,375],{"class":368},[358,505,378],{"class":368},[358,507,440],{"class":368},[358,509,510],{"class":360,"line":443},[358,511,512],{"class":465},"# Migration created: migrations\u002F20260720143012_create_products_and_orders.sql\n",[394,514,515,516,519,520,523],{},"It also works correctly against an older, sequentially-numbered project (",[355,517,518],{},"00001_init.sql",", ",[355,521,522],{},"00002_outbox.sql","): the command only considers 14-digit timestamp prefixes when checking for collisions, leaves the old sequential files untouched, and goose sorts both numerically, in the right order.",[414,525,527],{"id":526},"what-it-generates","What it generates",[394,529,530,531,534],{},"A single file: ",[355,532,533],{},"migrations\u002F\u003Ctimestamp>_\u003Cname>.sql",", with an empty up\u002Fdown skeleton:",[348,536,540],{"className":537,"code":538,"language":539,"meta":353,"style":353},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","-- +goose Up\n-- +goose StatementBegin\n\n-- +goose StatementEnd\n\n-- +goose Down\n-- +goose StatementBegin\n\n-- +goose StatementEnd\n","sql",[355,541,542,547,552,559,565,570,576,581,586],{"__ignoreMap":353},[358,543,544],{"class":360,"line":361},[358,545,546],{"class":465},"-- +goose Up\n",[358,548,549],{"class":360,"line":443},[358,550,551],{"class":465},"-- +goose StatementBegin\n",[358,553,555],{"class":360,"line":554},3,[358,556,558],{"emptyLinePlaceholder":557},true,"\n",[358,560,562],{"class":360,"line":561},4,[358,563,564],{"class":465},"-- +goose StatementEnd\n",[358,566,568],{"class":360,"line":567},5,[358,569,558],{"emptyLinePlaceholder":557},[358,571,573],{"class":360,"line":572},6,[358,574,575],{"class":465},"-- +goose Down\n",[358,577,579],{"class":360,"line":578},7,[358,580,551],{"class":465},[358,582,584],{"class":360,"line":583},8,[358,585,558],{"emptyLinePlaceholder":557},[358,587,589],{"class":360,"line":588},9,[358,590,564],{"class":465},[394,592,593,594,597,598,601],{},"The global ",[355,595,596],{},"--dry-run"," (prints the plan, writes nothing) and ",[355,599,600],{},"--force"," (overwrite existing files) flags work here too, as on every subcommand.",[414,603,605],{"id":604},"after-generation","After generation",[394,607,608,609,612,613,616],{},"Write the SQL between the markers (the change into the ",[355,610,611],{},"Up"," section, its rollback into ",[355,614,615],{},"Down","), then apply it:",[348,618,620],{"className":350,"code":619,"language":352,"meta":353,"style":353},"go run .\u002Fcmd\u002Fmigrate up\n",[355,621,622],{"__ignoreMap":353},[358,623,624,626,629,632],{"class":360,"line":361},[358,625,365],{"class":364},[358,627,628],{"class":368}," run",[358,630,631],{"class":368}," .\u002Fcmd\u002Fmigrate",[358,633,634],{"class":368}," up\n",[394,636,637,638,640,641,643],{},"The file format, the ",[355,639,411],{}," commands and the deployment patterns are covered on the ",[406,642,157],{"href":158}," page.",[645,646,647],"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}",{"title":353,"searchDepth":443,"depth":443,"links":649},[650,651,652,653],{"id":416,"depth":443,"text":417},{"id":469,"depth":443,"text":470},{"id":526,"depth":443,"text":527},{"id":604,"depth":443,"text":605},"Create a new, timestamp-prefixed SQL migration in the project's migrations\u002F directory.","md",null,{},{"icon":332},{"title":329,"description":654},"3Kw3UWHsRAUy6zYFjRYMaK7qbM_CtPcPN94EBIlionc",[662,664],{"title":324,"path":325,"stem":326,"description":663,"icon":327,"children":-1},"Add an endpoint, TypeSpec operation plus handler method skeleton.",{"title":334,"path":335,"stem":336,"description":665,"icon":195,"children":-1},"add event, add listener, add job and add worker: scaffold background work for the cmd\u002Fworker binary.",1784668714101]