Skip to content

Instantly share code, notes, and snippets.

@chocholous
Created February 22, 2026 14:04
Show Gist options
  • Select an option

  • Save chocholous/cf16eb93ae106182730149bf01de14e0 to your computer and use it in GitHub Desktop.

Select an option

Save chocholous/cf16eb93ae106182730149bf01de14e0 to your computer and use it in GitHub Desktop.

Architektura Sloneek Chat Interface

Vizualizace systému pro stakeholdery i technický tým. Všechny diagramy jsou ve formátu Mermaid — renderují se na GitHubu, v VS Code (s rozšířením), nebo na mermaid.live.


Obsah

  1. Přehled systému (pro stakeholdery)
  2. Detailní architektura (pro vývojáře)
  3. Kdo má kam přístup
  4. Autentizace a správa sessions
  5. Tok zprávy od uživatele k agentovi
  6. Bezpečnostní vrstvy
  7. Knowledge — co agent ví a umí
  8. Rate limiting — podrobně

1. Přehled systému

Pro koho: stakeholdeři, management, nový člen týmu. Co ukazuje: hlavní komponenty a jejich účel, bez technických detailů.

graph TB
    subgraph UŽIVATEL["👤 HR Profesionál"]
        browser["Webový prohlížeč"]
    end

    subgraph SYSTEM["Sloneek Chat Interface"]
        direction TB
        frontend["🖥️  Webová aplikace<br/><i>React chat rozhraní</i>"]
        auth["🔐 Přihlášení & správa sessions<br/><i>E-mail + heslo, JWT cookie</i>"]
        orchestrator["🎯 Orchestrátor<br/><i>Správa chatů, historie, nastavení</i>"]
        agent["🤖 AI Agent<br/><i>Claude Opus — HR asistent</i>"]
        proxy["🛡️  Bezpečnostní brána<br/><i>Rate limiting, audit, allowlist</i>"]
    end

    subgraph EXTERNI["🌐 Externí služby"]
        sloneek_api["Sloneek HR API<br/><i>Zaměstnanci, absence, docházka...</i>"]
        anthropic["Anthropic API<br/><i>Claude AI model</i>"]
    end

    subgraph KNOWLEDGE["📚 Znalostní báze"]
        hc["Sloneek Help Center<br/><i>130+ článků nápovědy</i>"]
        api_docs["API Dokumentace<br/><i>587 operací, 457 endpointů</i>"]
        skills["13 specializovaných skills<br/><i>Absence, docházka, nábor...</i>"]
    end

    browser --> frontend
    frontend --> auth
    frontend --> orchestrator
    orchestrator --> agent
    agent --> proxy
    proxy --> sloneek_api
    proxy --> anthropic
    agent -. "čte" .-> KNOWLEDGE

    style SYSTEM fill:#ededff,stroke:#5245ff,stroke-width:2px
    style EXTERNI fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style KNOWLEDGE fill:#d1fae5,stroke:#10b981,stroke-width:2px
    style UŽIVATEL fill:#f1f5f9,stroke:#64748b,stroke-width:2px
Loading

Co systém dělá (pro netechnické publikum)

Komponenta Účel Přínos
Webová aplikace Chat rozhraní pro HR profesionály Intuitivní ovládání, real-time odpovědi
Přihlášení Ověření identity přes Sloneek účet Stejné přihlášení jako do Sloneeku
Orchestrátor Ukládá historii chatů, nastavení Zachovává kontext mezi konverzacemi
AI Agent Claude Opus — inteligentní HR asistent Rozumí HR doméně, vykonává operace
Bezpečnostní brána Chrání API před zneužitím Rate limiting, auditní log, whitelist
Knowledge Dokumentace, skills, API spec Agent odpovídá přesně a aktuálně

2. Detailní architektura

Pro koho: vývojáři, DevOps. Co ukazuje: všechny služby, porty, protokoly, Docker síť.

