[{"data":1,"prerenderedAt":458},["ShallowReactive",2],{"navigation_docs":3,"-docs-reference-commands":60,"-docs-reference-commands-surround":453},[4,25,45],{"title":5,"path":6,"stem":7,"children":8,"page":24},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[9,14,19],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Configuration","\u002Fdocs\u002Fgetting-started\u002Fconfiguration","docs\u002F1.getting-started\u002F3.configuration","i-lucide-sliders-horizontal",false,{"title":26,"path":27,"stem":28,"children":29,"page":24},"Architecture","\u002Fdocs\u002Farchitecture","docs\u002F2.architecture",[30,35,40],{"title":31,"path":32,"stem":33,"icon":34},"Layers","\u002Fdocs\u002Farchitecture\u002Flayers","docs\u002F2.architecture\u002F1.layers","i-lucide-layers",{"title":36,"path":37,"stem":38,"icon":39},"Multi-tenancy","\u002Fdocs\u002Farchitecture\u002Fmulti-tenancy","docs\u002F2.architecture\u002F2.multi-tenancy","i-lucide-building-2",{"title":41,"path":42,"stem":43,"icon":44},"Testing","\u002Fdocs\u002Farchitecture\u002Ftesting","docs\u002F2.architecture\u002F3.testing","i-lucide-flask-conical",{"title":46,"path":47,"stem":48,"children":49,"page":24},"Reference","\u002Fdocs\u002Freference","docs\u002F3.reference",[50,55],{"title":51,"path":52,"stem":53,"icon":54},"Commands","\u002Fdocs\u002Freference\u002Fcommands","docs\u002F3.reference\u002F1.commands","i-lucide-terminal",{"title":56,"path":57,"stem":58,"icon":59},"Decisions","\u002Fdocs\u002Freference\u002Fdecisions","docs\u002F3.reference\u002F2.decisions","i-lucide-git-branch",{"id":61,"title":51,"body":62,"description":446,"extension":447,"links":448,"meta":449,"navigation":450,"path":52,"seo":451,"stem":53,"__hash__":452},"docs\u002Fdocs\u002F3.reference\u002F1.commands.md",{"type":63,"value":64,"toc":438},"minimark",[65,70,130,134,193,201,205,250,254,330,337,341,366,370,374,377,434],[66,67,69],"h2",{"id":68},"develop","Develop",[71,72,77],"pre",{"className":73,"code":74,"language":75,"meta":76,"style":76},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm dev            # http:\u002F\u002Flocalhost:3000\npnpm build          # production build\npnpm preview        # serve the build\npnpm typecheck      # nuxt typecheck\n","bash","",[78,79,80,97,108,119],"code",{"__ignoreMap":76},[81,82,85,89,93],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"sBMFI","pnpm",[81,90,92],{"class":91},"sfazB"," dev",[81,94,96],{"class":95},"sHwdD","            # http:\u002F\u002Flocalhost:3000\n",[81,98,100,102,105],{"class":83,"line":99},2,[81,101,88],{"class":87},[81,103,104],{"class":91}," build",[81,106,107],{"class":95},"          # production build\n",[81,109,111,113,116],{"class":83,"line":110},3,[81,112,88],{"class":87},[81,114,115],{"class":91}," preview",[81,117,118],{"class":95},"        # serve the build\n",[81,120,122,124,127],{"class":83,"line":121},4,[81,123,88],{"class":87},[81,125,126],{"class":91}," typecheck",[81,128,129],{"class":95},"      # nuxt typecheck\n",[66,131,133],{"id":132},"database","Database",[71,135,137],{"className":73,"code":136,"language":75,"meta":76,"style":76},"pnpm supabase \u003Ccmd> # the CLI is a project dep, not global\npnpm db:reset       # reset + migrate + seed\npnpm db:types       # regenerate shared\u002Ftypes\u002Fdatabase.types.ts\npnpm seed           # reseed (SEED_FAST=1 for the minimal set)\n",[78,138,139,163,173,183],{"__ignoreMap":76},[81,140,141,143,146,150,153,157,160],{"class":83,"line":84},[81,142,88],{"class":87},[81,144,145],{"class":91}," supabase",[81,147,149],{"class":148},"sMK4o"," \u003C",[81,151,152],{"class":91},"cm",[81,154,156],{"class":155},"sTEyZ","d",[81,158,159],{"class":148},">",[81,161,162],{"class":95}," # the CLI is a project dep, not global\n",[81,164,165,167,170],{"class":83,"line":99},[81,166,88],{"class":87},[81,168,169],{"class":91}," db:reset",[81,171,172],{"class":95},"       # reset + migrate + seed\n",[81,174,175,177,180],{"class":83,"line":110},[81,176,88],{"class":87},[81,178,179],{"class":91}," db:types",[81,181,182],{"class":95},"       # regenerate shared\u002Ftypes\u002Fdatabase.types.ts\n",[81,184,185,187,190],{"class":83,"line":121},[81,186,88],{"class":87},[81,188,189],{"class":91}," seed",[81,191,192],{"class":95},"           # reseed (SEED_FAST=1 for the minimal set)\n",[194,195,196,197,200],"caution",{},"After changing a table or function, run ",[78,198,199],{},"pnpm db:types"," or typecheck fails. Never\nedit a migration that has already been applied to a real database — add a new one.",[66,202,204],{"id":203},"test","Test",[71,206,208],{"className":73,"code":207,"language":75,"meta":76,"style":76},"pnpm test           # vitest (pure logic)\npnpm test:coverage  # with the 100% gate\npnpm test:e2e       # Playwright e2e + a11y\npnpm screenshots    # regenerate docs\u002Fscreenshots\u002F\n",[78,209,210,220,230,240],{"__ignoreMap":76},[81,211,212,214,217],{"class":83,"line":84},[81,213,88],{"class":87},[81,215,216],{"class":91}," test",[81,218,219],{"class":95},"           # vitest (pure logic)\n",[81,221,222,224,227],{"class":83,"line":99},[81,223,88],{"class":87},[81,225,226],{"class":91}," test:coverage",[81,228,229],{"class":95},"  # with the 100% gate\n",[81,231,232,234,237],{"class":83,"line":110},[81,233,88],{"class":87},[81,235,236],{"class":91}," test:e2e",[81,238,239],{"class":95},"       # Playwright e2e + a11y\n",[81,241,242,244,247],{"class":83,"line":121},[81,243,88],{"class":87},[81,245,246],{"class":91}," screenshots",[81,248,249],{"class":95},"    # regenerate docs\u002Fscreenshots\u002F\n",[66,251,253],{"id":252},"lint-and-generate","Lint and generate",[71,255,257],{"className":73,"code":256,"language":75,"meta":76,"style":76},"pnpm lint \u002F pnpm lint:fix\npnpm fmt \u002F pnpm fmt:check\npnpm lint:i18n            # key parity + usage\npnpm gen:layer \u003Cname>     # scaffold a feature layer\npnpm gen:auth-templates   # regenerate supabase\u002Ftemplates\u002F*.html\n",[78,258,259,275,289,299,319],{"__ignoreMap":76},[81,260,261,263,266,269,272],{"class":83,"line":84},[81,262,88],{"class":87},[81,264,265],{"class":91}," lint",[81,267,268],{"class":91}," \u002F",[81,270,271],{"class":91}," pnpm",[81,273,274],{"class":91}," lint:fix\n",[81,276,277,279,282,284,286],{"class":83,"line":99},[81,278,88],{"class":87},[81,280,281],{"class":91}," fmt",[81,283,268],{"class":91},[81,285,271],{"class":91},[81,287,288],{"class":91}," fmt:check\n",[81,290,291,293,296],{"class":83,"line":110},[81,292,88],{"class":87},[81,294,295],{"class":91}," lint:i18n",[81,297,298],{"class":95},"            # key parity + usage\n",[81,300,301,303,306,308,311,314,316],{"class":83,"line":121},[81,302,88],{"class":87},[81,304,305],{"class":91}," gen:layer",[81,307,149],{"class":148},[81,309,310],{"class":91},"nam",[81,312,313],{"class":155},"e",[81,315,159],{"class":148},[81,317,318],{"class":95},"     # scaffold a feature layer\n",[81,320,322,324,327],{"class":83,"line":321},5,[81,323,88],{"class":87},[81,325,326],{"class":91}," gen:auth-templates",[81,328,329],{"class":95},"   # regenerate supabase\u002Ftemplates\u002F*.html\n",[331,332,333,336],"note",{},[78,334,335],{},"forge.toml"," wires oxfmt and oxlint into a pre-commit hook that auto-fixes and\nrestages, so you don't need to run them during development.",[66,338,340],{"id":339},"set-up-and-verify","Set up and verify",[71,342,344],{"className":73,"code":343,"language":75,"meta":76,"style":76},"pnpm setup   # pick integrations, write .env\npnpm doctor  # verify what setup wrote\n",[78,345,346,356],{"__ignoreMap":76},[81,347,348,350,353],{"class":83,"line":84},[81,349,88],{"class":87},[81,351,352],{"class":91}," setup",[81,354,355],{"class":95},"   # pick integrations, write .env\n",[81,357,358,360,363],{"class":83,"line":99},[81,359,88],{"class":87},[81,361,362],{"class":91}," doctor",[81,364,365],{"class":95},"  # verify what setup wrote\n",[367,368,369],"p",{},"Both read the same subsystem manifest — adding a subsystem there wires up both.",[66,371,373],{"id":372},"changelogs","Changelogs",[367,375,376],{},"There are two, deliberately:",[378,379,380,396],"table",{},[381,382,383],"thead",{},[384,385,386,390,393],"tr",{},[387,388,389],"th",{},"File",[387,391,392],{},"Audience",[387,394,395],{},"Edited by",[397,398,399,417],"tbody",{},[384,400,401,407,410],{},[402,403,404],"td",{},[78,405,406],{},"CHANGELOG.md",[402,408,409],{},"developers",[402,411,412,413],{},"release-please — ",[414,415,416],"strong",{},"never by hand",[384,418,419,428,431],{},[402,420,421,424,425],{},[78,422,423],{},"app\u002Futils\u002Fchangelog.ts"," → ",[78,426,427],{},"\u002Fchangelog",[402,429,430],{},"your users",[402,432,433],{},"you, one entry per date",[435,436,437],"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 .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 .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 .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}",{"title":76,"searchDepth":99,"depth":99,"links":439},[440,441,442,443,444,445],{"id":68,"depth":99,"text":69},{"id":132,"depth":99,"text":133},{"id":203,"depth":99,"text":204},{"id":252,"depth":99,"text":253},{"id":339,"depth":99,"text":340},{"id":372,"depth":99,"text":373},"Every script worth knowing, grouped by what you're doing.","md",null,{},{"icon":54},{"title":51,"description":446},"a1e31zeHHLPQWtK4-zXwZE8DBAM_xFBaSMceeVRAA5s",[454,456],{"title":41,"path":42,"stem":43,"description":455,"icon":44,"children":-1},"Two suites with a hard line between them, and a 100% gate that means something.",{"title":56,"path":57,"stem":58,"description":457,"icon":59,"children":-1},"The architecture decision records, and the things deliberately not built.",1785842751196]