Architektura platformy
Progresus OSINT je jedna služba s jasnými vnitřními hranicemi: FastAPI jako jediná veřejná hranice, asynchronní worker pro dlouhé běhy, samostatní poskytovatelé dat a PostgreSQL jako jediný zdroj pravdy, z něhož se odvozují vyhledávací a grafové projekce.
Pohled na komponenty
Klienti
statický web + Alpine.js aplikace · API integrace zákazníků
FastAPI služba — veřejná hranice
routery · autentizace API klíči · Pydantic DTO · OpenAPI
ARQ worker
běh šetření: sběr → validace → syntéza
Registr poskytovatelů
cz-ares · cz-isir · cz-justice-or · cz-exekuce · cz-uzk · cz-hlidac-dotace · cz-hlidac-smlouvy · cz-sankce · eu-vies · gleif-lei · sanctions-eu · sanctions-ofac · mock (testy)
rate limit · circuit breaker · retry · cache — per zdroj
zdroj bez přístupových údajů se nikdy nevynechá tiše: katalog ho uvádí jako nenakonfigurovaný a běh ho zaznamená jako přeskočený
Vyhledávání · Graf · Zprávy
tenant filtr odvozený z autentizace, nikdy ze vstupu
Persistence
zdroj pravdy · časové řady
fronta · rate limit · cache
vyhledávací projekce
grafová projekce
Hranice, na kterých systém stojí
Veřejná hranice = FastAPI
Přes API procházejí výhradně veřejné DTO typy. Surová data od poskytovatelů, interní směrování ani vnitřnosti výpočtu důvěryhodnosti službu nikdy neopustí — veřejná a interní obálka jsou oddělené typy, ne flag.
Jeden zdroj pravdy
PostgreSQL je jediná autorita. Meilisearch i Kuzu jsou odvozené projekce, kdykoli přestavitelné z relační databáze. Neexistují dvě autority nad týmž faktem.
Nezávislí poskytovatelé
Poskytovatelé jsou vzájemně nezávislé, bezstavové moduly. Žádná koordinace mezi adaptéry — každý zdroj lze testovat, vypnout nebo vyměnit samostatně.
Životní cyklus šetření
Šetření je stavový automat. Každý přechod zapisuje událost do auditní časové řady, takže průběh každého běhu je zpětně rekonstruovatelný.
- queued
záznam + úloha; idempotenční klíč deduplikuje - collecting
poskytovatelé běží paralelně; ukládají se důkazy, entity, vztahy a zjištění - validating
kontrola integrity důkazů; degradace nepodložených zjištění - synthesizing
grafový snapshot; indexace; podklady zprávy - completed
dotazovatelné; zpráva generovatelná
Z kterékoli fáze může běh přejít do stavu failed; ruční zrušení vede do cancelled.
Model důkazů, zjištění a revizí
Důkaz (evidence) je atomický záznam z jednoho zdroje: kód zdroje, čas pořízení, hash obsahu vypočtený nad normalizovanými daty, důvěryhodnost, právní základ a viditelnost. Důkazy jsou po zápisu neměnné — změna zdrojových dat znamená nový důkaz, ne přepis starého.
Zjištění (finding) je interpretace: kategorie, závažnost, důvěryhodnost, shrnutí a — povinně — odkazy na podkladové důkazy. Vztah zjištění ↔ důkaz je provenanční vazba M:N uložená v databázi a vynucovaná kontrolou integrity, ne konvence.
Viditelnost se vynucuje na úrovni dotazů, ne až v prezentaci: neoprávněný klient skrytý důkaz či zjištění vůbec nedostane — z výpisů, vyhledávání, grafu i zpráv. Sdílený surový záznam se zpřístupní jen tehdy, když na něj klient smí přes všechny navázané důkazy; v pochybnostech systém selhává zavřeně.
Entity a vztahy propojují subjekty nalezené napříč šetřeními přes kanonické klíče; typované vztahy (vlastní, ovládá, jednatel, společník) nesou vlastní důvěryhodnost a časovou platnost.
# veřejná obálka důkazu (EvidencePublic)
{
"id": "0d9f2c66-…",
"source_code": "cz-isir",
"captured_at": "2026-07-27T09:14:21Z",
"content_hash": "sha256:2c26b46b68ffc68f…",
"confidence": 0.9,
"legal_basis": "verejny rejstrik (zakon c. 182/2006 Sb.)",
"visibility": "public"
}
# graf: typy uzlů a hran (Kuzu projekce)
(:Investigation)-[:TARGETS]->(:Entity)
(:Evidence)-[:MENTIONS]->(:Entity)
(:Finding)-[:SUPPORTED_BY]->(:Evidence)
(:Entity)-[:RELATED_TO {type, confidence}]->(:Entity)
Zprávy jako neměnné artefakty
Vygenerovaná zpráva je zmrazený snímek, ne živý pohled: obsah, všechny tři formáty artefaktů (JSON, HTML, Markdown) i odpojený verifikační manifest se ukládají s otisky v jediné transakci. Stažení servíruje uložené bajty — nikdy se nerenderuje znovu, takže zpráva se po vydání nemůže tiše změnit. Pravost artefaktu lze ověřit i mimo běžící službu, jen z manifestu a stažených bajtů.
Lidská revize zjištění
Nad zjištěními běží samostatná, doplňovací osa lidského úsudku: analytik zjištění potvrdí, zamítne, vyžádá další důkazy nebo znovu otevře — v revizní frontě aplikace na /app/review. Každé rozhodnutí se váže k přesnému stavu zjištění přes serverem vypočtený otisk a je po zápisu neměnné; oprava je nové rozhodnutí s povinným důvodem a plnou historií. Když se podklad zjištění změní, dřívější verdikt se automaticky označí jako zastaralý — nikdy se tiše nepřenáší na nový obsah.
Úložiště a plánování úloh
Relační schéma spravují migrace (Alembic) a všechny tenant-scoped tabulky nesou tenant_id. Časové řady — události sběru a historie zjištění — žijí v TimescaleDB hypertabulkách ve stejné databázi, stejným SQL. Právě ony jsou základem pro plánovaný kontinuální monitoring: sledování, jak se subjekt mění v čase.
Frontu úloh obsluhuje ARQ nad Redisem za portem JobQueue — implementace fronty je vyměnitelná bez zásahu do domény. Redis zároveň nese stav rate limiterů a circuit breakerů poskytovatelů a TTL cache výsledků. Distribuované zpracování na více workerech je Plánováno.
Observabilita a nasazení
Strukturované JSON logování s korelačními ID prochází celou pipeline a citlivé hodnoty (API klíče, hesla) jsou v logu automaticky redigovány. GET /health/dependencies souběžně a s časovým limitem ověřuje dostupnost PostgreSQL, Redisu a Meilisearch; GET /metrics vystavuje čítače a histogramy v Prometheus textovém formátu.
Služba se buildí do vícestupňového Docker obrazu bez závislosti na root uživateli, s vestavěným healthcheckem. Kubernetes manifesty (Deployment/Service/PVC pro trvalý svazek Kuzu) a distribuované trasování napříč službami jsou Plánováno; dnes se nasazuje samostatný kontejner.
API vrstva a web
REST API je verzované pod prefixem /v1, popsané OpenAPI specifikací s interaktivní Swagger UI referencí. Chybové odpovědi mají jednotnou problem+json obálku. Výkonové rozpočty (například zdravotní endpoint pod 10 ms) jsou vynucované testy, ne jen deklarované.
Veřejný web je statický HTML + Tailwind CSS s Flowbite komponentami; JavaScript (Alpine.js) se používá jen pro progresivní vylepšení v autentizované aplikaci. Veřejné stránky vykreslují plnohodnotné HTML bez JavaScriptu — kvůli SEO i přístupnosti. Žádný SPA framework, žádný build krok kromě Tailwind CSS.