graph TB
    subgraph DOCKER["Docker síť: sloneek"]
        direction TB

        subgraph FE["frontend :3000 (dev :4000)"]
            fe_tech["React 19 + Vite 7<br/>assistant-ui v0.12<br/>TailwindCSS v4.1"]
        end

        subgraph LC["login-chat :3002 (dev :4002)"]
            lc_auth["Auth modul<br/><small>SessionManager (JWT HS256)<br/>TokenManager (in-memory)</small>"]
            lc_chat["Chat CRUD<br/><small>SQLite per-user<br/>/data/sqlite/{userId}.db</small>"]
            lc_routes["REST API<br/><small>/api/auth/* /api/chats/*<br/>/api/settings /api/projects</small>"]
        end

        subgraph PX["proxy :3001 (dev :4001)"]
            px_allow["Allowlist middleware<br/><small>3 povolené hosty</small>"]
            px_rate["Rate limiter<br/><small>Sliding window, 3 tiers</small>"]
            px_audit["Audit logger<br/><small>JSONL → /data/audit/</small>"]
            px_proxy["http-proxy-middleware<br/><small>Forward na cílový host</small>"]
        end

        subgraph AG["agent-container :3010 (dev :4010)"]
            ag_sdk["Claude Agent SDK<br/><small>query() + streamování</small>"]
            ag_tools["Nástroje agenta<br/><small>Bash, Read, Write, Edit<br/>Glob, Grep</small>"]
            ag_cli["Sloneek CLI<br/><small>@sloneek/cli<br/>users, teams, absence...</small>"]
            ag_art["Artefakty<br/><small>/data/artifacts/<br/>HTML, SVG, CSV</small>"]
        end

        subgraph SHARED["@sloneek/shared"]
            sh["Typy, config loader<br/>Zod schémata"]
        end
    end

    subgraph EXT["Externí (HTTPS)"]
        api1["api.sloneek.com"]
        api2["api2.sloneek.com"]
        anthropic["api.anthropic.com"]
    end

    FE -->|"HTTP + Cookie"| LC
    LC -->|"x-target-host<br/>x-internal-request"| PX
    LC -->|"POST /chat (SSE)"| AG
    AG -->|"Bash: sloneek CLI<br/>--token $TOKEN"| PX
    PX -->|"HTTPS"| api1
    PX -->|"HTTPS"| api2
    PX -->|"HTTPS"| anthropic
    SHARED -.->|"importuje"| LC
    SHARED -.->|"importuje"| PX
    SHARED -.->|"importuje"| AG

    style DOCKER fill:#f8fafc,stroke:#334155,stroke-width:2px
    style FE fill:#dbeafe,stroke:#3b82f6,stroke-width:1px
    style LC fill:#fce7f3,stroke:#ec4899,stroke-width:1px
    style PX fill:#fef3c7,stroke:#f59e0b,stroke-width:1px
    style AG fill:#d1fae5,stroke:#10b981,stroke-width:1px
    style SHARED fill:#f3e8ff,stroke:#a855f7,stroke-width:1px
    style EXT fill:#fff7ed,stroke:#ea580c,stroke-width:1px
Loading

Porty a protokoly

Služba Interní port Dev port Protokol Healthcheck
Frontend 3000 4000 HTTP (Vite)
Login-Chat 3002 4002 HTTP (Express 5) GET /health
Proxy 3001 4001 HTTP (Express 5) GET /health
Agent 3010 4010 HTTP + SSE (Express 5) GET /health

Datové úložiště

Co Kde Formát
Chaty + zprávy /data/sqlite/{userId}.db SQLite per-user
Audit log /data/audit/audit.jsonl JSON Lines
Artefakty agenta /data/artifacts/ HTML, SVG, CSV
Nahrané soubory /data/projects/ Původní formát
Konfigurace root_config.yml YAML
Secrets .env Key=Value

3. Kdo má kam přístup

Pro koho: security review, stakeholdeři. Co ukazuje: oprávnění a izolace mezi komponentami.

