.. _Architecture: ๐Ÿ—๏ธ Architecture ================ This document describes TINO's high-level architecture and links to the individual Architecture Decision Records (ADRs) that explain key design choices. Components ---------- TINO is a single Python process (FastAPI) that serves both the REST/WebSocket API and the static frontend. There is no separate frontend build step and no external runtime dependencies beyond a filesystem and an optional OIDC provider. .. mermaid:: graph TD subgraph Browser JS[Vanilla JS] CM[CodeMirror 6] YC[Yjs CRDT client] end subgraph FastAPI R["REST routers
auth ยท buckets ยท files ยท git ยท compile ยท โ€ฆ"] C["Collab
Yjs room manager"] end FS[("Filesystem
git repos")] T["Typst CLI
subprocess"] O["OIDC provider
optional"] Browser -->|HTTP / REST| R YC -->|WebSocket| C R --> FS C --> FS R --> T R --> O Storage layout -------------- All persistent state lives on the filesystem โ€” no database is required. .. code-block:: text TINO_DATA_DIR/ โ”œโ”€โ”€ buckets/ โ† TINO_BUCKET_DIR โ”‚ โ”œโ”€โ”€ / โ† one directory per bucket โ”‚ โ”‚ โ”œโ”€โ”€ .git/ โ† full git repository โ”‚ โ”‚ โ”œโ”€โ”€ .meta.yml โ† bucket metadata (description, access rules) โ”‚ โ”‚ โ””โ”€โ”€ *.typ, img/, โ€ฆ โ† source files โ”‚ โ””โ”€โ”€ packages/ โ† TINO_PACKAGE_DIR (local Typst packages) โ””โ”€โ”€ fonts/ โ† TINO_FONT_DIR (custom fonts) Request lifecycle ----------------- A typical editing session follows this flow: .. mermaid:: sequenceDiagram actor User participant Browser participant FastAPI participant Collab as Yjs rooms participant Typst as Typst CLI participant FS as Filesystem User->>Browser: open TINO Browser->>FastAPI: GET / FastAPI-->>Browser: static frontend User->>Browser: log in Browser->>FastAPI: GET /oidc/login FastAPI-->>Browser: redirect โ†’ OIDC provider โ†’ session cookie User->>Browser: select bucket Browser->>FastAPI: GET /api/buckets FastAPI->>FS: list bucket dirs FastAPI-->>Browser: bucket list User->>Browser: open file Browser->>FastAPI: GET /api/buckets/{slug}/files/{path} FastAPI->>FS: read file FastAPI-->>Browser: file content Browser->>Collab: WS /api/buckets/{slug}/collab/{path} Collab->>FS: load saved state Collab-->>Browser: sync Yjs document User->>Browser: type Browser->>Collab: Yjs update (WebSocket) Collab-->>Browser: broadcast to other clients Note over Browser: auto-save debounce fires Browser->>FastAPI: PUT /api/buckets/{slug}/files/{path} FastAPI->>FS: write file Note over Browser: save triggers preview Browser->>FastAPI: GET /api/buckets/{slug}/compile/svg/{path} FastAPI->>Typst: typst compile --format svg Typst->>FS: read source + fonts Typst-->>FastAPI: SVG pages FastAPI-->>Browser: SVG pages Architecture Decision Records ------------------------------ .. toctree:: :maxdepth: 1 :glob: adr/*