```mermaid graph LR %% ── External ────────────────────────────────────────────────────────── NF([novelfire.net]) KK([Kokoro-FastAPI TTS]) CL([Browser / iOS App]) %% ── Init containers ─────────────────────────────────────────────────── subgraph INIT["Init containers (one-shot)"] MI[minio-init\nmc: create buckets] PI[pb-init\nbootstrap collections] end %% ── Storage ─────────────────────────────────────────────────────────── subgraph STORAGE["Storage"] MN[(MinIO :9000\nchapters · audio\navatars · browse)] PB[(PocketBase :8090\nbooks · chapters_idx\naudio_cache · progress\nscrape_jobs · app_users · ranking)] end %% ── Application ─────────────────────────────────────────────────────── subgraph APP["Application"] BE[Backend API :8080\nGo HTTP server] RN[Runner\nGo background worker] UI[SvelteKit UI :5252] end %% ── Init → Storage ──────────────────────────────────────────────────── MI -.->|create buckets| MN PI -.->|bootstrap schema| PB %% ── App → Storage ───────────────────────────────────────────────────── BE -->|blobs| MN BE -->|structured records| PB RN -->|chapter markdown & audio| MN RN -->|read/update jobs & books| PB %% ── App internal ────────────────────────────────────────────────────── UI -->|REST API| BE %% ── Runner → External ───────────────────────────────────────────────── RN -->|scrape HTTP GET| NF RN -->|TTS HTTP POST| KK %% ── Client ──────────────────────────────────────────────────────────── CL -->|HTTPS :5252| UI CL -->|presigned URLs| MN ```