graph LR
    subgraph BROWSER["Prohlížeč (uživatel)"]
        user["👤"]
    end

    subgraph FE["Frontend"]
        fe["React SPA"]
    end

    subgraph LC["Login-Chat"]
        lc["Orchestrátor"]
    end

    subgraph PX["Proxy"]
        px["Brána"]
    end

    subgraph AG["Agent"]
        ag["Claude SDK"]
    end

    subgraph DATA["Data"]
        sqlite[("SQLite")]
        audit[("Audit log")]
        artifacts[("Artefakty")]
    end

    subgraph EXT["Sloneek API"]
        api["api2.sloneek.com"]
    end

    user -->|"Session cookie<br/>HTTPS"| fe
    fe -->|"REST API<br/>Cookie auth"| lc
    lc -->|"SSE stream<br/>access_token"| ag
    lc -->|"Proxy volání<br/>x-internal-request"| px
    ag -->|"CLI přes Bash<br/>--token"| px
    px -->|"HTTPS<br/>Bearer token"| api

    lc -->|"R/W"| sqlite
    px -->|"Append"| audit
    ag -->|"Write"| artifacts

    user -.->|"NEMÁ přístup"| sqlite
    user -.->|"NEMÁ přístup"| api
    fe -.->|"NEMÁ přístup"| sqlite
    fe -.->|"NEMÁ přístup"| api
    ag -.->|"NEMÁ přístup"| sqlite

    linkStyle 7,8,9 stroke:#ef4444,stroke-dasharray:5
    linkStyle 10,11,12 stroke:#ef4444,stroke-dasharray:5

    style BROWSER fill:#f1f5f9,stroke:#64748b
    style FE fill:#dbeafe,stroke:#3b82f6
    style LC fill:#fce7f3,stroke:#ec4899
    style PX fill:#fef3c7,stroke:#f59e0b
    style AG fill:#d1fae5,stroke:#10b981
    style DATA fill:#f3e8ff,stroke:#a855f7
    style EXT fill:#fff7ed,stroke:#ea580c
Loading

Matice přístupu

Komponenta Frontend Login-Chat Proxy Agent Sloneek API SQLite Audit
Frontend REST + Cookie
Login-Chat HTTP (interní) SSE R/W
Proxy HTTPS Append
Agent přes CLI přes Proxy
Uživatel Prohlížeč

Klíčový princip: Žádná komponenta nemá přímý přístup k Sloneek API — vše prochází přes Proxy (allowlist + rate limit + audit).


4. Autentizace a správa sessions

Pro koho: všichni — bezpečnost je důležitá pro každého. Co ukazuje: jak probíhá přihlášení, obnova tokenů a odhlášení.

4.1 Přihlášení

sequenceDiagram
    participant U as 👤 Uživatel
    participant FE as Frontend
    participant LC as Login-Chat
    participant PX as Proxy
    participant API as Sloneek API

    U->>FE: Zadá e-mail + heslo
    FE->>LC: POST /api/auth/login<br/>{email, password}

    LC->>PX: POST /auth/login<br/>+ x-target-host: api2.sloneek.com<br/>+ x-internal-request: true

    Note over PX: ✅ Allowlist check<br/>✅ Rate limit check<br/>📝 Audit log zápis

    PX->>API: POST /auth/login<br/>{email, password, client_id, secret}
    API-->>PX: {access_token, refresh_token,<br/>access_token_expires_at}
    PX-->>LC: Forward odpovědi

    Note over LC: 🔑 TokenManager uloží<br/>tokeny do paměti<br/>⏱️  Spustí refresh timer (120s)

    LC->>LC: Vytvoří JWT session cookie<br/>(HS256, max 24h)
    LC-->>FE: Set-Cookie: session=JWT<br/>{userId, orgId}
    FE-->>U: ✅ Přihlášen — zobrazí chat
Loading

4.2 Životní cyklus session

stateDiagram-v2
    [*] --> Nepřihlášen

    Nepřihlášen --> Přihlášení: E-mail + heslo
    Přihlášení --> Aktivní: Sloneek API OK ✅
    Přihlášení --> Nepřihlášen: Špatné údaje ❌

    Aktivní --> Aktivní: Každých 120s → check + refresh
    Aktivní --> ObnováTokenu: Token expiruje za <60s
    ObnováTokenu --> Aktivní: Refresh OK ✅
    ObnováTokenu --> RetryBackoff: Refresh selhal
    RetryBackoff --> ObnováTokenu: Retry (max 3×)
    RetryBackoff --> Nepřihlášen: 3× selhání → odhlášení

    Aktivní --> Nepřihlášen: Nečinnost >10 min
    Aktivní --> Nepřihlášen: Cookie expirovala (24h)
    Aktivní --> Nepřihlášen: Uživatel klikne Odhlásit

    note right of Aktivní
        Token v paměti serveru
        Cookie v prohlížeči
        Obnovuje se automaticky
    end note

    note right of RetryBackoff
        1. pokus: čeká 2s
        2. pokus: čeká 4s
        3. pokus: čeká 8s
    end note
Loading

4.3 Kde se co ukládá

