Files
libnovel/v3/docs/request-flow.mermaid.md
Admin a85636d5db feat(v3): add v3 stack — backend rewrite, renamed env vars, docs
- New Go backend binary (backend + runner) replacing old scraper/
- Rename SCRAPER_API_URL → BACKEND_API_URL in UI env and docker-compose
- Rename scraperFetch → backendFetch across all 19 UI server files
- Remove SCRAPER_PROXY env var and proxy transport from browser.Config
- Add Meilisearch, Valkey, Caddy to docker-compose
- Add docs/: api-endpoints.md, request-flow.mermaid.md, data-flow.mermaid.md
2026-03-22 17:27:32 +05:00

2.6 KiB

Request Flow

Two representative request paths through the stack: a page load (SSR) and a media playback (presigned URL → direct MinIO stream).

SSR Page Load — Browse / Book Detail

sequenceDiagram
    actor C as Browser / iOS App
    participant CD as Caddy :443
    participant UI as SvelteKit UI :3000
    participant BE as Backend API :8080
    participant MS as Meilisearch :7700
    participant PB as PocketBase :8090
    participant VK as Valkey :6379
    participant MN as MinIO :9000

    C->>CD: HTTPS GET /browse
    CD->>UI: proxy /*
    UI->>BE: GET /api/catalogue?page=1&sort=popular
    BE->>MS: search(query, filters, sort)
    MS-->>BE: [{slug, title, …}, …]
    BE-->>UI: {books[], page, total, has_next}
    UI-->>CD: SSR HTML
    CD-->>C: 200 HTML

    Note over C,UI: Infinite scroll — client fetches next page
    C->>CD: HTTPS GET /api/browse-page?page=2
    CD->>UI: proxy (SvelteKit API route)
    UI->>BE: GET /api/catalogue?page=2
    BE->>MS: search(…)
    MS-->>BE: next page
    BE-->>UI: {books[], …}
    UI-->>C: JSON

Audio Playback — Presigned URL Flow

sequenceDiagram
    actor C as Browser / iOS App
    participant CD as Caddy :443
    participant UI as SvelteKit UI :3000
    participant BE as Backend API :8080
    participant VK as Valkey :6379
    participant MN as MinIO :9000

    C->>CD: GET /api/presign/audio/{slug}/{n}?voice=af_bella
    CD->>BE: proxy /api/*
    BE->>VK: GET presign:audio:{slug}:{n}:{voice}
    alt cache hit
        VK-->>BE: presigned URL (TTL remaining)
        BE-->>C: 302 redirect → presigned URL
    else cache miss
        BE->>MN: GeneratePresignedURL(audio-bucket, key, 1h)
        MN-->>BE: presigned URL
        BE->>VK: SET presign:audio:… EX 3500
        BE-->>C: 302 redirect → presigned URL
    end
    C->>MN: GET presigned URL (direct, no proxy)
    MN-->>C: audio/mpeg stream

Chapter Read — SSR + Content Fetch

sequenceDiagram
    actor C as Browser / iOS App
    participant CD as Caddy :443
    participant UI as SvelteKit UI :3000
    participant BE as Backend API :8080
    participant PB as PocketBase :8090
    participant MN as MinIO :9000

    C->>CD: HTTPS GET /books/{slug}/chapters/{n}
    CD->>UI: proxy /*
    UI->>PB: getBook(slug) + listChapterIdx(slug)
    PB-->>UI: book meta + chapter list
    UI->>BE: GET /api/chapter-markdown/{slug}/{n}
    BE->>MN: GetObject(chapters-bucket, {slug}/{n}.md)
    MN-->>BE: markdown text
    BE-->>UI: markdown body
    Note over UI: marked() → HTML
    UI-->>CD: SSR HTML
    CD-->>C: 200 HTML