[{"data":1,"prerenderedAt":1263},["ShallowReactive",2],{"docs-navigation":3,"\u002Fdocs\u002Fdevelopment\u002Frelease-process":231,"\u002Fdocs\u002Fdevelopment\u002Frelease-process-surround":1258},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,12,16,20,69,90,123,144,165,190],{"title":10,"path":6,"stem":11},"Gerbtrace Documentation","docs\u002Findex",{"title":13,"path":14,"stem":15},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",{"title":17,"path":18,"stem":19},"Licensing","\u002Fdocs\u002Flicensing","docs\u002F2.licensing",{"title":21,"path":22,"stem":23,"children":24,"page":68},"Viewer","\u002Fdocs\u002Fviewer","docs\u002F3.viewer",[25,29,33,37,41,45,49,53,56,60,64],{"title":26,"path":27,"stem":28},"Files","\u002Fdocs\u002Fviewer\u002Ffiles","docs\u002F3.viewer\u002F01.files",{"title":30,"path":31,"stem":32},"PCB","\u002Fdocs\u002Fviewer\u002Fpcb","docs\u002F3.viewer\u002F02.pcb",{"title":34,"path":35,"stem":36},"Panel","\u002Fdocs\u002Fviewer\u002Fpanel","docs\u002F3.viewer\u002F03.panel",{"title":38,"path":39,"stem":40},"Paste","\u002Fdocs\u002Fviewer\u002Fpaste","docs\u002F3.viewer\u002F04.paste",{"title":42,"path":43,"stem":44},"SMD","\u002Fdocs\u002Fviewer\u002Fsmd","docs\u002F3.viewer\u002F05.smd",{"title":46,"path":47,"stem":48},"THT","\u002Fdocs\u002Fviewer\u002Ftht","docs\u002F3.viewer\u002F06.tht",{"title":50,"path":51,"stem":52},"BOM","\u002Fdocs\u002Fviewer\u002Fbom","docs\u002F3.viewer\u002F07.bom",{"title":5,"path":54,"stem":55},"\u002Fdocs\u002Fviewer\u002Fdocs","docs\u002F3.viewer\u002F08.docs",{"title":57,"path":58,"stem":59},"Conversation","\u002Fdocs\u002Fviewer\u002Fconversation","docs\u002F3.viewer\u002F09.conversation",{"title":61,"path":62,"stem":63},"Summary","\u002Fdocs\u002Fviewer\u002Fsummary","docs\u002F3.viewer\u002F10.summary",{"title":65,"path":66,"stem":67},"Pricing","\u002Fdocs\u002Fviewer\u002Fpricing","docs\u002F3.viewer\u002F11.pricing",false,{"title":70,"path":71,"stem":72,"children":73,"page":68},"Tools","\u002Fdocs\u002Ftools","docs\u002F4.tools",[74,78,82,86],{"title":75,"path":76,"stem":77},"Exports","\u002Fdocs\u002Ftools\u002Fexports","docs\u002F4.tools\u002F1.exports",{"title":79,"path":80,"stem":81},"Compare","\u002Fdocs\u002Ftools\u002Fcompare","docs\u002F4.tools\u002F2.compare",{"title":83,"path":84,"stem":85},"Package Manager","\u002Fdocs\u002Ftools\u002Fpackage-manager","docs\u002F4.tools\u002F3.package-manager",{"title":87,"path":88,"stem":89},"Draw Tool","\u002Fdocs\u002Ftools\u002Fdraw-tool","docs\u002F4.tools\u002F4.draw-tool",{"title":91,"path":92,"stem":93,"children":94,"page":68},"Collaboration","\u002Fdocs\u002Fcollaboration","docs\u002F5.collaboration",[95,99,103,107,111,115,119],{"title":96,"path":97,"stem":98},"Team Settings","\u002Fdocs\u002Fcollaboration\u002Fteam-settings","docs\u002F5.collaboration\u002F1.team-settings",{"title":100,"path":101,"stem":102},"Team Members","\u002Fdocs\u002Fcollaboration\u002Fteam-members","docs\u002F5.collaboration\u002F2.team-members",{"title":104,"path":105,"stem":106},"User Profile","\u002Fdocs\u002Fcollaboration\u002Fuser-profile","docs\u002F5.collaboration\u002F3.user-profile",{"title":108,"path":109,"stem":110},"Spaces","\u002Fdocs\u002Fcollaboration\u002Fspaces","docs\u002F5.collaboration\u002F4.spaces",{"title":112,"path":113,"stem":114},"Notifications","\u002Fdocs\u002Fcollaboration\u002Fnotifications","docs\u002F5.collaboration\u002F6.notifications",{"title":116,"path":117,"stem":118},"Plans & Billing","\u002Fdocs\u002Fcollaboration\u002Fplans-and-billing","docs\u002F5.collaboration\u002F7.plans-and-billing",{"title":120,"path":121,"stem":122},"Connected Apps & MCP","\u002Fdocs\u002Fcollaboration\u002Fconnected-apps","docs\u002F5.collaboration\u002F8.connected-apps",{"title":124,"path":125,"stem":126,"children":127,"page":68},"App","\u002Fdocs\u002Fapp","docs\u002F6.app",[128,132,136,140],{"title":129,"path":130,"stem":131},"Desktop App","\u002Fdocs\u002Fapp\u002Fdesktop","docs\u002F6.app\u002F1.desktop",{"title":133,"path":134,"stem":135},"Light & Dark Mode","\u002Fdocs\u002Fapp\u002Flight-dark-mode","docs\u002F6.app\u002F2.light-dark-mode",{"title":137,"path":138,"stem":139},"Performance Monitor","\u002Fdocs\u002Fapp\u002Fperformance-monitor","docs\u002F6.app\u002F3.performance-monitor",{"title":141,"path":142,"stem":143},"Report a Bug","\u002Fdocs\u002Fapp\u002Freport-a-bug","docs\u002F6.app\u002F4.report-a-bug",{"title":145,"path":146,"stem":147,"children":148,"page":68},"Guides","\u002Fdocs\u002Fguides","docs\u002F7.guides",[149,153,157,161],{"title":150,"path":151,"stem":152},"Importing Files","\u002Fdocs\u002Fguides\u002Fimporting-files","docs\u002F7.guides\u002F1.importing-files",{"title":154,"path":155,"stem":156},"Supported Formats","\u002Fdocs\u002Fguides\u002Fsupported-formats","docs\u002F7.guides\u002F2.supported-formats",{"title":158,"path":159,"stem":160},"Package Library","\u002Fdocs\u002Fguides\u002Fpackage-library","docs\u002F7.guides\u002F3.package-library",{"title":162,"path":163,"stem":164},"Panel Checks","\u002Fdocs\u002Fguides\u002Fpanel-checks","docs\u002F7.guides\u002F4.panel-checks",{"title":166,"path":167,"stem":168,"children":169,"page":68},"Reference","\u002Fdocs\u002Freference","docs\u002F8.reference",[170,174,178,182,186],{"title":171,"path":172,"stem":173},"BOM File Format","\u002Fdocs\u002Freference\u002Fbom-format","docs\u002F8.reference\u002F1.bom-format",{"title":175,"path":176,"stem":177},"Package Definitions","\u002Fdocs\u002Freference\u002Fpackage-definitions","docs\u002F8.reference\u002F2.package-definitions",{"title":179,"path":180,"stem":181},"Package Naming","\u002Fdocs\u002Freference\u002Fpackage-naming","docs\u002F8.reference\u002F3.package-naming",{"title":183,"path":184,"stem":185},"TPSys Format","\u002Fdocs\u002Freference\u002Ftpsys-format","docs\u002F8.reference\u002F4.tpsys-format",{"title":187,"path":188,"stem":189},"Jet Printing","\u002Fdocs\u002Freference\u002Fjet-printing","docs\u002F8.reference\u002F5.jet-printing",{"title":191,"path":192,"stem":193,"children":194,"page":68},"Development","\u002Fdocs\u002Fdevelopment","docs\u002F9.development",[195,199,203,207,211,215,219,223,227],{"title":196,"path":197,"stem":198},"Development Setup","\u002Fdocs\u002Fdevelopment\u002Fsetup","docs\u002F9.development\u002F1.setup",{"title":200,"path":201,"stem":202},"Architecture","\u002Fdocs\u002Fdevelopment\u002Farchitecture","docs\u002F9.development\u002F2.architecture",{"title":204,"path":205,"stem":206},"CAD Libraries","\u002Fdocs\u002Fdevelopment\u002Fcad-libraries","docs\u002F9.development\u002F3.cad-libraries",{"title":208,"path":209,"stem":210},"Release Process","\u002Fdocs\u002Fdevelopment\u002Frelease-process","docs\u002F9.development\u002F4.release-process",{"title":212,"path":213,"stem":214},"Error Monitoring","\u002Fdocs\u002Fdevelopment\u002Ferror-monitoring","docs\u002F9.development\u002F5.error-monitoring",{"title":216,"path":217,"stem":218},"Contributing","\u002Fdocs\u002Fdevelopment\u002Fcontributing","docs\u002F9.development\u002F6.contributing",{"title":220,"path":221,"stem":222},"Commit Conventions","\u002Fdocs\u002Fdevelopment\u002Fcommit-conventions","docs\u002F9.development\u002F7.commit-conventions",{"title":224,"path":225,"stem":226},"Sidebar Design","\u002Fdocs\u002Fdevelopment\u002Fsidebar-design","docs\u002F9.development\u002F8.sidebar-design",{"title":228,"path":229,"stem":230},"Operational Runbooks","\u002Fdocs\u002Fdevelopment\u002Frunbooks","docs\u002F9.development\u002F9.runbooks",{"id":232,"title":208,"body":233,"description":1252,"extension":1253,"links":1254,"meta":1255,"navigation":927,"path":209,"seo":1256,"stem":210,"__hash__":1257},"docs\u002Fdocs\u002F9.development\u002F4.release-process.md",{"type":234,"value":235,"toc":1230},"minimark",[236,240,244,290,301,306,317,346,360,364,367,402,409,413,484,491,534,545,549,558,575,578,582,639,644,647,673,677,683,719,723,740,743,747,751,780,786,789,803,806,815,818,861,864,884,888,891,909,913,916,1027,1031,1034,1110,1121,1125,1136,1140,1219,1223,1226],[237,238,208],"h1",{"id":239},"release-process",[241,242,243],"p",{},"Gerbtrace has three deployable surfaces:",[245,246,247,264,274],"ul",{},[248,249,250,254,255,258,259,263],"li",{},[251,252,253],"strong",{},"Web app"," — a Nuxt app deployed on ",[251,256,257],{},"Cloudflare Workers"," (",[260,261,262],"code",{},"gerbtrace.com",")",[248,265,266,269,270,273],{},[251,267,268],{},"Desktop app"," — Tauri 2 builds for macOS\u002FWindows shipped via ",[251,271,272],{},"GitHub Releases"," with the Tauri updater",[248,275,276,279,280,283,284,258,287,263],{},[251,277,278],{},"API server"," — ",[251,281,282],{},"Supabase Cloud"," project ",[260,285,286],{},"gqrnlnlfidighosujpdb",[260,288,289],{},"https:\u002F\u002Fgqrnlnlfidighosujpdb.supabase.co",[241,291,292,293,296,297,300],{},"Architecture and operations decisions are tracked in ",[260,294,295],{},"docs\u002Fadr\u002F",". See\n",[260,298,299],{},"docs\u002Fadr\u002FREADME.md"," for the decision log and ADR-005 for deployment authority.",[302,303,305],"h2",{"id":304},"environment-variables","Environment variables",[241,307,308,309,312,313,316],{},"For local development, copy ",[260,310,311],{},".env.example"," to ",[260,314,315],{},".env"," and set:",[245,318,319,338],{},[248,320,321,279,326,328,329,332,333,263],{},[251,322,323],{},[260,324,325],{},"SUPABASE_URL",[260,327,289],{}," (or ",[260,330,331],{},"http:\u002F\u002F127.0.0.1:54321"," when using ",[334,335,337],"a",{"href":336},"\u002Fdocs\u002Fdevelopment\u002Fsetup#local-supabase-development","Local Supabase development",[248,339,340,345],{},[251,341,342],{},[260,343,344],{},"SUPABASE_ANON_KEY"," — Supabase anon key (JWT)",[241,347,348,349,352,353,356,357,359],{},"The Nuxt runtime config also accepts ",[260,350,351],{},"NUXT_PUBLIC_SUPABASE_URL"," and ",[260,354,355],{},"NUXT_PUBLIC_SUPABASE_ANON_KEY"," (same values). Never commit ",[260,358,315],{}," (it is gitignored). Treat service-role keys and SMTP credentials as secrets.",[302,361,363],{"id":362},"version-bump","Version bump",[241,365,366],{},"Update the version in all four files:",[368,369,370,379,386,394],"ol",{},[248,371,372,375,376],{},[260,373,374],{},"package.json"," – ",[260,377,378],{},"\"version\"",[248,380,381,375,384],{},[260,382,383],{},"src-tauri\u002Ftauri.conf.json",[260,385,378],{},[248,387,388,375,391],{},[260,389,390],{},"src-tauri\u002FCargo.toml",[260,392,393],{},"version",[248,395,396,375,399],{},[260,397,398],{},"nuxt.config.ts",[260,400,401],{},"runtimeConfig.public.appVersion",[241,403,404,405,408],{},"All four must match for the release to be consistent. ",[260,406,407],{},"pnpm run version:check","\nverifies this locally and in CI.",[302,410,412],{"id":411},"tag-and-release","Tag and release",[414,415,420],"pre",{"className":416,"code":417,"language":418,"meta":419,"style":419},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git add -A && git commit -m \"Release vX.Y.Z\"\ngit tag vX.Y.Z\ngit push origin vX.Y.Z\n","bash","",[260,421,422,460,471],{"__ignoreMap":419},[423,424,427,431,435,438,442,445,448,451,454,457],"span",{"class":425,"line":426},"line",1,[423,428,430],{"class":429},"sBMFI","git",[423,432,434],{"class":433},"sfazB"," add",[423,436,437],{"class":433}," -A",[423,439,441],{"class":440},"sMK4o"," &&",[423,443,444],{"class":429}," git",[423,446,447],{"class":433}," commit",[423,449,450],{"class":433}," -m",[423,452,453],{"class":440}," \"",[423,455,456],{"class":433},"Release vX.Y.Z",[423,458,459],{"class":440},"\"\n",[423,461,463,465,468],{"class":425,"line":462},2,[423,464,430],{"class":429},[423,466,467],{"class":433}," tag",[423,469,470],{"class":433}," vX.Y.Z\n",[423,472,474,476,479,482],{"class":425,"line":473},3,[423,475,430],{"class":429},[423,477,478],{"class":433}," push",[423,480,481],{"class":433}," origin",[423,483,470],{"class":433},[241,485,486,487,490],{},"GitHub Actions builds signed macOS and Windows installers in the private source repository when a ",[260,488,489],{},"v*"," tag is pushed. After both jobs pass, mirror the binaries to the public release repository:",[414,492,494],{"className":416,"code":493,"language":418,"meta":419,"style":419},"pnpm run desktop:publish -- vX.Y.Z \u002Fpath\u002Fto\u002Frelease-notes.md --dry-run\npnpm run desktop:publish -- vX.Y.Z \u002Fpath\u002Fto\u002Frelease-notes.md\n",[260,495,496,519],{"__ignoreMap":419},[423,497,498,501,504,507,510,513,516],{"class":425,"line":426},[423,499,500],{"class":429},"pnpm",[423,502,503],{"class":433}," run",[423,505,506],{"class":433}," desktop:publish",[423,508,509],{"class":433}," --",[423,511,512],{"class":433}," vX.Y.Z",[423,514,515],{"class":433}," \u002Fpath\u002Fto\u002Frelease-notes.md",[423,517,518],{"class":433}," --dry-run\n",[423,520,521,523,525,527,529,531],{"class":425,"line":462},[423,522,500],{"class":429},[423,524,503],{"class":433},[423,526,506],{"class":433},[423,528,509],{"class":433},[423,530,512],{"class":433},[423,532,533],{"class":433}," \u002Fpath\u002Fto\u002Frelease-notes.md\n",[241,535,536,537,540,541,544],{},"The publisher requires ",[260,538,539],{},"gh"," access to both Newmatik repositories. It uploads all signed assets and a public ",[260,542,543],{},"latest.json"," before publishing the release. Existing installs through v1.4.3 need one manual reinstall because their embedded updater URL points to the private source repository.",[302,546,548],{"id":547},"release-notes","Release notes",[241,550,551,552,557],{},"Every release includes short, user-oriented release notes on the ",[334,553,272],{"href":554,"rel":555},"https:\u002F\u002Fgithub.com\u002Fnewmatik\u002Fgerbtrace-releases\u002Freleases",[556],"nofollow"," page. Guidelines:",[245,559,560,566,569,572],{},[248,561,562,563,263],{},"Use the bare version number as the release title (e.g., ",[260,564,565],{},"v1.1.1",[248,567,568],{},"Use a flat bullet list with concise sentences",[248,570,571],{},"Focus on new features and bug fixes that affect users",[248,573,574],{},"No emojis, no internal details, no auto-generated contributor lists",[241,576,577],{},"The same text appears in the desktop app's \"What's New\" dialog after an auto-update.",[302,579,581],{"id":580},"cicd-workflows","CI\u002FCD workflows",[583,584,585,601],"table",{},[586,587,588],"thead",{},[589,590,591,595,598],"tr",{},[592,593,594],"th",{},"Workflow",[592,596,597],{},"Trigger",[592,599,600],{},"Action",[602,603,604,624],"tbody",{},[589,605,606,612,621],{},[607,608,609],"td",{},[260,610,611],{},"ci.yml",[607,613,614,615,618,619],{},"Pull request to ",[260,616,617],{},"main"," and push to ",[260,620,617],{},[607,622,623],{},"Type check, tests, architecture checks, Worker build, and the required browser smoke suite (ADR-007)",[589,625,626,631,636],{},[607,627,628],{},[260,629,630],{},"build-desktop.yml",[607,632,633,634,263],{},"Tag push (",[260,635,489],{},[607,637,638],{},"Quality gate (typecheck, version check, tests), then build macOS\u002FWindows apps in the private source repository",[640,641,643],"h3",{"id":642},"web-deployment","Web deployment",[241,645,646],{},"The web app is deployed to Cloudflare Workers. Until a checked-in deploy\nworkflow exists, Cloudflare Workers Builds is the deployment authority and its\ndashboard build command\u002Fenvironment are part of the release configuration.",[368,648,649,654,659,670],{},[248,650,651],{},[260,652,653],{},"pnpm install --frozen-lockfile",[248,655,656],{},[260,657,658],{},"pnpm run build",[248,660,661,662,665,666,669],{},"Deploy the generated Worker via the Cloudflare Workers Builds pipeline\n(",[260,663,664],{},"wrangler deploy"," on the production branch, ",[260,667,668],{},"wrangler versions upload"," for\npreview branches)",[248,671,672],{},"Optional cache purge in Cloudflare dashboard when needed",[640,674,676],{"id":675},"desktop-release","Desktop release",[241,678,679,680,682],{},"Triggered on ",[260,681,489],{}," tag push:",[368,684,685,694,697,700,703,706],{},[248,686,687,690,691,693],{},[260,688,689],{},"quality"," job: typecheck, ",[260,692,407],{},", Vitest. The build\nmatrix does not start if it fails (ADR-005)",[248,695,696],{},"Matrix build for macOS (universal binary) and Windows",[248,698,699],{},"macOS: Apple certificate import, keychain setup, notarization",[248,701,702],{},"Windows: standard build",[248,704,705],{},"Signs updater artifacts with the Tauri signing key and creates the private release",[248,707,708,709,712,713,715,716],{},"Run ",[260,710,711],{},"desktop:publish"," to publish the signed installers and rewritten ",[260,714,543],{}," in ",[260,717,718],{},"newmatik\u002Fgerbtrace-releases",[640,720,722],{"id":721},"api-deployment","API deployment",[241,724,725,726,728,729,731,732,735,736,739],{},"Database migrations are applied directly to ",[251,727,282],{}," (project ",[260,730,286],{},") using the Supabase MCP tools (",[260,733,734],{},"apply_migration",", ",[260,737,738],{},"execute_sql",").",[241,741,742],{},"Edge functions are deployed via the Supabase dashboard or CLI.",[302,744,746],{"id":745},"github-secrets","GitHub secrets",[640,748,750],{"id":749},"web-deploy-cloudflare-workers-builds","Web deploy (Cloudflare Workers Builds)",[245,752,753,766],{},[248,754,755,735,760,765],{},[251,756,757],{},[260,758,759],{},"CLOUDFLARE_API_TOKEN",[251,761,762],{},[260,763,764],{},"CLOUDFLARE_ACCOUNT_ID"," (if required by the configured build\u002Fdeploy pipeline)",[248,767,768,773,774,779],{},[251,769,770],{},[260,771,772],{},"SENTRY_DSN",", (optional) ",[251,775,776],{},[260,777,778],{},"SENTRY_AUTH_TOKEN"," for source maps",[640,781,783,784,263],{"id":782},"desktop-builds-build-desktopyml","Desktop builds (",[260,785,630],{},[241,787,788],{},"Updater signing:",[245,790,791],{},[248,792,793,735,798],{},[251,794,795],{},[260,796,797],{},"TAURI_SIGNING_PRIVATE_KEY",[251,799,800],{},[260,801,802],{},"TAURI_SIGNING_PRIVATE_KEY_PASSWORD",[241,804,805],{},"Runtime config:",[245,807,808],{},[248,809,810,814],{},[251,811,812],{},[260,813,344],{}," (URL is fixed in workflows)",[241,816,817],{},"Apple signing \u002F notarization (macOS):",[245,819,820,837,844],{},[248,821,822,735,827,735,832],{},[251,823,824],{},[260,825,826],{},"APPLE_CERTIFICATE",[251,828,829],{},[260,830,831],{},"APPLE_CERTIFICATE_PASSWORD",[251,833,834],{},[260,835,836],{},"KEYCHAIN_PASSWORD",[248,838,839],{},[251,840,841],{},[260,842,843],{},"APPLE_SIGNING_IDENTITY",[248,845,846,735,851,735,856],{},[251,847,848],{},[260,849,850],{},"APPLE_API_ISSUER",[251,852,853],{},[260,854,855],{},"APPLE_API_KEY",[251,857,858],{},[260,859,860],{},"APPLE_API_KEY_CONTENT",[241,862,863],{},"Use the setup scripts to configure secrets:",[245,865,866,872,878],{},[248,867,868,871],{},[260,869,870],{},"scripts\u002Fsetup-github-secrets.sh"," — Tauri signing keypair",[248,873,874,877],{},[260,875,876],{},"scripts\u002Fsetup-apple-signing.sh"," — Apple certificate and notarization",[248,879,880,883],{},[260,881,882],{},"scripts\u002Fset-sentry-secrets.mjs"," — Sentry DSN and auth token",[302,885,887],{"id":886},"updater-signing","Updater signing",[241,889,890],{},"The desktop auto-updater verifies signatures to ensure update integrity:",[245,892,893,902],{},[248,894,895,896,258,898,901],{},"The public key in ",[260,897,383],{},[260,899,900],{},"plugins.updater.pubkey",") must match the private key used in CI",[248,903,904,905,908],{},"If desktop builds fail with ",[260,906,907],{},"incorrect updater private key password",", rotate\u002Fupdate the keypair and secrets",[302,910,912],{"id":911},"supabase-migration-review","Supabase migration review",[241,914,915],{},"If the release includes new SQL migrations, verify before merging:",[245,917,920,934,947,958,968,981,990,1004,1017],{"className":918},[919],"contains-task-list",[248,921,924,929,930,933],{"className":922},[923],"task-list-item",[925,926],"input",{"disabled":927,"type":928},true,"checkbox"," ",[260,931,932],{},"pnpm run migrations:check"," passes",[248,935,937,939,940,943,944],{"className":936},[923],[925,938],{"disabled":927,"type":928}," Every ",[260,941,942],{},"CREATE TABLE"," uses ",[260,945,946],{},"IF NOT EXISTS",[248,948,950,939,952,943,955],{"className":949},[923],[925,951],{"disabled":927,"type":928},[260,953,954],{},"CREATE FUNCTION",[260,956,957],{},"CREATE OR REPLACE",[248,959,961,939,963,943,966],{"className":960},[923],[925,962],{"disabled":927,"type":928},[260,964,965],{},"ALTER TABLE ADD COLUMN",[260,967,946],{},[248,969,971,939,973,976,977,980],{"className":970},[923],[925,972],{"disabled":927,"type":928},[260,974,975],{},"ALTER TABLE ADD CONSTRAINT"," checks ",[260,978,979],{},"pg_constraint"," before adding",[248,982,984,939,986,989],{"className":983},[923],[925,985],{"disabled":927,"type":928},[260,987,988],{},"CREATE POLICY"," is guarded against re-creation",[248,991,993,995,996,999,1000,1003],{"className":992},[923],[925,994],{"disabled":927,"type":928}," Dedup ",[260,997,998],{},"DELETE"," statements use ",[260,1001,1002],{},"row_number()"," with a stable tiebreaker",[248,1005,1007,1009,1010,1013,1014],{"className":1006},[923],[925,1008],{"disabled":927,"type":928}," No statement depends on ",[260,1011,1012],{},"postgres"," being able to ",[260,1015,1016],{},"SET ROLE supabase_admin",[248,1018,1020,1022,1023,1026],{"className":1019},[923],[925,1021],{"disabled":927,"type":928}," No statement requires table\u002Ffunction ownership that ",[260,1024,1025],{},"supabase_admin"," does not have",[302,1028,1030],{"id":1029},"verification-checklist","Verification checklist",[241,1032,1033],{},"After a release:",[245,1035,1037,1048,1062,1079,1087,1098],{"className":1036},[919],[248,1038,1040,929,1042,1045,1046],{"className":1039},[923],[925,1041],{"disabled":927,"type":928},[251,1043,1044],{},"Web",": Cloudflare Workers build\u002Fdeploy succeeded after merge to ",[260,1047,617],{},[248,1049,1051,929,1053,1055,1056,1059,1060,263],{"className":1050},[923],[925,1052],{"disabled":927,"type":928},[251,1054,1044],{},": ",[260,1057,1058],{},"RELEASE_BUILD_ID=\u003Cdeployed commit sha> pnpm run release:verify","\npasses: synthetic routes, the deployed build id, the docs rows through\nthe D1-backed content route, and the Sentry release with source maps\n(see ",[334,1061,228],{"href":229},[248,1063,1065,929,1067,1055,1070,1072,1073,352,1076],{"className":1064},[923],[925,1066],{"disabled":927,"type":928},[251,1068,1069],{},"Desktop",[260,1071,630],{}," succeeded for both ",[260,1074,1075],{},"macos-latest",[260,1077,1078],{},"windows-latest",[248,1080,1082,929,1084,1086],{"className":1081},[923],[925,1083],{"disabled":927,"type":928},[251,1085,1069],{},": the public GitHub Release has both macOS and Windows installers",[248,1088,1090,929,1092,1094,1095,1097],{"className":1089},[923],[925,1091],{"disabled":927,"type":928},[251,1093,1069],{},": the public ",[260,1096,543],{}," and installer URLs return 200 without GitHub authentication",[248,1099,1101,929,1103,1106,1107,1109],{"className":1100},[923],[925,1102],{"disabled":927,"type":928},[251,1104,1105],{},"Supabase",": migrations applied (confirm via ",[260,1108,738],{}," or Supabase dashboard)",[241,1111,1112,1113,1116,1117,1120],{},"If ",[260,1114,1115],{},"release:verify"," reports the previous build id (or the footer shows an old version) after deploy, purge cache in the Cloudflare dashboard (",[251,1118,1119],{},"Caching > Configuration > Purge Everything",") and re-run it.",[302,1122,1124],{"id":1123},"operational-safety","Operational safety",[245,1126,1127,1130,1133],{},[248,1128,1129],{},"Never paste private keys into PRs, issues, or chat. Treat pasted keys as compromised and rotate them.",[248,1131,1132],{},"Keep deploy keys scoped and rotate periodically.",[248,1134,1135],{},"Confirm Actions logs do not contain secret material.",[302,1137,1139],{"id":1138},"historical-failure-log","Historical failure log",[583,1141,1142,1155],{},[586,1143,1144],{},[589,1145,1146,1149,1152],{},[592,1147,1148],{},"Release",[592,1150,1151],{},"Failure",[592,1153,1154],{},"Root cause",[602,1156,1157,1168,1181,1194,1207],{},[589,1158,1159,1162,1165],{},[607,1160,1161],{},"v1.0.6",[607,1163,1164],{},"Initial schema fails on provisioned DB",[607,1166,1167],{},"Migration not idempotent",[589,1169,1170,1172,1178],{},[607,1171,1161],{},[607,1173,1174,1177],{},[260,1175,1176],{},"set -e"," kills script on expected errors",[607,1179,1180],{},"Error handling too strict",[589,1182,1183,1186,1191],{},[607,1184,1185],{},"v1.0.9",[607,1187,1188],{},[260,1189,1190],{},"must be owner of function",[607,1192,1193],{},"postgres cannot replace function owned by supabase_admin",[589,1195,1196,1199,1204],{},[607,1197,1198],{},"v1.0.10",[607,1200,1201],{},[260,1202,1203],{},"must be owner of table",[607,1205,1206],{},"postgres cannot ALTER tables owned by supabase_admin",[589,1208,1209,1211,1216],{},[607,1210,1198],{},[607,1212,1213],{},[260,1214,1215],{},"permission denied to set role",[607,1217,1218],{},"postgres cannot SET ROLE to supabase_admin",[302,1220,1222],{"id":1221},"sample-data","Sample data",[241,1224,1225],{},"The project ships with sample Arduino UNO Gerber files for demo purposes. The \"Try a Sample\" button on the landing page loads these files so users can explore without importing their own data.",[1227,1228,1229],"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 .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);}",{"title":419,"searchDepth":473,"depth":462,"links":1231},[1232,1233,1234,1235,1236,1241,1246,1247,1248,1249,1250,1251],{"id":304,"depth":462,"text":305},{"id":362,"depth":462,"text":363},{"id":411,"depth":462,"text":412},{"id":547,"depth":462,"text":548},{"id":580,"depth":462,"text":581,"children":1237},[1238,1239,1240],{"id":642,"depth":473,"text":643},{"id":675,"depth":473,"text":676},{"id":721,"depth":473,"text":722},{"id":745,"depth":462,"text":746,"children":1242},[1243,1244],{"id":749,"depth":473,"text":750},{"id":782,"depth":473,"text":1245},"Desktop builds (build-desktop.yml)",{"id":886,"depth":462,"text":887},{"id":911,"depth":462,"text":912},{"id":1029,"depth":462,"text":1030},{"id":1123,"depth":462,"text":1124},{"id":1138,"depth":462,"text":1139},{"id":1221,"depth":462,"text":1222},"Deployment architecture, environment variables, CI\u002FCD workflows, release checklist, and operational safety.","md",null,{},{"title":208,"description":1252},"dqdgRSopdgudKmHfGSZ-sVyS0Wvr0gWM7y6UvtiJZ9Q",[1259,1261],{"title":204,"path":205,"stem":206,"description":1260,"children":-1},"External CAD library ingestion, parser pipelines, and package generation workflow.",{"title":212,"path":213,"stem":214,"description":1262,"children":-1},"Sentry integration for error reporting in web and desktop builds.",1790998747373]