Skip to content

Konfigurace

Veškeré nastavení se ukládá v kolekci app_config. Každý záznam má klíč (key), hodnotu (value) a příznak tajnosti (is_secret).

Registr klíčů

Každý konfigurační klíč je popsán na jednom místě v backendu (internal/config/registry.go): typ (string, int, float, bool, json, html, timezone, enum), výchozí hodnota, příznak tajnosti, skupina, popis, případná doplňková kontrola a to, kterou službu je po změně nutné znovu inicializovat (platby, produkty, MCP, heartbeat, varování před zavřením). Z registru se odvozují:

  • typové čtečky konfigurace (BankNum(), EmailPort(), …) a jejich výchozí hodnoty,
  • seedování výchozích hodnot (SeedDefaults),
  • kontrola hodnot při ukládání,
  • editor v administraci (přes GET /api/v1/admin/contracts → app_config; nikdy se neposílají hodnoty tajných klíčů),
  • seznam klíčů, jejichž změna znovu inicializuje platební službu.

Výchozí hodnoty se nezměnily. Registr přesně zachovává dosavadní chování; hlídá to charakterizační test (internal/config/characterization_test.go), který pevně zná výchozí hodnotu každého klíče (včetně BANK_NUM, BANK_NUM_SHORT, OPERATING_RULES_HTML). Dva klíče mají historicky jinou hodnotu při seedování než „výchozí" čtečky — obojí zůstává:

Klíč Hodnota, když není nastaven (čtečka) Hodnota po seedování nové instalace
BANK_EMAIL_REGEX_PROVIDERS prázdné (žádní vlastní provideři) []
CLOSING_WARNING_CONFIG prázdné (funkce vypnuta) {"enabled":false,"blink_minutes_before":[10,5]}
OPERATING_RULES_HTML prázdné český text provozního řádu

Kontrola hodnot při ukládání

Při vytvoření nebo změně hodnoty registrovaného klíče backend hodnotu zkontroluje (HTTP 400, data.value.message, např. EMAIL_PORT: must be an integer). Pravidla:

  • Prázdná hodnota = nenastaveno a je vždy povolená.
  • Kontrola přijímá přesně to, co čtečky dnes úspěšně přečtou: bool cokoli, co přijme strconv.ParseBool (1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False), int jako strconv.Atoi (např. +25, -1, 007), float jako strconv.ParseFloat, timezone přes time.LoadLocation, enum (poskytovatel plateb; velikost písmen se ignoruje, protože ji tak čte i běh).
  • JSON klíče kontroluje jejich vlastní parser: AI_CHAT_SETTINGS (ai.ParseSettings), BANK_EMAIL_REGEX_PROVIDERS (bankemail.ProvidersFromJSON), CLOSING_WARNING_CONFIG (config.ParseClosingWarning). Za běhu se chování při špatné hodnotě nemění (tiše se použije výchozí) — kontrola se týká jen nových zápisů.
  • Při změně existujícího záznamu se kontroluje jen když se změnila hodnota. Starší záznam s neplatnou hodnotou jde dál upravovat (např. přepnout is_secret) a opravit.
  • Neznámé klíče a provozní stav se nekontrolují.
  • Programové zápisy (seed, aktivace poskytovatele, ukládání AI nastavení, heartbeaty, kurzory, demo zařízení) procházejí stejnou kontrolou; jejich hodnoty jí vyhovují.

Už uložené neplatné hodnoty vypíše GET /api/v1/admin/config/health (kind: "app_config"; hodnoty tajných klíčů se nikdy nevypisují). Zkušební kontrola bez uložení: POST /api/v1/admin/contracts/validate s {"kind":"app_config","target":{"key":"EMAIL_PORT"},"value":"587"}.

Provozní stav (není konfigurace)

Některé řádky v app_config jsou provozní stav zapisovaný systémem, ne nastavení. Editor je zařazuje do sbalené sekce Systém / ostatní a export instalace je vynechává:

Klíč / předpona Zapisuje
HEARTBEAT_DEVICE_<id> kontrola dostupnosti zařízení
PAYMENT_LAST_RUN_TIMESTAMP poslední běh kontroly plateb
BANK_EMAIL_IMAP_CURSOR kurzor UID bankovního e-mailu (IMAP)
DEMO_… (DEMO_LOCK_STATUS_<id>, DEMO_LOCK_OPEN_UNTIL_<id>, …) simulovaná demo zařízení

Editor v administraci

