direction: right # ─── External ───────────────────────────────────────────────────────────────── novelfire: novelfire.net { shape: cloud style.fill: "#f0f4ff" } kokoro: Kokoro-FastAPI TTS { shape: cloud style.fill: "#f0f4ff" } browser: Browser / iOS App { shape: person style.fill: "#fff9e6" } # ─── Init containers (one-shot) ─────────────────────────────────────────────── init: Init containers { style.fill: "#f5f5f5" style.stroke-dash: 4 minio-init: minio-init { shape: rectangle label: "minio-init\n(mc: create buckets)" } pb-init: pb-init { shape: rectangle label: "pb-init\n(bootstrap collections)" } } # ─── Storage ────────────────────────────────────────────────────────────────── storage: Storage { style.fill: "#eaf7ea" minio: MinIO { shape: cylinder label: "MinIO :9000\n\nbuckets:\n libnovel-chapters\n libnovel-audio\n libnovel-avatars\n libnovel-browse" } pocketbase: PocketBase { shape: cylinder label: "PocketBase :8090\n\ncollections:\n books chapters_idx\n audio_cache progress\n scrape_jobs app_users\n ranking" } } # ─── Application ────────────────────────────────────────────────────────────── app: Application { style.fill: "#eef3ff" backend: backend { shape: rectangle label: "Backend API :8080\n(Go — HTTP API server)" } runner: runner { shape: rectangle label: "Runner\n(Go — background worker\nscraping + TTS jobs)" } ui: ui { shape: rectangle label: "SvelteKit UI :5252\n(adapter-node)" } } # ─── Init → Storage deps ────────────────────────────────────────────────────── init.minio-init -> storage.minio: create buckets {style.stroke-dash: 4} init.pb-init -> storage.pocketbase: bootstrap schema {style.stroke-dash: 4} # ─── App → Storage ──────────────────────────────────────────────────────────── app.backend -> storage.minio: blobs (chapters, audio,\navatars, browse) app.backend -> storage.pocketbase: structured records\n(books, progress, jobs…) app.runner -> storage.minio: write chapter markdown\n& audio MP3s app.runner -> storage.pocketbase: read/update scrape jobs\nwrite book records # ─── App internal ───────────────────────────────────────────────────────────── app.ui -> app.backend: REST API calls\n(server-side) # ─── External → App ─────────────────────────────────────────────────────────── app.runner -> novelfire: scrape\n(HTTP GET) app.runner -> kokoro: TTS generation\n(HTTP POST) # ─── Browser ────────────────────────────────────────────────────────────────── browser -> app.ui: HTTPS :5252 browser -> storage.minio: presigned URLs\n(audio / chapter downloads)