[{"data":1,"prerenderedAt":867},["ShallowReactive",2],{"repo-tree":3,"repo-\u002Fmonorepo-structure":283},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,69,72,75,78,81,84,86,88,90,93,96,99,102,105,108,111,114,117,120,123,125,127,129,131,133,135,138,141,143,146,149,152,155,158,161,164,167,169,172,175,178,180,183,186,189,192,195,198,201,203,206,209,212,215,218,221,224,227,230,233,236,239,242,245,248,251,254,257,260,263,266,269,272,275,278,281],{"path":5,"title":6},"\u002Fagents\u002Fbackend-code-style","Backend Conventions",{"path":8,"title":9},"\u002Fagents\u002Fdatabase","Database",{"path":11,"title":12},"\u002Fagents\u002Fportal-code-style","Portal Conventions",{"path":14,"title":15},"\u002Fagents\u002Ftranslation","Translation",{"path":17,"title":18},"\u002Fconventions\u002Fbackend-coding","Backend coding conventions",{"path":20,"title":21},"\u002Fconventions\u002Ffrontend-coding","Frontend coding conventions",{"path":23,"title":24},"\u002Fdevelopment-process","Development process",{"path":26,"title":27},"\u002Flearning-api-preview-hetzner-setup","Learning API Preview on Hetzner + Cloudflare",{"path":29,"title":30},"\u002Flearning-api-preview-vm-plan","Learning API Preview VM Plan",{"path":32,"title":33},"\u002Fmonorepo-structure","Monorepo structure",{"path":35,"title":36},"\u002Foperations","Operations — bugs and support",{"path":38,"title":39},"\u002Fpostmortems\u002F2026-03-16_onboarding-currency-regression","Onboarding Zod transform silently broken — web signups assigned wrong checkout currency",{"path":41,"title":42},"\u002Fpostmortems\u002Freadme","Postmortems",{"path":44,"title":45},"\u002Fpostmortems\u002F_template","TEMPLATE",{"path":47,"title":48},"\u002Fpostmortems\u002Fposthog-comparison","Postmortem practice — comparison with PostHog",{"path":50,"title":51},"\u002Fpreview-environment-plan","Preview Environment Plan",{"path":53,"title":54},"\u002Fprinciples","Engineering principles",{"path":56,"title":57},"\u002Fworking-with-ai","Working with AI",{"path":59,"title":60},"\u002F.claude\u002Fskills\u002Feval-playground\u002Fskill","Eval Playground — Co-development Skill",{"path":62,"title":63},"\u002F.claude\u002Fskills\u002Ffigma-diff-section\u002Fskill","Figma Diff Section Pipeline",{"path":65,"title":66},"\u002Fagents","AGENTS.md",{"path":68,"title":66},"\u002Fclaude",{"path":70,"title":71},"\u002Freadme","Studyflash",{"path":73,"title":74},"\u002Fapps\u002Fcore-api\u002Fagents","Core API (apps\u002Fcore-api)",{"path":76,"title":77},"\u002Fapps\u002Fcore-api\u002Freadme","README",{"path":79,"title":80},"\u002Fapps\u002Femail-previews\u002Fagents","Email Previews (apps\u002Femail-previews)",{"path":82,"title":83},"\u002Fapps\u002Flanding-page\u002Fagents","Landing Page (apps\u002Flanding-page)",{"path":85,"title":83},"\u002Fapps\u002Flanding-page\u002Fclaude",{"path":87,"title":66},"\u002Fapps\u002Flearning-api\u002Fagents",{"path":89,"title":77},"\u002Fapps\u002Flearning-api\u002Freadme",{"path":91,"title":92},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Feval_metrics_design","Surface-Specific Eval Metrics Design",{"path":94,"title":95},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Ftest_set","Quiz Eval Test Set",{"path":97,"title":98},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Ffrontend\u002Freadme","React + TypeScript + Vite",{"path":100,"title":101},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fknown-issues\u002Fcontent-pillar-shallow-coverage\u002Freadme","Content pillar misses subtopics in dense documents",{"path":103,"title":104},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fknown-issues\u002Fdocling-empty-section-headers\u002Freadme","Empty section headers dropped by docling chunker",{"path":106,"title":107},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fknown-issues\u002Fdocling-table-reading-order\u002Freadme","Table\u002Fbox layout causes wrong reading order",{"path":109,"title":110},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fmetrics\u002Freadme","Quiz eval metrics — canonical rubrics",{"path":112,"title":113},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Freports\u002F2026-04-12-quiz-summary-feedback-current-state","Quiz and Summary Feedback Current State",{"path":115,"title":116},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Freports\u002F2026-04-24-quiz-eval-metrics","Quiz Evaluation Metrics",{"path":118,"title":119},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Freports\u002F2026-05-01-quiz-eval-current-state","Quiz Eval Current State",{"path":121,"title":122},"\u002Fapps\u002Flearning-api\u002Fmonitoring\u002Freadme","Monitoring Stack",{"path":124,"title":77},"\u002Fapps\u002Flearning-api\u002Fshared\u002Freadme",{"path":126,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fflashcard_agent\u002Freadme",{"path":128,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fingestion_agent\u002Freadme",{"path":130,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fquiz_agent\u002Freadme",{"path":132,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fsummary_agent\u002Freadme",{"path":134,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Fparser\u002Freadme",{"path":136,"title":137},"\u002Fapps\u002Fmarketing-emails-preview\u002Fagents","Marketing Emails Preview (apps\u002Fmarketing-emails-preview)",{"path":139,"title":140},"\u002Fapps\u002Fmobile-app\u002Fagents","StudyFlash Mobile App - Claude Code Configuration",{"path":142,"title":140},"\u002Fapps\u002Fmobile-app\u002Fclaude",{"path":144,"title":145},"\u002Fapps\u002Fmountain-max\u002Fagents","Mountain Max (apps\u002Fmountain-max)",{"path":147,"title":148},"\u002Fapps\u002Fmountain-max\u002Fgame\u002Freadme","Mountain Max Game",{"path":150,"title":151},"\u002Fapps\u002Fportal\u002Fagents","Portal (apps\u002Fportal)",{"path":153,"title":154},"\u002Fapps\u002Fportal\u002Freadme","Nuxt Minimal Starter",{"path":156,"title":157},"\u002Fapps\u002Fportal\u002Fapp\u002Fcomposables\u002Ffiles\u002Freadme","File Upload Composables",{"path":159,"title":160},"\u002Fapps\u002Fportal\u002Fdocs\u002Flibrary-routing","Library Routing Documentation",{"path":162,"title":163},"\u002Fapps\u002Fsupabase\u002Fagents","Supabase (apps\u002Fsupabase)",{"path":165,"title":166},"\u002Fapps\u002Fwrapped\u002Fagents","Wrapped (apps\u002Fwrapped)",{"path":168,"title":98},"\u002Fapps\u002Fwrapped\u002Freadme",{"path":170,"title":171},"\u002Finfra\u002Freadme","infra\u002F",{"path":173,"title":174},"\u002Finfra\u002Fdns\u002Freadme","DNS Infrastructure",{"path":176,"title":177},"\u002Finfra\u002Fdokploy\u002Freadme","studyflash-dokploy",{"path":179,"title":77},"\u002Finfra\u002Fdokploy\u002Fsdk\u002Fnodejs\u002Freadme",{"path":181,"title":182},"\u002Finfra\u002Finfisical\u002Freadme","Infisical Infrastructure",{"path":184,"title":185},"\u002Finfra\u002Flearning-api\u002Freadme","Pulumi GCP TypeScript Template",{"path":187,"title":188},"\u002Finfra\u002Fopenreplay\u002Freadme","OpenReplay on Hetzner",{"path":190,"title":191},"\u002Finfra\u002Fscripts\u002Freadme","infra\u002Fscripts\u002F",{"path":193,"title":194},"\u002Finfra\u002Fturborepo-cache\u002Freadme","Turborepo Remote Cache Infrastructure",{"path":196,"title":197},"\u002Finternal\u002Fchatwoot\u002Freadme","Chatwoot Infrastructure",{"path":199,"title":200},"\u002Finternal\u002Fchatwoot\u002Fprovider\u002Freadme","studyflash-chatwoot-provider",{"path":202,"title":77},"\u002Finternal\u002Fchatwoot\u002Fprovider\u002Fsdk\u002Fnodejs\u002Freadme",{"path":204,"title":205},"\u002Finternal\u002Fdocs\u002Freadme","internal\u002Fdocs",{"path":207,"title":208},"\u002Finternal\u002Fsupport-bot\u002Fclaude","Support Bot (Maximilian)",{"path":210,"title":211},"\u002Finternal\u002Fsupport-bot\u002Freadme","Studyflash Customer Support Bot (Maximilian)",{"path":213,"title":214},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Faccount_issues","Account Issues",{"path":216,"title":217},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fbilling_invoice","Billing Invoice",{"path":219,"title":220},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fcontent_upload","Content Upload",{"path":222,"title":223},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fdata_loss","Data Loss",{"path":225,"title":226},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fflashcard_issues","Flashcard Issues",{"path":228,"title":229},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fgarbage","Garbage",{"path":231,"title":232},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fgeneral_how_to","General How To",{"path":234,"title":235},"\u002Finternal\u002Fsupport-bot\u002Fkb","Knowledge Base Index",{"path":237,"title":238},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Flanguage_issues","Language Issues",{"path":240,"title":241},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fmindmap_issues","Mindmap Issues",{"path":243,"title":244},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fmisunderstanding","Misunderstanding",{"path":246,"title":247},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fmock_exam_issues","Mock Exam Issues",{"path":249,"title":250},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fpodcast_issues","Podcast Issues",{"path":252,"title":253},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fquiz_issues","Quiz Issues",{"path":255,"title":256},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Frefund_request","Refund Request",{"path":258,"title":259},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fsubscription_cancellation","Subscription Cancellation",{"path":261,"title":262},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fsubscription_info","Subscription Info",{"path":264,"title":265},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fsummary_issues","Summary Issues",{"path":267,"title":268},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Ftechnical_errors","Technical Errors",{"path":270,"title":271},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fvideo_issues","Video Issues",{"path":273,"title":274},"\u002Fpackages\u002Fcommon\u002Fdocs\u002Fearly-access-features","Declarative Early Access Features",{"path":276,"title":277},"\u002Fpackages\u002Fcommon\u002Fscripts\u002Freadme","Common Package Scripts",{"path":279,"title":280},"\u002Fpackages\u002Fdevtools\u002Ffigma-plugins\u002Freadme","Figma plugins",{"path":282,"title":77},"\u002Fpackages\u002Fpulumi-infisical\u002Freadme",{"id":284,"title":33,"body":285,"description":853,"extension":854,"lastReviewed":855,"meta":856,"navigation":857,"owner":858,"path":32,"seo":859,"status":860,"stem":861,"tags":862,"__hash__":866},"handbook\u002Fmonorepo-structure.md",{"type":286,"value":287,"toc":842},"minimark",[288,303,309,314,414,419,480,484,525,529,535,579,583,589,608,625,629,636,698,705,709,715,781,785,788,838],[289,290,291,292,302],"p",{},"PH analogue: ",[293,294,298],"a",{"href":295,"rel":296},"https:\u002F\u002Fposthog.com\u002Fhandbook\u002Fengineering\u002Fproject-structure",[297],"nofollow",[299,300,301],"code",{},"posthog.com\u002Fhandbook\u002Fengineering\u002Fproject-structure",".",[304,305,306],"blockquote",{},[289,307,308],{},"TODO: architecture diagram (Excalidraw). The previous link was stale.",[310,311,313],"h2",{"id":312},"apps","Apps",[315,316,317,333],"table",{},[318,319,320],"thead",{},[321,322,323,327,330],"tr",{},[324,325,326],"th",{},"App",[324,328,329],{},"Stack",[324,331,332],{},"Description",[334,335,336,350,363,376,389,402],"tbody",{},[321,337,338,344,347],{},[339,340,341],"td",{},[299,342,343],{},"portal",[339,345,346],{},"Nuxt 3",[339,348,349],{},"Student-facing web app",[321,351,352,357,360],{},[339,353,354],{},[299,355,356],{},"core-api",[339,358,359],{},"Hono (TS)",[339,361,362],{},"API service — auth, subscriptions, orchestration",[321,364,365,370,373],{},[339,366,367],{},[299,368,369],{},"learning-api",[339,371,372],{},"FastAPI (Py)",[339,374,375],{},"AI content generation (flashcards, quizzes, summaries)",[321,377,378,383,386],{},[339,379,380],{},[299,381,382],{},"mobile-app",[339,384,385],{},"Expo \u002F React Native",[339,387,388],{},"Mobile app",[321,390,391,396,399],{},[339,392,393],{},[299,394,395],{},"supabase",[339,397,398],{},"Supabase",[339,400,401],{},"Schemas, migrations, seeds, edge functions",[321,403,404,409,411],{},[339,405,406],{},[299,407,408],{},"landing-page",[339,410,346],{},[339,412,413],{},"Marketing site",[415,416,418],"h3",{"id":417},"other","Other",[315,420,421,429],{},[318,422,423],{},[321,424,425,427],{},[324,426,326],{},[324,428,332],{},[334,430,431,441,450,460,470],{},[321,432,433,438],{},[339,434,435],{},[299,436,437],{},"mountain-max",[339,439,440],{},"Microsite",[321,442,443,448],{},[339,444,445],{},[299,446,447],{},"subway-max",[339,449,440],{},[321,451,452,457],{},[339,453,454],{},[299,455,456],{},"wrapped",[339,458,459],{},"Studyflash Wrapped microsite",[321,461,462,467],{},[339,463,464],{},[299,465,466],{},"email-previews",[339,468,469],{},"Transactional email previews",[321,471,472,477],{},[339,473,474],{},[299,475,476],{},"marketing-emails-preview",[339,478,479],{},"Marketing email previews",[310,481,483],{"id":482},"packages","Packages",[485,486,487,495,501,507,513,519],"ul",{},[488,489,490,494],"li",{},[491,492,493],"strong",{},"types"," — Shared TypeScript types (incl. generated Supabase DB types)",[488,496,497,500],{},[491,498,499],{},"common"," — Shared utilities and constants",[488,502,503,506],{},[491,504,505],{},"api-client"," — Shared API client",[488,508,509,512],{},[491,510,511],{},"tsconfig"," — Shared TypeScript configs",[488,514,515,518],{},[491,516,517],{},"devtools"," — Developer tooling scripts (Deno)",[488,520,521,524],{},[491,522,523],{},"learning-service"," — Shared learning service client",[310,526,528],{"id":527},"infra","Infra",[289,530,531,534],{},[299,532,533],{},"infra\u002F*"," — one Pulumi stack per concern. Examples:",[485,536,537,548,554,560,573],{},[488,538,539,542,543,547],{},[299,540,541],{},"infra\u002Flearning-api"," — Hetzner VM + preview environments (see ",[293,544,546],{"href":545},"\u002Frepo\u002Fpreview-environment-plan","preview environment plan",")",[488,549,550,553],{},[299,551,552],{},"infra\u002Fdns"," — DNS records",[488,555,556,559],{},[299,557,558],{},"infra\u002Finfisical"," — secrets manager stack",[488,561,562,565,566,565,569,572],{},[299,563,564],{},"infra\u002Fdokploy",", ",[299,567,568],{},"infra\u002Fopenreplay",[299,570,571],{},"infra\u002Fturborepo-cache"," — self-hosted services",[488,574,575,578],{},[299,576,577],{},"infra\u002Fsentry"," — explicitly excluded from the workspace",[310,580,582],{"id":581},"internal","Internal",[289,584,585,588],{},[299,586,587],{},"internal\u002F*"," — services and surfaces that aren't products:",[485,590,591,597,603],{},[488,592,593,596],{},[299,594,595],{},"internal\u002Fsupport-bot"," — Chatwoot SLA + triage assistant",[488,598,599,602],{},[299,600,601],{},"internal\u002Fchatwoot"," — Chatwoot provider config",[488,604,605,607],{},[299,606,205],{}," — this handbook surface (Nuxt 3 + Nuxt Content)",[289,609,610,612,613,616,617,620,621,624],{},[299,611,205],{}," is intentionally ",[491,614,615],{},"not"," in ",[299,618,619],{},"pnpm-workspace.yaml",". It runs its own ",[299,622,623],{},"pnpm install --ignore-workspace",", so a half-finished docs demo can't break the workspace lockfile or CI pipeline.",[310,626,628],{"id":627},"build-order","Build order",[289,630,631,632,635],{},"Internal ",[299,633,634],{},"packages\u002F*"," must be built before type-checking dependent apps:",[637,638,643],"pre",{"className":639,"code":640,"language":641,"meta":642,"style":642},"language-sh shiki shiki-themes github-light github-dark","pnpm turbo build --filter=@studyflash-ai\u002Ftypes \\\n                 --filter=@studyflash-ai\u002Fcommon \\\n                 --filter=@studyflash-ai\u002Fapi-client \\\n                 --filter=@studyflash-ai\u002Flearning-service \\\n                 --filter=@studyflash-ai\u002Fmarketing-emails\n","sh","",[299,644,645,668,676,684,692],{"__ignoreMap":642},[646,647,650,654,658,661,665],"span",{"class":648,"line":649},"line",1,[646,651,653],{"class":652},"sScJk","pnpm",[646,655,657],{"class":656},"sZZnC"," turbo",[646,659,660],{"class":656}," build",[646,662,664],{"class":663},"sj4cs"," --filter=@studyflash-ai\u002Ftypes",[646,666,667],{"class":663}," \\\n",[646,669,671,674],{"class":648,"line":670},2,[646,672,673],{"class":663},"                 --filter=@studyflash-ai\u002Fcommon",[646,675,667],{"class":663},[646,677,679,682],{"class":648,"line":678},3,[646,680,681],{"class":663},"                 --filter=@studyflash-ai\u002Fapi-client",[646,683,667],{"class":663},[646,685,687,690],{"class":648,"line":686},4,[646,688,689],{"class":663},"                 --filter=@studyflash-ai\u002Flearning-service",[646,691,667],{"class":663},[646,693,695],{"class":648,"line":694},5,[646,696,697],{"class":663},"                 --filter=@studyflash-ai\u002Fmarketing-emails\n",[289,699,700,701,704],{},"(Or ",[299,702,703],{},"pnpm turbo build"," for everything.)",[310,706,708],{"id":707},"quick-start","Quick start",[289,710,711,714],{},[491,712,713],{},"Prerequisites:"," Node.js, pnpm v10, Deno, Python 3, Docker, Infisical CLI.",[637,716,718],{"className":639,"code":717,"language":641,"meta":642,"style":642},"pnpm install        # install dependencies\npnpm dev            # interactive dev launcher\npnpm dev:local      # full local dev stack\npnpm build          # build all apps\npnpm test           # run tests\npnpm lint           # lint all packages\n",[299,719,720,731,741,751,760,770],{"__ignoreMap":642},[646,721,722,724,727],{"class":648,"line":649},[646,723,653],{"class":652},[646,725,726],{"class":656}," install",[646,728,730],{"class":729},"sJ8bj","        # install dependencies\n",[646,732,733,735,738],{"class":648,"line":670},[646,734,653],{"class":652},[646,736,737],{"class":656}," dev",[646,739,740],{"class":729},"            # interactive dev launcher\n",[646,742,743,745,748],{"class":648,"line":678},[646,744,653],{"class":652},[646,746,747],{"class":656}," dev:local",[646,749,750],{"class":729},"      # full local dev stack\n",[646,752,753,755,757],{"class":648,"line":686},[646,754,653],{"class":652},[646,756,660],{"class":656},[646,758,759],{"class":729},"          # build all apps\n",[646,761,762,764,767],{"class":648,"line":694},[646,763,653],{"class":652},[646,765,766],{"class":656}," test",[646,768,769],{"class":729},"           # run tests\n",[646,771,773,775,778],{"class":648,"line":772},6,[646,774,653],{"class":652},[646,776,777],{"class":656}," lint",[646,779,780],{"class":729},"           # lint all packages\n",[310,782,784],{"id":783},"boundaries-and-rules","Boundaries and rules",[289,786,787],{},"TODO. Things to capture:",[485,789,790,797,804,812,824],{},[488,791,792,793,796],{},"What lives in ",[299,794,795],{},"packages\u002F"," vs inline in an app.",[488,798,799,800,803],{},"When a new ",[299,801,802],{},"app\u002F"," is justified.",[488,805,806,808,809,811],{},[299,807,356],{}," ↔ ",[299,810,369],{}," boundary.",[488,813,814,808,816,818,819,565,821,823],{},[299,815,343],{},[299,817,382],{}," shared code path (",[299,820,505],{},[299,822,493],{},").",[488,825,826,829,830,833,834,837],{},[299,827,828],{},"internal\u002F"," vs ",[299,831,832],{},"apps\u002F"," — why ",[299,835,836],{},"support-bot"," isn't an app.",[839,840,841],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":642,"searchDepth":670,"depth":670,"links":843},[844,847,848,849,850,851,852],{"id":312,"depth":670,"text":313,"children":845},[846],{"id":417,"depth":678,"text":418},{"id":482,"depth":670,"text":483},{"id":527,"depth":670,"text":528},{"id":581,"depth":670,"text":582},{"id":627,"depth":670,"text":628},{"id":707,"depth":670,"text":708},{"id":783,"depth":670,"text":784},"Map of apps, packages, and infra in the studyflash monorepo — what each is for and where boundaries lie.","md",null,{},true,"rajiv",{"title":33,"description":853},"published","monorepo-structure",[863,864,865],"architecture","monorepo","onboarding","PPMg1Ni2wAEOkn2VEA2CNluRJ2w4suKe91HgrbKDVlE",1779007962944]