# k3s runtime map (VPS `qstack`) — co działa i po co Ten dokument opisuje **aktualny runtime na VPS** (k3s) dla projektu `trade`: jakie komponenty działają w klastrze, jak płynie dane oraz które tabele/metrki są “źródłem prawdy” dla UI. Zakładamy namespace: `trade-staging`. ## TL;DR (logika) - **Dane są zbierane i liczone na backendzie** (k3s). - UI (`trade-frontend`) **tylko wizualizuje** i proxy’uje ruch (API + GraphQL + WS). - Hasura to **jedyny GraphQL/WS** na “metrics/live” (subscriptions). - Postgres/Timescale trzyma: - ticki (`drift_ticks`) + candles (funkcja `get_drift_candles`) - “latest” warstw DLOB (`dlob_*_latest`) - (opcjonalnie) historię warstw (`dlob_*_ts`) ## Mapa (ruch z zewnątrz) ``` Internet | v Ingress/Traefik | +--> trade-frontend (https://trade.mpabi.pl) | - /api -> trade-api | - /graphql -> hasura | - /graphql-ws -> hasura (WS subscriptions; protokół graphql-ws) | +--> (opcjonalnie inne ingressy w tym samym klastrze) ``` ### `trade-frontend` (UI + reverse-proxy) - **Rola:** UI + proxy do usług w klastrze. - **Dlaczego:** przeglądarka nie dostaje sekretów; token read jest wstrzykiwany server‑side, a WS działa przez proxy. - **Wejście:** HTTP/WS od użytkownika. - **Wyjście:** - `/api/*` → `trade-api` - `/graphql` (HTTP) → `hasura` - `/graphql-ws` (WS) → `hasura` ## Mapa (dane rynkowe — ticki / candles) ``` Solana RPC/WS (zewn.) | v trade-ingestor | v trade-api -> Postgres/Timescale (drift_ticks) | +--> /v1/chart (candles + wskaźniki liczone na backendzie) | v Hasura (GraphQL query/subscriptions dla wybranych tabel) ``` ### `trade-ingestor` - **Rola:** pobiera dane (oracle/mark) i wysyła ticki do API. - **Wyjście:** ticki zapisane do `drift_ticks` przez `trade-api`. ### `trade-api` - **Rola:** API dla UI i algów (healthz, ticks, chart). - **DB:** zapis do `drift_ticks`. - **Agregacje:** candles (`get_drift_candles`) + wskaźniki (backend). ## Mapa (DLOB — orderbook + metryki warstw) ``` Solana RPC/WS (zewn.) | v dlob-publisher ----> dlob-redis <---- dlob-server (/l2, /l3) \ \ (opcjonalne źródło L2) v dlob-worker (kolektor L2) | v Postgres/Hasura: dlob_l2_latest + dlob_stats_latest | +------------+------------+ | | v v dlob-depth-worker dlob-slippage-worker (bands ±bps) (impact vs size USD) | | v v Postgres/Hasura: dlob_depth_bps_latest Postgres/Hasura: dlob_slippage_latest | v (opcjonalnie) dlob-ts-archiver | v Postgres/Timescale: dlob_stats_ts / dlob_depth_bps_ts / dlob_slippage_ts ``` ### `dlob-publisher` - **Rola:** utrzymuje “żywy” DLOB (on‑chain) i publikuje snapshoty do Redis. - **Wejście:** Solana RPC/WS. - **Wyjście:** publikacja do `dlob-redis`. ### `dlob-redis` - **Rola:** cache/pubsub pomiędzy publisherem i serwerem HTTP. ### `dlob-server` - **Rola:** serwuje REST `/l2` i `/l3` na podstawie cache Redis (do debugowania i/lub jako źródło L2). ### `dlob-worker` (kolektor L2 + “basic stats”) - **Rola:** pobiera snapshoty L2 i liczy podstawowe metryki (`dlob_stats_latest`). - **Źródło L2:** w praktyce: - albo zewnętrzne `https://dlob.drift.trade/l2` - albo wewnętrzne `http://dlob-server:6969/l2` (jeśli tak ustawione) - **Zapis do tabel:** - `dlob_l2_latest` (raw L2) - `dlob_stats_latest` (bid/ask/mid/spread/depth/imbalance) ### `dlob-depth-worker` (depth bands ±bps) - **Rola:** liczy płynność w pasmach ±bps wokół mid. - **Źródło:** `dlob_l2_latest` - **Zapis:** `dlob_depth_bps_latest` (klucz: `market_name + band_bps`) ### `dlob-slippage-worker` (slippage vs size) - **Rola:** symuluje market fill po L2 dla zadanych rozmiarów (USD) i liczy `impact_bps`. - **Źródło:** `dlob_l2_latest` - **Zapis:** `dlob_slippage_latest` (klucz: `market_name + side + size_usd`) ### `dlob-ts-archiver` (historia warstw) - **Rola:** zapisuje “timeline” dla warstw do hypertabli Timescale (historia pod UI). - **Źródło:** `dlob_stats_latest`, `dlob_depth_bps_latest`, `dlob_slippage_latest` - **Zapis:** `dlob_stats_ts`, `dlob_depth_bps_ts`, `dlob_slippage_ts` - **Retencja (startowo):** ~7 dni (policy w Timescale). ## Co UI realnie czyta (dla “nowych funkcji”) - live/subscriptions: - `dlob_stats_latest` - `dlob_depth_bps_latest` - `dlob_slippage_latest` - (jeśli dołączymy w UI wykres “historia”): - `dlob_stats_ts` - `dlob_depth_bps_ts` - `dlob_slippage_ts` ## Najczęstsze miejsca problemów (diagnostyka) - Jeśli UI nie pokazuje warstw: - sprawdź czy Hasura trackuje tabele i ma `public select` (bootstrap job), - sprawdź, czy workery odświeżają `updated_at` w `dlob_*_latest`. - Jeśli `dlob-worker` loguje 503: - to zwykle problem na ścieżce `DLOB_HTTP_URL` (upstream/LB/IPv6) — wtedy przełącz na `http://dlob-server:6969`. - Jeśli WS subscriptions nie łączą: - sprawdź proxy `/graphql-ws` w `trade-frontend` i origin/CORS w Hasurze.