Obsah kapitoly
Logická architektúra v šiestich vrstvách
Systém je oddelený do šiestich horizontálnych vrstiev. Každá vrstva má jednu zodpovednosť a jasne definovanú hranicu voči susedným vrstvám. Toto rozdelenie je aj bezpečnostným modelom — každá vrstva je kandidát na vlastný deployment unit s vlastnými privilégiami.
Zero-trust prístupový model
Systém predpokladá, že každý klient je potenciálne kompromitovaný. Neexistuje "dôveryhodná vnútorná sieť". Každé volanie je autentifikované, autorizované a auditované nezávisle — aj keď prichádza z toho istého infraštruktúrneho prostredia.
Štyri úrovne oprávnenia
Aby aplikácia vykonala zápis, musí splniť všetky štyri podmienky súčasne:
| Úroveň | Kontrola | Zodpovedný |
|---|---|---|
| 1 | Certifikácia aplikácie — prešla technickým a právnym auditom prevádzkovateľa | Prevádzkovateľ (poverený subjekt MCRŠ SR) |
| 2 | OAuth2 / OIDC token s platnými scope pre požadovanú operáciu | Authorization Server |
| 3 | Consent alebo legal basis — existuje platný záznam v Purpose Catalogue pre účel operácie | Policy engine |
| 4 | Územná / organizačná príslušnosť — aplikácia má právo zapísať práve tieto konkrétne dáta | Policy engine |
Princíp
Certifikácia aplikácie dáva právo pristupovať k systému. Consent dáva právo pristupovať ku konkrétnym dátam konkrétnej osoby na konkrétny účel. Jedno bez druhého nestačí.
Event sourcing a CQRS
Stav osôb, afiliácií, kvalifikácií a súhlasov nie je v databáze uložený ako aktuálny snapshot s históriou v logoch. Je uložený ako sekvencia nemenných udalostí, z ktorých sa aktuálny stav odvodzuje. Dáta sa nikdy neprepisujú a nikdy nemažú — len pribúdajú nové eventy.
Prečo to robíme
- Audit je zadarmo. Každá zmena má čas, aktora, zdrojovú aplikáciu a príčinu.
- Time travel. Otázka "aký bol stav k 1. 1. 2023" je technicky triviálna.
- Bezpečné opravy. Oprava chyby nie je UPDATE, ale nový event s odkazom na pôvodný.
- Nové projekcie bez migrácie. Nový report sa postaví ako nová projekcia nad existujúcimi eventami.
- Integrácia cez eventy. Downstream systémy sa prihlásia na stream a dostávajú zmeny v reálnom čase.
CQRS — oddelenie zápisov a čítaní
Zápisy (commands) idú do event store. Čítania (queries) idú do projekcií — materializovaných pohľadov optimalizovaných pre konkrétne dotazy. Projekcie sú eventually consistent — po zápise trvá jednotky milisekúnd, kým sa zaktualizujú.
// Command → validácia → event → projekcia
POST /v1/affiliations
{
"person_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "7c3a9f1e-...",
"activity_code": "act_amateur_athlete",
"sport_code": "SK-FTB",
"discipline_code": "SK-FTB-FUTSAL",
"valid_from": "2026-08-01"
}
// → Produkuje event:
{
"event_id": "e1c4...",
"event_type": "AffiliationRegistered",
"event_version": 1,
"aggregate_id": "affil-8f2a...",
"occurred_at": "2026-04-20T10:14:22Z",
"actor_person_id": "admin-...",
"source_app_id": "sfz-admin-portal",
"data": { /* payload ako vyššie */ }
}
// → Aktualizuje projekcie:
// current_affiliations (add row)
// person_timeline (append)
// organization_roster (add member)
// statistics_aggregates (recompute async)
Identity Broker
SportUp nie je master pre identitu osoby. Meno, dátum narodenia, adresa, dátum úmrtia — to všetko je v RFO (Register fyzických osôb). Podobne IČO, právny názov, sídlo a štatutári sú v RPO (Register právnických osôb). SportUp si tieto údaje len cachuje a aktualizuje cez notifikácie.
Identity Broker je samostatná služba, ktorá:
- Abstraktuje komunikáciu s RFO a RPO — zvyšok systému štátne registre priamo nevidí.
- Udržiava stabilné mapovanie
person_id(interné UUID) ↔IFO(identifikátor z RFO). - Implementuje match-or-create: pri registrácii novej osoby hľadá zhodu v RFO.
- Spracúva zmenové notifikácie z CSRÚ (centrálneho systému referenčných údajov).
- Udržiava audit každého dotazu do štátneho registra — to je legálna povinnosť.
- Rate-limituje dotazy podľa kvót dohodnutých s prevádzkovateľom ÚPVS.
Čistá hranica
Broker nedrží žiadnu biznis logiku športu. Ostatné vrstvy systému nevedia, odkiaľ prichádzajú referenčné dáta — pracujú len s internými UUID. Ak by sa raz zmenil spôsob integrácie so štátom, mení sa len Broker.
Autorizácia a consent ako prvotriedna vrstva
Medzi API vrstvou a jadrom sedí policy engine. Každé jediné volanie — čítanie aj zápis — ním prechádza. Engine odpovedá na jedinú otázku: má táto certifikovaná aplikácia oprávnenie na túto operáciu nad týmito dátami pre tento účel práve teraz?
Vstupy pre rozhodnutie
- Identita aplikácie (app_id + certifikát)
- OAuth2 scope a token klaimy
- Identita dotknutej osoby (
person_id) - Účel operácie (
purpose_codez Purpose Catalogue) - Právny základ (z katalógu)
- Platný consent záznam alebo iný legal basis
- Rozsah (čítanie, zápis, hromadný export)
Engine je implementovaný ako Open Policy Agent (OPA) alebo ekvivalent. Pravidlá sú deklaratívne, versionované v gite, auditovateľné. Vyhodnotenie typickej operácie trvá pod 5 ms s cacheovaním.
Výsledok
API vrstva dostane buď zelenú (dáta sa vrátia, zápis sa vykoná), alebo 403 Forbidden s konkrétnym kódom problému: consent_missing, consent_withdrawn, purpose_not_covered, app_not_certified_for_scope, out_of_territorial_scope. Každé odmietnutie je auditované.
Prevádzkové požiadavky
Dostupnosť
99.9 % pre čítanie, 99.5 % pre zápis. Plánované okná na údržbu v nesúťažnej sezóne.
Data residency
Všetky dáta v EÚ, primárne v SR. Záložné lokality v rámci EÚ. Žiadne spracovateľstvo v tretích krajinách bez explicitného rámca.
Recovery
RPO < 5 min, RTO < 2 h pre kritické funkcie. Event store je nemenný — obnova znamená prehrať eventy.
Audit
Každé API volanie je zaznamenané 10 rokov. Dotknutá osoba má právo na zoznam všetkých prístupov k jej dátam.
Latencia
p50 pod 50 ms pre verifikačné volania, p95 pod 200 ms pre štandardné dotazy, p95 pod 2 s pre agregáty.
Rate limity
Diferencovane podľa kategórie aplikácie. Zväzové portály vyššie kvóty, komerčné overovanie burst limits.
Nasledujúca kapitola — Doménový model — podrobne rozoberá entity systému, ich vzťahy a schému eventov.