graph LR
    subgraph BROWSER["Prohlížeč"]
        cookie["🍪 Session Cookie<br/><small>JWT (HS256)<br/>HttpOnly, SameSite=Lax<br/>Max-Age: 24h</small>"]
    end

    subgraph LC["Login-Chat (paměť)"]
        tm["🔑 TokenManager<br/><small>access_token<br/>refresh_token<br/>expires_at<br/>lastActivity</small>"]
    end

    subgraph NOWHERE["Nikde se NEUKLÁDÁ"]
        no1["❌ Heslo uživatele"]
        no2["❌ Token na disku"]
        no3["❌ Token ve frontend"]
    end

    cookie ---|"obsahuje: userId, orgId"| tm
    tm ---|"automaticky obnovuje"| tm

    style BROWSER fill:#dbeafe,stroke:#3b82f6
    style LC fill:#fce7f3,stroke:#ec4899
    style NOWHERE fill:#fee2e2,stroke:#ef4444
Loading

5. Tok zprávy od uživatele k agentovi

Pro koho: vývojáři, kdo chce pochopit jak chat funguje. Co ukazuje: celý lifecycle jedné zprávy — od odeslání po zobrazení odpovědi.

sequenceDiagram
    participant U as 👤 Uživatel
    participant FE as Frontend
    participant LC as Login-Chat
    participant AG as Agent
    participant PX as Proxy
    participant API as Sloneek API

    U->>FE: Napíše zprávu v chatu
    FE->>LC: POST /api/chats/:id/message<br/>{message, attachmentIds}

    Note over LC: 🔍 Ověří session (JWT cookie)<br/>📂 Načte chat ze SQLite<br/>🔑 Získá access_token z TokenManager<br/>⚙️  Načte user settings + projekt<br/>💾 Uloží
user message do SQLite

    LC->>AG: POST /chat (SSE stream)<br/>{chatId, message, accessToken,<br/>systemPrompt, model, attachments}

    Note over AG: 🧠 Sestaví system prompt<br/>📎 Zpracuje přílohy<br/>🚀 Spustí query() na Claude SDK

    loop Streamování odpovědi
        AG-->>LC: SSE: data: {type: "text", text: "..."}
        LC-->>FE: Forward SSE event
        FE-->>U: Zobrazí text v reálném čase

        opt Agent potřebuje data ze Sloneek
            AG->>AG: Bash: sloneek users list --token $TOKEN
            AG->>PX: CLI → HTTP request
            Note over PX: ✅ Allowlist<br/>✅ Rate limit<br/>📝 Audit
            PX->>API: HTTPS request
            API-->>PX: JSON response
            PX-->>AG: Forward
            AG-->>LC: SSE: {type: "tool_use"} + {type: "tool_result"}
            LC-->>FE: Forward
            FE-->>U: Zobrazí výsledek nástroje
        end

        opt Agent vytvoří artefakt
            AG->>AG: Write → /data/artifacts/report.html
            AG-->>LC: SSE: {type: "artifact", filename, content}
            LC-->>FE: Forward
            FE-->>U: Zobrazí v postranním panelu
        end

        opt Agent se potřebuje zeptat
            AG-->>LC: SSE: {type: "ask_user_question", questions}
            LC-->>FE: Forward
            FE-->>U: Zobrazí modální okno s otázkami
            U->>FE: Vybere odpověď
            FE->>LC: POST /api/chats/:id/tool-response
            LC->>AG: POST /tool-response
            Note over AG: ▶️  Pokračuje ve streamu
        end
    end

    AG-->>LC: SSE: {type: "done"}
    Note over LC: 💾 Uloží odpověď do SQLite<br/>🏷️  Auto-generuje titulek (Haiku)
    LC-->>FE: SSE: {type: "title_updated", title}
    FE-->>U: Aktualizuje titulek chatu
Loading

6. Bezpečnostní vrstvy

Pro koho: security review, stakeholdeři. Co ukazuje: ochranné mechanismy na každé úrovni.

