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.
- Přehled systému (pro stakeholdery)
- Detailní architektura (pro vývojáře)
- Kdo má kam přístup
- Autentizace a správa sessions
- Tok zprávy od uživatele k agentovi
- Bezpečnostní vrstvy
- Knowledge — co agent ví a umí
- Rate limiting — podrobně
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
| 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ě |
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
| 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 |
| 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 |
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
| 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).
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í.
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
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
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
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
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
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
Pro koho: všichni — ukazuje schopnosti AI asistenta. Co ukazuje: zdroje znalostí, nástroje a dovednosti agenta.
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í
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
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
Samostatná sekce — detailní vysvětlení rate limitingu včetně hypotetického nasazení před standardní Sloneek API.
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
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
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
Hypotetický scénář: Co kdyby se rate limiter nasadil jako ochranná vrstva přímo před standardní Sloneek API (ne jen v Chat Interface)?
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
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í |
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
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
| 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 |
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
| 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 |