Datový model
Databáze je PostgreSQL, přístup přes SeaORM. Migrace m_001–m_022 v src/migration/ běží automaticky při startu serveru.
Uživatelé a auth
users
| Sloupec | Typ | Popis |
id | PK | |
username | unique | Přihlašovací jméno |
password_hash | text | Argon2 hash |
tokens
| Sloupec | Typ | Popis |
id | PK | |
nonce | unique | Hodnota tokenu |
user_id | FK → users | Vlastník |
expires_at | timestamp? | NULL = bez expirace |
label | text? | Lidský popis (u service tokenů) |
is_service | bool | false = session cookie (24 h), true = service token (manuální správa) |
oauth_clients
RFC 7591 — dynamicky registrovaní OAuth klienti.
| Sloupec | Typ | Popis |
id | PK | |
client_id | unique | Identifikátor klienta |
client_secret | text? | Volitelné (PKCE-only klienti ho nemají) |
client_name | text | Display name |
redirect_uris | JSON | Seznam povolených redirect URI |
oauth_codes
Krátkodobé authorization codes (10 min, PKCE).
| Sloupec | Typ | Popis |
id | PK | |
code | unique | Auth code |
client_id | text | |
user_id | FK → users | |
redirect_uri | text | |
code_challenge | text | SHA-256 PKCE challenge |
expires_at | timestamp | |
used | bool | One-time use |
oauth_tokens
Access (1 h) + refresh (bez expirace) tokeny.
| Sloupec | Typ | Popis |
id | PK | |
access_token | unique | Bearer pro /mcp a další chráněné API |
refresh_token | unique | Pro grant_type=refresh_token |
client_id, user_id | | |
expires_at | timestamp | Pouze pro access |
revoked | bool | |
Obsah
pages
| Sloupec | Typ | Popis |
id | PK | |
path | unique | URL cesta (např. about/blog) |
summary | text? | Krátký popis |
markdown | text | Obsah stránky |
tag_ids | INT[] | Pole tagů |
private | bool | Skrytá pro nepřihlášené |
created_at/by, modified_at/by | | Audit |
Migrace m_022 přidává fulltext index nad path + markdown (accent-insensitive) — pohání search_pages MCP tool i /search.
page_revisions
| Sloupec | Typ | Popis |
id | PK | |
page_id | FK → pages | |
seq | int | Pořadí revize v rámci stránky |
prev_markdown | text | Stav před změnou |
diff | text | Diff (knihovna diffy) |
created_at/by | | Audit |
tags
| Sloupec | Typ | Popis |
id | PK | |
name | unique | Název tagu |
description | text? | Popis |
menus
Statický obsah pro top-level cesty (např. /about, /blog, /partie).
| Sloupec | Typ | Popis |
id | PK | |
path | unique | URL cesta |
markdown | text | Obsah |
private | bool | Skrytá pro nepřihlášené (od m_008) |
Soubory a galerie
Starý systém images + gallery_images byl v m_010 nahrazen content-addressed schématem (deduplikace přes SHA-256).
files
Metadata souboru.
| Sloupec | Typ | Popis |
id | PK | |
path | unique | Identifikátor / název (přidáno v m_017) |
hash | text | SHA-256 obsahu (FK → file_blobs.hash) |
mimetype | text | Např. image/png |
size_bytes | int | |
description | text? | |
created_at/by | | Audit |
file_blobs
Obsah souboru, deduplikovaný hashem.
| Sloupec | Typ | Popis |
hash | PK | SHA-256 |
data | bytea | Binární obsah |
size_bytes | int | |
created_at | | |
file_thumbnails
Automaticky generované náhledy obrázků (knihovna image).
| Sloupec | Typ | Popis |
file_id | PK / FK → files | |
hash | text | Hash náhledu |
width, height | int | |
mimetype | text | |
galleries
| Sloupec | Typ | Popis |
id | PK | |
path | unique | (přidáno v m_020) |
title | text | |
description | text? | |
file_ids | INT[] | Seznam ID souborů, v pořadí zobrazení |
created_at/by | | Audit |
AI assistant
Detail v about/blog/ai.
llm_providers
| Sloupec | Typ | Popis |
id | PK | |
label | text | Lidský název |
kind | enum | anthropic, ollama, gemini |
api_key | text? | Pokud poskytovatel vyžaduje |
base_url | text? | Pro self-hosted endpointy |
llm_models
Po m_015 rozdělené z původní llm_providers.
| Sloupec | Typ | Popis |
id | PK | |
provider_id | FK → llm_providers | |
label | text | Lidský název |
model | text | Wire ID (např. claude-opus-4-7) |
is_default | bool | |
assistant_sessions
| Sloupec | Typ | Popis |
id | PK | |
user_id | FK → users | |
title | text | |
provider, model | text | Snapshoty pro audit |
model_id | FK → llm_models? | |
enabled_mcp_server_ids | JSONB | Pole ID, které MCP servery jsou v session aktivní (od m_018) |
created_at, updated_at | | |
assistant_messages
| Sloupec | Typ | Popis |
id | PK | |
session_id | FK → assistant_sessions | |
seq | int | Pořadí v session |
role | enum | user, assistant (případně tool) |
content | JSON | Multi-modální obsah (text, tool calls, results) |
created_at | | |
user_mcp_servers
Externí MCP servery, které si uživatel přidá do své AI session.
| Sloupec | Typ | Popis |
id | PK | |
user_id | FK → users | |
name | text | |
url | text | HTTP MCP endpoint |
enabled | bool | |
forward_user_token | bool | Předávat session token do MCP serveru |
headers | JSON | Vlastní hlavičky (např. Authorization) |
tool_permissions
Pravidla pro povolení/zákaz volání nástrojů AI assistentem.
| Sloupec | Typ | Popis |
id | PK | |
user_id | FK → users | |
name | text | Pattern (wildcard) jména nástroje |
effect | enum | allow, deny, prompt |
priority | int | Vyšší = vyhodnoceno dřív |