graph TB
    subgraph L1["Vrstva 1: Prohlížeč"]
        b1["🍪 HttpOnly cookie — JS nemá přístup k tokenu"]
        b2["🔒 SameSite=Lax — ochrana proti CSRF"]
        b3["⚛️  React JSX auto-escaping — ochrana proti XSS"]
    end

    subgraph L2["Vrstva 2: Login-Chat"]
        c1["🔐 JWT ověření na každém requestu"]
        c2["⏱️  Session max 24h + idle timeout 10 min"]
        c3["🔑 Tokeny jen v paměti — nikdy na disku"]
        c4["🔄 Auto-refresh s retry + exponential backoff"]
        c5["🗄️  Parameterized SQL queries — ochrana proti injection"]
    end

    subgraph L3["Vrstva 3: Proxy"]
        d1["📋 Allowlist — jen 3 povolené hosty"]
        d2["🚦 Rate limiting — 5/s, 60/min, 1000/h"]
        d3["📝 Audit log — každý request logován"]
        d4["🏷️  Interní hlavičky odstraněny před odesláním"]
    end

    subgraph L4["Vrstva 4: Agent Sandbox"]
        e1["📦 Read-only rootfs — agent nemůže měnit systém"]
        e2["🔒 cap_drop: ALL — žádné Linux capabilities"]
        e3["🚫 no-new-privileges — nemůže eskalovat"]
        e4["💾 tmpfs /tmp: 64MB, noexec, nosuid"]
        e5["📏 Memory limit: 512MB, CPU limit: 1.0"]
    end

    L1 --> L2 --> L3 --> L4

    style L1 fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
    style L2 fill:#fce7f3,stroke:#ec4899,stroke-width:2px
    style L3 fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style L4 fill:#d1fae5,stroke:#10b981,stroke-width:2px
Loading

Hrozby a mitigace

graph LR
    subgraph HROZBY["⚠️  Hrozby"]
        t1["Přímý přístup k API"]
        t2["Krádež tokenu"]
        t3["Brute-force login"]
        t4["SQL injection"]
        t5["XSS útok"]
        t6["Agent útěk ze sandboxu"]
        t7["DDoS / přetížení API"]
    end

    subgraph OBRANA["🛡️  Obrana"]
        d1["Proxy allowlist<br/>(jen 3 hosty)"]
        d2["HttpOnly cookie<br/>+ paměťový token store"]
        d3["Rate limiting<br/>(5 req/sec)"]
        d4["Parameterized queries<br/>(better-sqlite3)"]
        d5["React JSX escaping<br/>+ no dangerouslySetInnerHTML"]
        d6["Read-only rootfs<br/>+ cap_drop ALL<br/>+ no-new-privileges"]
        d7["Sliding window<br/>+ tier multipliers<br/>+ Retry-After header"]
    end

    t1 --> d1
    t2 --> d2
    t3 --> d3
    t4 --> d4
    t5 --> d5
    t6 --> d6
    t7 --> d7

    style HROZBY fill:#fee2e2,stroke:#ef4444,stroke-width:2px
    style OBRANA fill:#d1fae5,stroke:#10b981,stroke-width:2px
Loading

7. Knowledge — co agent ví a umí

Pro koho: všichni — ukazuje schopnosti AI asistenta. Co ukazuje: zdroje znalostí, nástroje a dovednosti agenta.

7.1 Zdroje znalostí

mindmap
    root((🤖 AI Agent<br/>Claude Opus))
        📚 Znalostní báze
            Sloneek Help Center
                130+ článků nápovědy
                /reference/sloneek-hc-articles.json
            API Dokumentace
                457 endpointů
                587 operací
                /docs-ref/sloneek-api-spec-extended.json
            User dokumentace
                91 KB, 24 sekcí
                /docs-ref/sloneek-user-docs.md
        🛠️  Nástroje
            Bash — spouštění příkazů
            Read/Write/Edit — práce se soubory
            Glob/Grep — vyhledávání
            AskUserQuestion — dotazy na uživatele
            EnterPlanMode — plánovací režim
        🎯 Skills (13)
            managing-absences
            managing-employees
            tracking-attendance
            recruiting-candidates
            managing-documents
            planning-events
            generating-reports
            running-surveys
            analyzing-engagement
            managing-workflows
            taking-screenshots
            browsing-api-reference
        🔧 Sloneek CLI
            users — zaměstnanci
            teams — týmy
            absence — dovolená
            attendance — docházka
            ats — nábor
            documents — dokumenty
            planning — plánování
            engagement — zapojení
            workflows — procesy
            raw — přímé API volání
Loading

7.2 Jak agent zpracovává dotaz

