# ArchitekturaSterowana zdarzeniami, multi-tenant, rozszerzona ML platforma decyzyjna — jak jest zorganizowana.

## Przegląd pipeline'u

```
Stream-Ingest → walidatory feature → persystencja
                                        ↓
                                  Event-Bus (PG LISTEN/NOTIFY)
                                        ↓
                            ┌──────────────────┐
                            │ Decision-Daemon  │ (konfig per tenant)
                            └────────┬─────────┘
                                     ↓
                            zwalidowana akcja
                                     ↓
                            outcome-feedback
                                     ↓
                          trening modelu / tuning
```

Platforma przekształca surowe strumienie danych przez celowo wielostopniowy pipeline w zbieżne decyzje. Każdy stopień ma jedną odpowiedzialność i emituje durable events dla następnego.

## Sterowany zdarzeniami rdzeń

- **Event-Bus.** PostgreSQL `LISTEN/NOTIFY` transportuje eventy między daemonami. Eventy są persystowane w durable tabeli, nie tylko broadcastowane — konsumenci mogą po reconnectcie replayować od cursora.
- **At-least-once-delivery.** Konsumenci potwierdzają przetworzone eventy. Niepotwierdzone eventy są po timeout dostarczane ponownie. Idempotencja jest odpowiedzialnością konsumenta.
- **Cursor-tracked replay.** Każdy konsument trzyma własny cursor. Po fazie disconnect kontynuuje tam, gdzie skończył — żadne eventy nie giną, żadne nie są przetwarzane podwójnie poza skonfigurowane retry-semantyki.

## Pipeline ML

- **Modele.** XGBoost trenowany na historycznych feature'ach, z ONNX Runtime do inferencji (2–5× szybciej niż framework treningowy).
- **Outputy.** Modele klasyfikują reżimy w trzech wymiarach — kierunek, zmienność, jakość. Bez spekulatywnych predykcji punktowych.
- **Tuning hiperparametrów.** Optuna z walk-forward-holdout, falami champion/challenger, bramkami jakości.
- **Pętla feedback.** Outcome każdej decyzji jest logowany i wpuszczany z powrotem do następnej rundy tuningowej.

## Model multi-tenant

Izolacja tenantów jest wymuszana na dwóch poziomach:

- **Stored procedures.** Wszystkie operacje strony tenanta idą przez stored procedures, które wymuszają ownership. Bezpośrednie zapisy do tabel przez kod tenanta nie są dozwolone.
- **Row-level security.** Postgres-RLS jako twardy backstop. Nawet gdy logika aplikacji ma bug, RLS zapobiega cross-tenant data-access.

Konfiguracja per tenant obejmuje:

- **Klucze i rate-limits.**
- **Kill-switch.** Override operatora, aby natychmiastowo zdeaktywować tenant bez redeploy.
- **Profil ryzyka.** Parametry progowe per klasa decyzji.

## Walidatory

Trzy miejsca, w których odbywa się walidacja:

1. **Przed persystencją.** Eventy streamu, które nie przechodzą walidacji, są markowane, nie cicho dropowane. Operatorzy widzą je na dashboardzie.
2. **Przed treningiem modelu.** Feature'y do treningu są ponownie walidowane wobec schematu. Drift triggeruje alert, zanim modele zostaną przetrenowane.
3. **W runtime.** Walidatory feature'ów działają ciągle z auto-recovery `DATAMISSING` — gdy oczekiwany feature brakuje, daemon spada do udokumentowanego defaultu i odpala strukturyzowany event.

## Observability

- **21 live-dashboardów.** Heartbeat, latencja, detekcja driftu, rozkład decyzji, wolumen per tenant.
- **Strukturyzowane logowanie.** Konsola, plik i baza danych — te same eventy logu z wszystkich trzech czytelne tym samym query.
- **Health-monitoring.** Każdy daemon emituje eventy health w stałej kadencji. Brakujące eventy triggerują pages.

## Mechanizmy gotowości produkcyjnej

- **Circuit Breaker** per źródło danych — awarie degradują się gracefully, zamiast kaskadować.
- **Alertowanie e-mail i XMPP** dla eventów istotnych dla operatora.
- **Universal config-driven defaults.** Mapowania źródeł danych, łańcuchy fallback, konwersje jednostek, progi — wszystko w JSON. Bez magic numbers w kodzie.
- **Izolacja procesów** przez tmux + Devuan — daemony mogą być restartowane indywidualnie bez koordynacji.

## Czym to nie jest

- Bez platformy autoscalingu w stylu Kubernetes. To działa na małej liczbie dobrze rozumianych maszyn z celowym rozmieszczeniem daemonów.
- Bez rozwiązania „postawić i zapomnieć". Zestawy tokenów, wersje modeli, konfiguracje tenantów i dashboardy potrzebują uwagi operatora.
- Niegeneryczne. Platforma odzwierciedla konkretną klasę problemów decyzyjnych o wysokiej częstotliwości — adaptacja do bardzo innego workloadu to usługa [Rozwój](/pl/services/development/).