Administrace → Konfigurace zobrazuje klíče po skupinách (Areál a region, Platby a banka, E-mail, Provoz, Dobíjení, Funkce, Zařízení, Uchování dat, Obsah stránek). U každého klíče je název, technický klíč, popis, vstup podle typu (přepínač/výběr pro bool a enum, textové pole pro čísla, text, JSON a HTML), výchozí hodnota s tlačítkem Obnovit výchozí a průběžná kontrola backendem.

  • Tajné hodnoty se nikdy nezobrazují (pole je maskované, vidíte jen „Nastaveno / Nenastaveno"). Prázdné pole hodnotu ponechá, Smazat hodnotu ji vymaže.
  • Změny se ukládají až tlačítkem Uložit změny; při chybě kontroly je uložení zablokováno.
  • Klíče se samostatným postupem jsou jen pro čtení s odkazem na správnou záložku: PAYMENT_CHECK_SERVICE_ENABLED / PAYMENT_CHECK_SERVICE_NAME (Integrace → Aktivovat) a AI_CHAT_SETTINGS (Systém → AI asistent).
  • Sekce Systém / ostatní (sbalená) zachovává původní surový editor (úprava, mazání, přidání, odkrytí tajných) pro provozní stav a vlastní klíče.

Předvolba regionu

Nad klíči je Předvolba regionu (CZ, SK, PL, UA). Vyplní pouze COUNTRY_CODE, CURRENCY_CODE, FACILITY_TIMEZONE a PRICE_DECIMAL_PLACES; hodnoty se jen předvyplní jako neuložené změny ke kontrole. Bankovní ani platební klíče předvolba nikdy nemění.

Region COUNTRY_CODE CURRENCY_CODE FACILITY_TIMEZONE PRICE_DECIMAL_PLACES Jazyk e-mailů
Česko CZ CZK Europe/Prague 0 čeština
Slovensko SK EUR Europe/Bratislava 2 angličtina (slovenský překlad zatím není)
Polsko PL PLN Europe/Warsaw 2 polština
Ukrajina UA UAH Europe/Kyiv 2 ukrajinština

Platební QR kód

Platební QR kód je ve formátu SPAYD (SPD*1.0*ACC:…*CC:…), který čtou české a slovenské bankovní aplikace. Pro PL a UA se předvolba povolit dá (měna se do QR kódu jen přepíše), ale QR kód tamní banky nepřečtou — zákazníkům zobrazte číslo účtu (BANK_NUM_SHORT) a bankovní údaje nastavte ručně.

Priorita konfigurace

  1. Proměnné prostředí (nejvyšší priorita)
  2. Databáze (kolekce app_config)
  3. Výchozí hodnoty (nejnižší priorita)

Proměnné prostředí vždy přebíjejí hodnoty v databázi. To je užitečné pro tajné klíče v produkci.

Konfigurační klíče

Země / Jazyk

Klíč Typ Výchozí Popis
COUNTRY_CODE string "CZ" ISO 3166-1 alpha-2 kód země provozovny

Klíč COUNTRY_CODE je semí pro jazyk notifikací — z něj se automaticky odvodí jazyk e-mailů a frontendu:

COUNTRY_CODE Odvozený jazyk
CZ cs
PL pl
UA ua
cokoli jiného en

Jazyk se předává frontendu přes endpointy /api/v1/public/system-config a /api/v1/me/dashboard, aby si SPA mohla nastavit fallback locale pro i18n.

Nezávislost na měně

COUNTRY_CODE je nezávislý na CURRENCY_CODE — polské zařízení může fakturovat v EUR (CURRENCY_CODE=EUR), ale dostávat polské e-maily (COUNTRY_CODE=PL → pl).

Banka / Platby

Klíč Typ Výchozí Popis
BANK_NUM string "CZ242010000000210221372X" Číslo bankovního účtu (formát IBAN) — pro generování QR kódů a e-maily. Změna ovlivní párování plateb, nastavte vlastní účet
BANK_NUM_SHORT string "210221372X/2010" Krátké číslo účtu zobrazované uživatelům
CURRENCY_CODE string "CZK" Kód měny

Ceny

Klíč Typ Výchozí Popis
PRICE_DECIMAL_PLACES int 0 Počet desetinných míst pro zaokrouhlení cen (0 = celé koruny, půlka od nuly). Rozdíl se ukládá jako zaokrouhlení relace (price_rounding), nikdy jako sleva; kredit se strhává zaokrouhlený dolů na tento počet míst. Při 2 je zaokrouhlení vždy 0

Limity

Klíč Typ Výchozí Popis
MAX_DEBT int 0 Maximální povolený dluh (Kč). 0 = bez limitu. Uživatelé s vyšším dluhem nemohou zahájit relaci
MIN_CREDIT_BALANCE float 0 Minimální potřebný kredit pro vstup do entry-based zóny

Hardware / Terminál

Klíč Typ Výchozí Popis
TERMINAL_ENABLED bool false Povolení terminálového hardwaru (zobrazení user_code/user_pin a API terminálu)
AUTH_HEADER string "" Tajný — autentizační hlavička pro API terminálu

Email

Klíč Typ Výchozí Popis
EMAIL_SENDING_ENABLED bool false Povolení e-mailových notifikací
EMAIL_APP_NAME string "" Název aplikace v emailech
EMAIL_HOST_USER string "" SMTP uživatelské jméno
EMAIL_HOST_PASSWORD string "" Tajný — SMTP heslo
EMAIL_HOST string "smtp.seznam.cz" SMTP server
EMAIL_PORT int 587 SMTP port
PLATBY_EMAIL string "" E-mail pro platební notifikace
PLATBY_EMAIL_PASSWORD string "" Tajný — heslo pro platební e-mail
EMAIL_LOGS_RETENTION_DAYS int 365 Počet dní, po které se uchovávají záznamy o e-mailech (denně mazány cronem)

Platební služba

Klíč Typ Výchozí Popis
PAYMENT_CHECK_SERVICE_ENABLED bool false Povolení automatické kontroly plateb přes bankovní API
PAYMENT_CHECK_SERVICE_NAME enum "" Název aktivního poskytovatele: "fio", "erste" nebo "email". Nastavuje se tlačítkem Aktivovat v záložce Integrace (viz Bankovní integrace)
FIO_URL string "" Bázová URL FIO Bank API
FIO_TOKEN string "" Tajný — API token FIO Bank

Erste banka

Klíč Typ Výchozí Popis
ERSTE_API_KEY string "" Tajný — WEB-API-key z Erste Developer Portal
ERSTE_CLIENT_ID string "" Tajný — OAuth2 Client ID
ERSTE_CLIENT_SECRET string "" Tajný — OAuth2 Client Secret
ERSTE_IDP_URL string sandbox URL URL identitního poskytovatele (IDP)
ERSTE_API_URL string sandbox URL URL Accounts API

Provoz zařízení

Klíč Typ Výchozí Popis
AUTO_ACCEPT bool false Automatické schválení nových registrací uživatelů
FACILITY_TIMEZONE string "Europe/Prague" Časová zóna zařízení

Provozní hodiny zón se nastavují pomocí time_from a time_to v zone_pricing_rules. Mimo tyto hodiny nelze spustit novou relaci a aktivní relace jsou automaticky ukončeny po uplynutí doby od konce provozní doby (viz AUTO_CLOSE_GRACE_MINUTES dole).

Automatické ukončení relací

Klíč Typ Výchozí Popis
AUTO_CLOSE_ENABLED bool true Hlavní přepínač automatického ukončování relací mimo provozní dobu. true = relace se ukončí po době odkladu (viz AUTO_CLOSE_GRACE_MINUTES). false = aktivní relace může běžet neomezeně i mimo provozní dobu; ukončení je na uživateli.
LIGHTS_OFF_AFTER_CLOSE bool false Nezávislý donucovací signál: po konci provozní doby se okamžitě (bez odkladu) jednou vypnou světla — bez ohledu na to, zda je zapnutý auto-close. Při zapnutém auto-close se navíc relace i tak ukončí v AUTO_CLOSE_GRACE_MINUTES (světla tak při ukončení zhasnou znovu — neškodné, idempotentní). Při vypnutém auto-close relace zůstává aktivní a zámky zůstávají otevřené.
AUTO_CLOSE_GRACE_MINUTES int 10 Počet minut po konci provozní doby, po které zůstane aktivní relace otevřená, než je automaticky ukončena. Hodnota 0 ukončí relaci okamžitě v okamžiku konce provozní doby (bez odkladu).

Poznámka k přejmenování: dřívější klíč AUTO_CLOSE_LIGHTS_OFF_AFTER_CLOSE byl přejmenován na LIGHTS_OFF_AFTER_CLOSE, aby byl nezávislý na auto-close. Seed starý klíč automaticky odstraňuje.

AUTO_CLOSE_ENABLED a LIGHTS_OFF_AFTER_CLOSE jsou dva nezávislé přepínače — kombinace určuje chování po zavírací době:

AUTO_CLOSE_ENABLED LIGHTS_OFF_AFTER_CLOSE Chování po zavírací době
true false Auto-close ukončí relaci po odkladu (AUTO_CLOSE_GRACE_MINUTES) → zhasnou světla a zamknou se zámky.
true true Světla se zhasnou hned v okamžiku konce provozní doby (nezávisle) a relace se i tak ukončí po odkladu (světla zhasnou znovu).
false false Relace běží dál neomezeně; světla zůstávají tak, jak je uživatel nechá. Jediným varováním je blikání (CLOSING_WARNING_CONFIG).
false true Světla se zhasnou hned po konci provozní doby jako signál k odchodu, ale relace běží dál neomezeně a zámky zůstávají otevřené.

Varování

V režimu s vypnutým auto-close (AUTO_CLOSE_ENABLED=false) může uživatel zapomenout relaci ukončit a hřiště může zůstat otevřené i několik dní (zámek zůstává otevřený, dokud relace běží). Je to vědomá volba provozovatele. Při zapnutém LIGHTS_OFF_AFTER_CLOSE se alespoň zhasne, ale zámek zůstane otevřený.

Ve všech režimech platí: - Nový vstup je stále blokovaný — mimo provozní hodiny nelze spustit novou relaci (OperatingHoursCheckValidator), takže noví lidé se dovnitř nedostanou. - Uživatel s aktivní relací si ponechává ovládání zařízení (světla, zámky dveří atd.), protože ovládání zařízení kontroluje jen, že relace je aktivní, ne provozní hodiny. - Účtování pokračuje poslední známou sazbou, protože cena se počítá při ukončení relace (delší relace = vyšší poplatek). - Varovné blikání (CLOSING_WARNING_CONFIG) funguje ve všech režimech. - Admin a uživatelé s maintenance produktem auto-close bypassují vždy. - Zhasnutí světel (LIGHTS_OFF_AFTER_CLOSE) se provede jednou za den a zónu, hned v okamžiku konce provozní doby (bez čekání na odklad).

Výstraha před zavírací dobou

Klíč Typ Výchozí Popis
CLOSING_WARNING_CONFIG JSON {"enabled":false,"blink_minutes_before":[10,5]} Dynamická výstraha před zavírací dobou — blikne světla jako varování

JSON struktura:

{
  "enabled": true,
  "blink_minutes_before": [10, 5]
}
  • enabled — zapne/vypne celý systém varování
  • blink_minutes_before — pole minut před koncem provozní doby, kdy se blikne světly (sestupně). Cron běží každou minutu a pro každou zónu s aktivními relacemi kontroluje, zda se blíží zavírací doba.

Příklad: {"enabled":true,"blink_minutes_before":[10,5]} — blikne 10 a 5 minut před koncem.

Chování

  • Blikne pouze sekundární zařízení typu light (světla)
  • Každé bliknutí se zapíše do action logu jako triggered_by: "cron"
  • Po zavírací době normálně pokračuje auto-close (ukončení relací + zamknutí)

Produkty

Klíč Typ Výchozí Popis
PRODUCTS_ENABLED bool false Povolení systému produktů (permanentky, balíčky, slevy)

Dobíjení kreditu

Klíč Typ Výchozí Popis
TOPUP_ENABLED bool false Povolení dobíjení kreditu
TOPUP_MIN_AMOUNT float 50 Minimální částka dobíjení (Kč)
TOPUP_MAX_AMOUNT float 10000 Maximální částka dobíjení (Kč)
TOPUP_EXPIRATION_DAYS int 30 Počet dnů do expirace čekajícího dobíjení

AI asistent (chatbot)

AI asistent se konfiguruje jediným klíčem AI_CHAT_SETTINGS (JSON, tajný klíč). Umožňuje definovat seřazený seznam poskytovatelů LLM — při dotazu se zkoušejí postupně a první, který odpoví, vyhraje (fallback). API klíče se ukládají na serveru a nikdy se neposílají do prohlížeče (admin přes API vidí jen has_key).

Odpovědi asistenta jsou založené výhradně na nástrojích MCP (vyhledávání v dokumentaci, zóny, rezervace atd.). Bez dostupných nástrojů (MCP vypnutý) chat selže s chybou — žádný fallback bez nástrojů neexistuje.

Přednost: hodnota z prostředí AI_CHAT_SETTINGS má přednost před hodnotou v databázi. Hodnota se čte čerstvě z databáze při každém dotazu, změny se projeví okamžitě.

Klíč Typ Výchozí Popis
AI_CHAT_SETTINGS JSON "" Nastavení AI asistenta (schéma níže)

Schéma AI_CHAT_SETTINGS:

{
  "enabled": true,
  "max_tool_rounds": 10,
  "system_prompt": "",
  "providers": [
    {
      "id": "openrouter-1",
      "order": 1,
      "label": "OpenRouter",
      "provider": "openrouter",
      "base_url": "https://openrouter.ai/api/v1/chat/completions",
      "models_url": "https://openrouter.ai/api/v1/models",
      "model": "openrouter/free",
      "api_key": "sk-or-v1-..."
    },
    {
      "id": "opencode-1",
      "order": 2,
      "label": "OpenCode",
      "provider": "opencode",
      "base_url": "https://opencode.ai/zen/v1/chat/completions",
      "model": "big-pickle",
      "api_key": ""
    }
  ]
}
  • enabled — zapnutí/vypnutí AI asistenta.
  • max_tool_rounds — maximální počet kol volání nástrojů na jeden dotaz. 0 = bez limitu.
  • system_prompt — volitelná systémová výzva (osobnost + pravidla asistenta). Prázdné = vestavěný default. Změna se projeví okamžitě u nových konverzací; admin API vrací výchozí text jako default_system_prompt.
  • providers — seznam poskytovatelů, seřazený podle order (řazení vždy vzestupně podle order, nezávisle na pořadí v poli).
  • Podporované typy poskytovatelů (provider):
  • openrouter — vyžaduje api_key.
  • opencode — anonymní režim (klíč se nevyplňuje), ověřuje se public tokenem.
  • ollama — lokální Ollama (default base_url = http://localhost:11434/v1/chat/completions, modely z …/api/tags).
  • custom — libovolný OpenAI-kompatibilní endpoint.
  • base_url — OpenAI-kompatibilní chat completions URL (povinné u každého poskytovatele).
  • models_url — volitelná URL pro seznam modelů; když chybí, odvodí se z base_url (pro openrouter/opencode z ${base bez /chat/completions}/models, pro ollama /api/tags).
  • api_key — API klíč; prázdný / __keep__ při uložení přes admin API zachová uložený klíč. U openrouter je povinný, u opencode se ignoruje.

Retence / cleanup

Klíč Typ Výchozí Popis
ACTION_LOGS_RETENTION_DAYS int 90 Počet dnů uchovávání action logů. Starší záznamy se denně mažou v 02:00. 0 = cleanup vypnut

Obsah

Klíč Typ Výchozí Popis
CONTACTS_HTML string "" HTML obsah kontaktní stránky
OPERATING_RULES_HTML string "" HTML obsah provozního řádu

Tajné klíče

Následující klíče jsou označeny jako is_secret = true a měly by být chráněny:

  • AUTH_HEADER
  • EMAIL_HOST_PASSWORD
  • PLATBY_EMAIL_PASSWORD
  • FIO_TOKEN
  • ERSTE_API_KEY
  • ERSTE_CLIENT_ID
  • ERSTE_CLIENT_SECRET
  • AI_CHAT_SETTINGS (obsahuje API klíče poskytovatelů — server je maluje jako has_key)

Doporučení

Tajné klíče nastavujte především pomocí proměnných prostředí, ne přes databázi. Proměnné prostředí nejsou uloženy v SQLite databázi a nelze je získat přes PocketBase API.

Nastavení přes prostředí

export MAX_DEBT=500
export TERMINAL_ENABLED=true
export FIO_TOKEN=váš_tajný_token

Nastavení přes databázi

V PocketBase administraci (/_/) v kolekci app_config vytvořte nebo upravte záznam:

key value is_secret
MAX_DEBT 500 false

Datové typy

  • Boolean hodnoty přijímají: true, false, 1, 0, yes, no (bez ohledu na velikost písmen)
  • Číselné hodnoty se validují a při chybě parsování se použije výchozí hodnota
  • Prázdné řetězce vrací výchozí hodnotu
  • Nové klíče lze přidávat za běhu bez změny kódu (přístup přes config.Get())

Seedování výchozích hodnot

Při prvním spuštění aplikace se do app_config automaticky vloží výchozí hodnoty všech klíčů. Seedování:

  • Vkládá pouze klíče, které ještě neexistují
  • Nastavuje odpovídající výchozí hodnoty
  • Označuje citlivé klíče jako tajné