flowchart TD
    START["👤 Uživatel: 'Kolik dovolené zbývá Janu Novákovi?'"]

    START --> PROMPT["🧠 Sestavení kontextu"]
    PROMPT --> |"System prompt<br/>+ User settings<br/>+ Project context"| SKILL

    SKILL{"📖 Existuje relevantní skill?"}
    SKILL -->|"Ano: managing-absences"| READ_SKILL["Přečte SKILL.md<br/>pro specifické instrukce"]
    SKILL -->|"Ne"| GENERAL["Použije obecné znalosti"]

    READ_SKILL --> CLI["🔧 Zavolá Sloneek CLI"]
    GENERAL --> CLI

    CLI --> |"sloneek absence balances<br/>--user-id UUID --token $TOKEN"| PROXY["Požadavek přes Proxy"]

    PROXY --> |"Rate limit ✅<br/>Allowlist ✅<br/>Audit ✅"| API["Sloneek API"]

    API --> |"JSON odpověď"| FORMAT{"📊 Formátování výstupu"}

    FORMAT --> |"Jednoduchý výsledek"| MD["Markdown tabulka<br/>(inline v chatu)"]
    FORMAT --> |"Složitější vizualizace"| HTML["HTML artefakt<br/>(postranní panel)"]
    FORMAT --> |"Data pro export"| CSV["CSV soubor<br/>(ke stažení)"]

    MD --> LINKS["📎 Přidá odkaz na nápovědu"]
    HTML --> LINKS
    CSV --> LINKS

    LINKS --> DONE["✅ Zobrazí uživateli"]

    style START fill:#dbeafe,stroke:#3b82f6
    style PROMPT fill:#f3e8ff,stroke:#a855f7
    style CLI fill:#d1fae5,stroke:#10b981
    style PROXY fill:#fef3c7,stroke:#f59e0b
    style API fill:#fff7ed,stroke:#ea580c
    style DONE fill:#d1fae5,stroke:#10b981
Loading

7.3 Výstupní formáty agenta

graph LR
    subgraph INPUT["Vstup"]
        q1["Jednoduchý dotaz<br/><small>'Kdo je ve Finance týmu?'</small>"]
        q2["Dashboard / report<br/><small>'Přehled absencí za Q1'</small>"]
        q3["Export dat<br/><small>'Exportuj seznam zaměstnanců'</small>"]
        q4["Proces / workflow<br/><small>'Jak funguje schvalování?'</small>"]
        q5["Org. struktura<br/><small>'Ukaž hierarchii týmů'</small>"]
    end

    subgraph OUTPUT["Výstup"]
        o1["📋 Markdown tabulka<br/><small>Inline v chatu</small>"]
        o2["🖥️  HTML artefakt<br/><small>Interaktivní dashboard<br/>Karty, grafy, tabulky</small>"]
        o3["📄 CSV soubor<br/><small>Stažitelný pro Excel</small>"]
        o4["📊 Mermaid diagram<br/><small>Flowchart v chatu</small>"]
        o5["🖼️  SVG artefakt<br/><small>Vektorová grafika</small>"]
    end

    q1 --> o1
    q2 --> o2
    q3 --> o3
    q4 --> o4
    q5 --> o5

    style INPUT fill:#dbeafe,stroke:#3b82f6
    style OUTPUT fill:#d1fae5,stroke:#10b981
Loading

8. Rate limiting

Samostatná sekce — detailní vysvětlení rate limitingu včetně hypotetického nasazení před standardní Sloneek API.

8.1 Jak funguje rate limiting v Chat Interface

graph TD
    REQ["📨 Příchozí HTTP request"]
    REQ --> ALLOW{"📋 Je host na allowlistu?"}

    ALLOW -->|"❌ Ne"| BLOCK_403["🚫 403 Forbidden"]
    ALLOW -->|"✅ Ano"| INTERNAL{"🔒 Je to interní cesta?<br/>/auth/login, /auth/refresh"}

    INTERNAL -->|"Ano"| CHECK_HEADER{"Má hlavičku<br/>x-internal-request?"}
    CHECK_HEADER -->|"❌ Ne"| BLOCK_403
    CHECK_HEADER -->|"✅ Ano"| RATE

    INTERNAL -->|"Ne"| RATE{"🚦 Rate limit check"}

    RATE --> EXTRACT["Extrahuj Bearer token<br/>z Authorization hlavičky"]
    EXTRACT --> TIER{"Jaký tier má token?"}

    TIER -->|"free / professional"| LIMITS_STD["Limity: 1×<br/>5/s · 60/min · 1000/h"]
    TIER -->|"enterprise"| LIMITS_ENT["Limity: 4×<br/>20/s · 240/min · 4000/h"]

    LIMITS_STD --> WINDOW["Sliding window check<br/>(per-token, per-window)"]
    LIMITS_ENT --> WINDOW

    WINDOW -->|"✅ Pod limitem"| AUDIT["📝 Audit log zápis"]
    WINDOW -->|"❌ Limit překročen"| BLOCK_429["🚫 429 Too Many Requests<br/>+ Retry-After hlavička"]

    AUDIT --> PROXY["➡️  Forward na cílový host"]
    PROXY --> RESPONSE["📨 Odpověď klientovi<br/>+ X-RateLimit-* hlavičky"]

    style REQ fill:#dbeafe,stroke:#3b82f6
    style BLOCK_403 fill:#fee2e2,stroke:#ef4444
    style BLOCK_429 fill:#fee2e2,stroke:#ef4444
    style AUDIT fill:#f3e8ff,stroke:#a855f7
    style RESPONSE fill:#d1fae5,stroke:#10b981
