OllinDocs
Architecture

Repository layout

Where each piece lives — the app, the API, and the data plane.

Three codebases carry the system, one per architectural role:

RepoRoleStack
repos/ollin-studyThis app. The user-facing study product; also hosts these docs at /docs.Next.js App Router, React, TypeScript, Tailwind v4, shadcn-style UI, Vitest. pnpm 10.28.1.
repos/ollin-study-apiServing API. Stateless read-only pack server.Fastify + TypeScript (tsx), Vitest, Docker/Cloud Run. pnpm 10.28.1.
solver-lab/Data plane + verification workspace. Extraction ETLs, backbone ops, gate runs, specs.Python (ETLs), operating docs.

ollin-study (this repo)

src/
  app/
    (product)/            # the product shell (topbar + main)
      study/              # preflop tree  →  /study
      study/library/      # family index  →  /study/library
      study/[spotId]/     # family view + [boardId] strategy browser
      methodology/  practice/  analyze/
    docs/                 # Fumadocs layout + catch-all page (this site)
    api/search/           # docs search route (Orama)
  components/
    preflop/  study/      # screen components
    shell/                # topbar, demo ribbon
    docs/                 # MDX registry, Mermaid
  lib/
    api/                  # fetch layer, wire contracts (mirrored), view models, mock/
    poker/                # boards, cards, 169 classes, combo query
content/docs/             # these pages (MDX)

The wire contracts under src/lib/api/contract.ts and src/lib/api/preflop-contract.ts are mirrors of the API's schema files — see Data flow.

ollin-study-api

schema/                   # THE frozen contracts: node-document.v1.ts, preflop.v1.ts
                          #   + JSON Schema mirrors (*.schema.json)
src/
  routes/v1.ts            # families / boards / node-slot endpoints
  routes/preflop.ts       # preflop catalog / depth / node / boundaries
  serving/                # catalog, grid169 aggregation, cache headers, card utils
  store/                  # local + GCS pack sources, sha256 LRU, v0 pack adapter
scripts/agpl-check.sh     # the CI deny-gate
fixtures/                 # fabricated packs (tests, offline dev)
fixtures-real/            # trimmed copies of real producer packs

solver-lab (read-only from here)

data_plane/
  extract_roots_v0.py     # backbone roots → v0-roots serving packs
  extract_preflop_v0.py   # HRC exports  → preflop-v0 serving packs
  specs/extraction_spec_v1.md   # Tier-A full-tree extraction (draft)
fleet/                    # campaign ops, BOARDS_184_SPEC, cost notes
verification/  signoffs/  # gate runs over inherited artifacts
STATUS.md                 # live workspace status

The data plane is upstream of everything: the app and API only ever consume what its ETLs publish to gs://ollin-solver-data. Nothing in the serving plane writes.

On this page