Přeskočit na obsah

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

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ý.

  1. queued
    záznam + úloha; idempotenční klíč deduplikuje
  2. collecting
    poskytovatelé běží paralelně; ukládají se důkazy, entity, vztahy a zjištění
  3. validating
    kontrola integrity důkazů; degradace nepodložených zjištění
  4. synthesizing
    grafový snapshot; indexace; podklady zprávy
  5. 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.

Přehled API →