Loading

8.2 Sliding window — vizualizace

gantt
    title Sliding Window — 5 req/sec limit (ilustrace)
    dateFormat X
    axisFormat %S s

    section Požadavky
    Req 1 (OK)          :done, r1, 0, 1
    Req 2 (OK)          :done, r2, 1, 2
    Req 3 (OK)          :done, r3, 2, 3
    Req 4 (OK)          :done, r4, 3, 4
    Req 5 (OK)          :done, r5, 4, 5
    Req 6 (BLOCKED 429) :crit, r6, 5, 6

    section Okno
    1-sekundové okno    :active, w1, 0, 10
Loading

8.3 Tier systém

graph LR
    subgraph FREE["Free / Professional"]
        f1["5 req/sec"]
        f2["60 req/min"]
        f3["1 000 req/hod"]
    end

    subgraph ENT["Enterprise (4×)"]
        e1["20 req/sec"]
        e2["240 req/min"]
        e3["4 000 req/hod"]
    end

    TOKEN["🔑 Bearer token"] --> CACHE["TierCache<br/>(5 min TTL)"]
    CACHE --> |"Detekce tieru"| FREE
    CACHE --> |"Detekce tieru"| ENT

    style FREE fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
    style ENT fill:#d1fae5,stroke:#10b981,stroke-width:2px
Loading

8.4 Rate Limiter jako samostatná služba před Sloneek API

Hypotetický scénář: Co kdyby se rate limiter nasadil jako ochranná vrstva přímo před standardní Sloneek API (ne jen v Chat Interface)?

Současný stav — bez ochrany

graph LR
    subgraph KLIENTI["Klienti Sloneek API"]
        c1["📱 Mobilní app"]
        c2["🖥️  Web app"]
        c3["🔗 Integrace<br/>(Zapier, Make...)"]
        c4["🤖 AI Chat Interface"]
        c5["📊 Interní skripty"]
        c6["❓ Neznámí klienti"]
    end

    subgraph API["Sloneek API"]
        api["api2.sloneek.com<br/><br/>⚠️  Žádný veřejný<br/>rate limiting"]
    end

    c1 -->|"neomezeno"| api
    c2 -->|"neomezeno"| api
    c3 -->|"neomezeno"| api
    c4 -->|"rate limited ✅"| api
    c5 -->|"neomezeno"| api
    c6 -->|"neomezeno"| api

    style KLIENTI fill:#fee2e2,stroke:#ef4444,stroke-width:2px
    style API fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
Loading

Problémy bez rate limitingu na API:

Riziko Dopad Pravděpodobnost
Jedno špatné integrace → zaplaví API Degradace pro všechny uživatele Vysoká
Neošetřený retry loop v klientovi Kaskádové přetížení Střední
Úmyslný DDoS Výpadek služby Nízká
Crawling / scraping dat Zvýšená latence + náklady Střední
Bug v AI agentu (nekonečná smyčka) Tisíce requestů za minutu Střední

Navrhovaný stav — s rate limiterem

graph LR
    subgraph KLIENTI["Klienti Sloneek API"]
        c1["📱 Mobilní app"]
        c2["🖥️  Web app"]
        c3["🔗 Integrace"]
        c4["🤖 AI Chat Interface"]
        c5["📊 Interní skripty"]
        c6["❓ Neznámí klienti"]
    end

    subgraph RL["🛡️  Rate Limiter Gateway"]
        direction TB
        allow["📋 Allowlist / blocklist"]
        rate["🚦 Per-token sliding window"]
        tier["📊 Tier-based limity"]
        audit["📝 Audit trail"]
        headers["📨 X-RateLimit-* hlavičky"]
        retry["⏳ Retry-After na 429"]
    end

    subgraph API["Sloneek API"]
        api["api2.sloneek.com<br/><br/>✅ Chráněno"]
    end

    c1 -->|"request"| RL
    c2 -->|"request"| RL
    c3 -->|"request"| RL
    c4 -->|"request"| RL
    c5 -->|"request"| RL
    c6 -->|"request"| RL

    RL -->|"✅ Propuštěno"| api
    RL -.->|"❌ 429 Odmítnuto"| KLIENTI

    style KLIENTI fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
    style RL fill:#d1fae5,stroke:#10b981,stroke-width:3px
    style API fill:#d1fae5,stroke:#10b981,stroke-width:2px
Loading

Srovnání: Před a po nasazení

graph TB
    subgraph BEFORE["❌ BEZ Rate Limiteru"]
        direction TB
        b1["Žádná ochrana proti přetížení"]
        b2["Žádná viditelnost kdo kolik volá"]
        b3["Jeden klient může shodit API"]
        b4["Žádné fair-use vynucování"]
        b5["Žádná retry-after logika"]
        b6["Komplikované ladění problémů"]
    end

    subgraph AFTER["✅ S Rate Limiterem"]
        direction TB
        a1["Per-token limity (sliding window)"]
        a2["Kompletní audit log (kdo, co, kdy)"]
        a3["Izolace klientů — jeden neovlivní ostatní"]
        a4["Tier-based přístup (free/pro/enterprise)"]
        a5["Retry-After + X-RateLimit hlavičky"]
        a6["Dashboard metrik z audit logu"]
    end

    style BEFORE fill:#fee2e2,stroke:#ef4444,stroke-width:2px
    style AFTER fill:#d1fae5,stroke:#10b981,stroke-width:2px
Loading

Konkrétní přínosy rate limiteru před Sloneek API

Přínos Detail Business hodnota
Ochrana proti přetížení Max 5 req/s per token (free), 20 req/s (enterprise) Stabilita pro všechny zákazníky
Fair-use vynucování Tier systém — enterprise klienti mají 4× vyšší limity Monetizace API přístupu
Audit trail Každý request logován: kdo, kdy, kam, jak rychle Compliance, debugging, fakturace
Graceful degradace 429 + Retry-After místo 500 Klienti vědí co dělat
Viditelnost X-RateLimit-Limit/Remaining hlavičky Klienti monitorují vlastní usage
Izolace selhání Jeden buggy klient neshazí API pro ostatní Snížení support ticketů
Jitter na retry 30–300s randomizovaný jitter Zabránění thundering herd efektu
Budoucí rozšíření Snadné přidání: quota per měsíc, burst limity, IP blocking Škálovatelný základ

Architektura nasazení

graph TD
    subgraph DEPLOY["Možnosti nasazení"]
        direction TB

        subgraph OPT1["Varianta A: Reverse proxy"]
            rp["Nginx/Caddy<br/>+ Rate limit modul"]
        end

        subgraph OPT2["Varianta B: Standalone služba"]
            standalone["@sloneek/rate-limiter<br/>jako Express middleware<br/>(existující kód)"]
        end

        subgraph OPT3["Varianta C: API Gateway"]
            gw["Kong / AWS API Gateway<br/>+ custom plugin"]
        end
    end

    NOTE["💡 Varianta B je nejsnadnější —<br/>kód už existuje v monorepu,<br/>stačí nasadit jako samostatnou službu<br/>s vlastním root_config.yml"]

    style OPT2 fill:#d1fae5,stroke:#10b981,stroke-width:3px
    style NOTE fill:#ededff,stroke:#5245ff,stroke-width:2px
Loading

Legenda

Symbol Význam
Plná čára (→) Datový tok / přístup
Čárkovaná čára (- - ->) Nemá přístup / blokováno
🔐 Autentizace
🛡️ Bezpečnostní vrstva
🤖 AI Agent
📝 Logging / audit
🚦 Rate limiting
📚 Knowledge / dokumentace
Povoleno / OK
Blokováno / chyba
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment