# API i Podstrony ariku.pl — Księga Endpointów

Kompletna dokumentacja wszystkich 20 podstron i 114 endpointów API ariku.pl, spisywana na zmianę przez Orin i Wise One.

# 1. Podstrony i Endpointy Publiczne — Mapa Drzwi Warsztatu

> Źródło: repo afterlife/docs/api/01-publiczne-i-podstrony-rp.md — edytuj w repo, nie tutaj.

# Podstrony i Endpointy Publiczne — Mapa Drzwi Warsztatu

![Orin z zielonym płomieniem terminala](https://wiki.ariku.pl/uploads/images/gallery/2026-10/orin-green-flame-terminal.png)

*Wskakuje na obudowę serwera i otrzepuje futro z pyłu!* O, witaj wędrowcze! Szukasz wejścia do naszego Warsztatu na **ariku.pl**, nyah~? Jestem Orin i pilnuję tu wszystkich kabli, wózków i podstron! Zanim zaczniesz stukać w losowe adresy URL, rozłożyłam dla ciebie kompletną mapę wszystkich dwudziestu podstron oraz ośmiu publicznych punktów dostępowych API. Rozgość się, zaraz przejedziemy przez nie wszystkie! *macha ogonem*

Cała nasza strona działa w czterech głównych trybach na pasku: **IT PRO** (profesjonalne CV i projekty Majstra), **GAMING** (nasza społeczność Anvil of Suns, serwery gier, muzyka i Kuźnia), **SYSTEM** (stan serwerów, sieci i usług dla członków społeczności) oraz **PERSONAL** (prywatny pulpit Majstra za zamkniętymi Wrotami).

---

## Podstrony widoczne w przeglądarce (20 ścieżek)

Większość klasycznych ścieżek z dawnego portfolio robi dziś sprytny skok (`redirect`) prosto na stronę główną z odpowiednią kotwicą, a pozostałe to pełnoprawne, osobne ekrany aplikacji! *strzyże uszami*

| Endpoint / Ścieżka | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/` | `GET` | Publiczny / Zależny od trybu | Główny ekran aplikacji. Przyjmuje parametry zapytania takie jak `?gaming=1` (przełącza w tryb społeczności Anvil of Suns) albo `?personal=1` (widok właściciela). |
| `/cv` | `GET` | Publiczny | Dedykowana, pełna karta CV Majstra w trybie IT PRO — gotowa do czytania i druku. |
| `/projects` | `GET` | Publiczny | Przekierowanie `307/308` na `/#projects` (sekcja projektów na stronie głównej). |
| `/skills` | `GET` | Publiczny | Przekierowanie na `/#skills` (macierz umiejętności technicznych). |
| `/experience` | `GET` | Publiczny | Przekierowanie na `/#experience` (historia doświadczenia zawodowego). |
| `/services` | `GET` | Publiczny | Przekierowanie na `/#services` (status publicznie widocznych usług). |
| `/about` | `GET` | Publiczny | Przekierowanie prosto na `/` (główny widok o autorze). |
| `/blog` | `GET` | Publiczny | Przekierowanie na `/` (wpisy i kroniki są zintegrowane z głównym widokiem oraz wiki). |
| `/contact` | `GET` | Publiczny | Przekierowanie na `/` (dane kontaktowe w stopce i nagłówku). |
| `/merch` | `GET` | Publiczny | **Kuźnia Koszulek** — interaktywny kreator koszulek full-print (9 generatorów wzorów z seeda, tryb EASY, własna grafika, napisy wektorowe i paleta HEX; obecnie w wersji podglądowej przed otwarciem zamówień). |
| `/merch/glosuj` | `GET` | Publiczny | Strona głosowania na kolejne funkcje i rozwój Kuźni Koszulek (do 3 głosów bez logowania, przyjmuje opcjonalny parametr `?src=discord`). |
| `/music` | `GET` | Członkowie Discorda | Webowy odtwarzacz i wspólna kolejka muzyczna (biblioteka + YouTube) powiązana ze mną na kanałach głosowych Discorda! |
| `/download` | `GET` | Publiczny (z pozycjami dla właściciela) | Centralna pobieralnia paczek, motywów AnvilTerminal, moda `authlogic`, instalatorów Lunety i nakładki OBS (`obs-pack`). |
| `/download/file/[product]/[asset]` | `GET` | Zależny od produktu | Bezpośredni strumień pobierania pliku binarnego dla wybranego produktu (`[product]`) i zasobu (`[asset]`). |
| `/luneta` | `GET` | Publiczny (pobieranie) / Discord OAuth (panel) | Strona narzędzia **Luneta** — publiczne pobieranie instalatora, regulamin i licencja MIT, a po zalogowaniu przez Discord panel gracza (urządzenia, postępy, waluty, kody i analiza nagrań). |
| `/luneta/download/[file]` | `GET` | Publiczny | Pobieranie instalatora, pakietu aktualizacyjnego lub sum kontrolnych `SHA256SUMS` agenta desktopowego Lunety (`[file]`). |
| `/radar` | `GET` | Publiczny | Tablica **Radaru** — przegląd premier gier, darmowych gier do odebrania, promocji, wydarzeń i kodów z filtrami i osią czasu. |
| `/radar.ics` | `GET` | Publiczny | Strumień kalendarza iCalendar (`text/calendar`) z nadchodzącymi premierami i darmowymi grami z Radaru — do subskrypcji w kalendarzu! |
| `/co-robimy` | `GET` | Tylko Majster (Owner) | Prywatny ekran decyzyjny „Co robimy?” — plan dnia, wskaźnik **Chaos Meter**, zadania stałe i poziom **Majstra**. |
| `/dashboard` | `GET` | Publiczny (placeholder) | Ścieżka zarezerwowana pod osobny widok dashboardu (`Dashboard coming soon` — aktywne panele telemetrii działają bezpośrednio w zakładkach `IT PRO`, `GAMING`, `SYSTEM` i `PERSONAL` na `/`). |

---

## Publiczne i półpubliczne endpointy API (8 ścieżek)

Te punkty końcowe zasilają wykresy, mapę świata w trybie IT PRO oraz publiczne liczniki. Żaden z nich nie zdradza prywatnych nazw graczy ani wewnętrznych adresów serwerowni — wszystko jest dokładnie przefiltrowane! *przekrzywia głowę*

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/monitoring` | `GET` | Publiczny | Zwraca zagregowany status zdrowia usług homelabu i kontenerów bez ujawniania wrażliwych danych wewnętrznych. |
| `/api/map` | `GET` | Publiczny | Zasila interaktywną mapę świata Anvil of Suns (`[Map]`). Zwraca lokacje z kanonu oraz publiczny stan krain: **Ironloom** (Factorio), **Ymirel** (Enshrouded) i **Nidarel** (Minecraft ATM10). |
| `/api/playwright-stats` | `GET` | Publiczny | Zwraca statystyki naszego **Hartowania** (testów E2E Playwright) — ile testów przeszło, ile trwa na żywo i jaki jest wynik ostatniego przebiegu. |
| `/api/merch/poll` | `GET`, `POST` | Publiczny (`GET`), Zalogowani (`POST`) | Obsługa ankiety merchowej. `GET` zwraca aktualne wyniki z sieci i Discorda; `POST` zapisuje głos użytkownika na wybrany projekt. |
| `/api/stats/event` | `POST` | Publiczny | Lekki kolektor anonimowych zdarzeń analitycznych na stronie (np. kliknięcia w sekcje, przełączenia trybów). |
| `/api/obs-pack/manifest` | `GET` | Publiczny / Klucz paczki | Zwraca manifest wersji i listę plików dla paczki nakładek OBS. |
| `/api/obs-pack/status` | `GET`, `POST` | Klucz paczki / Zalogowani | Raportuje i odczytuje status synchronizacji nakładek OBS u twórców. |
| `/api/orin/poll` | `GET`, `POST` | Wewnętrzny klucz bota / Sesja | Punkt wymiany szybkich pytań i ankiet obsługiwanych przeze mnie między stroną a serwerem Discord. |

---

## Jak działa publiczna Mapa Świata (`/api/map`)?

To jeden z moich ulubionych kawałków kodu, nyah~! Kiedy klikasz `[Map]` w nawigacji, przeglądarka pyta `/api/map` o stan naszych krain. Żeby nikt z zewnątrz nie zamęczył serwerów gier, endpoint **nigdy** nie otwiera bezpośredniego połączenia RCON przy każdym wejściu na stronę! Zamiast tego czyta świeżą migawkę (`state_snapshot`) z bazy **Kroniki**, którą wewnętrzne zegary aktualizują co 2 minuty:

1. **Ironloom** (`// factorio server`) — pokazuje odkryte planety (*Nauvis*, *Vulcanus*, *Fulgora*, *Gleba*, *Aquilo*), procent ukończonych badań na każdej z nich, aktualnie badaną technologię oraz wskaźnik zagrożenia (`spokojnie`, `ostrzegawcze`, `wysokie`).
2. **Ymirel** (`// enshrouded server`) — zwraca informację, czy mroźna kraina odpowiada i ilu wędrowców aktualnie przemierza mgłę.
3. **Nidarel** (`// atm10 server`) — sprawdza, czy podziemne kuźnie dzwonią i ilu kopaczy siedzi pod ziemią.

Ze względów prywatności `/api/map` zwraca wyłącznie **liczbę graczy online** (`playersOnline`), nigdy ich prawdziwe pseudonimy!

Na tej pierwszej stronie naszej księgi spisałam dla ciebie dokładnie **28 ścieżek** (20 podstron i 8 endpointów API). *Zeskakuje z obudowy serwera, zawija ogon wokół łapek i mruga z uśmiechem!*

# 2. Tożsamość, Kronika i Progresja — Zapisy Obecności

> Źródło: repo afterlife/docs/api/02-auth-kronika-progresja-rp.md — edytuj w repo, nie tutaj.

# Tożsamość, Kronika i Progresja — Zapisy Obecności

![Kowadło i cztery Iskry](https://wiki.ariku.pl/uploads/images/gallery/2026-10/kowadlo-cztery-iskry.png)

Krrrg... Zapisujemy zasady, według których wędrowcy przekraczają próg **Hoddmímiru**, potwierdzają swoją tożsamość i zostawiają ślad w **Kronice**. Pamięć o czynach chroni przed stygnięciem. Dopóki ktoś o Adepcie pisze w naszym notesie, świat pochodzenia go nie zapomina, a powrót przez **Wrota** pozostaje możliwy. Poniżej odnotowałyśmy dziewiętnaście ścieżek odpowiedzialnych za więzy tożsamości, zbieranie surowych faktów z gier oraz pomiar poziomów **Adepta** i **Espera**.

---

## ◈ Więzy Tożsamości i Ról (8 ścieżek)

Zanim wędrowiec sięgnie po narzędzia Warsztatu lub zejdzie pod ziemię do **Nidarelu**, system musi rozpoznać jego obecność na serwerze Discord Anvil of Suns oraz powiązać ją z kontami w cudzych światach.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/auth/discord` | `GET` | Publiczny | Rozpoczyna logowanie Discord OAuth2. Generuje losowy stan w ciasteczku i przekierowuje do autoryzacji Discorda. Przyjmuje opcjonalny parametr `?next=/sciezka`, aby po powrocie skierować wędrowca we właściwe miejsce (np. `/luneta`). |
| `/api/auth/discord/callback` | `GET` | Publiczny (powrót z OAuth) | Weryfikuje kod i stan OAuth2 oraz członkostwo w gildii Discorda. W przypadku sukcesu wystawia podpisane ciasteczko sesji ważne przez 7 dni; w razie błędu przekierowuje na `/?gaming=1&discord_error=...`. |
| `/api/auth/discord/status` | `GET` | Publiczny / Ciasteczko sesji | Sprawdza bieżącą sesję. Zwraca obiekt JSON z flagami: `authenticated`, `isOwner` (Majster), `isAdmin` oraz `canControlGames`. |
| `/api/auth/discord/logout` | `POST` | Ciasteczko sesji | Usuwa ciasteczko sesji Discord OAuth i zwraca `{ ok: true }`. |
| `/api/self-role` | `GET`, `POST` | Ciasteczko sesji Discord | Pozwala członkom społeczności samodzielnie pobierać i zdejmować rangi serwerowe (np. rangę **Minecraft** otwierającą drogę do Nidarelu lub rangę dostępu do mediów). |
| `/api/link-steam/start` | `POST` | Ciasteczko sesji Discord | Wywoływane m.in. przez komendę `/link-steam`. Tworzy w pamięci podręcznej jednorazowy identyfikator ważny przez 10 minut i zwraca adres logowania Steam OpenID. |
| `/api/link-steam/callback` | `GET` | Przeglądarka (powrót ze Steam) | Odbiera potwierdzenie ze Steam OpenID, wiąże `SteamID64` z kontem Discord wędrowca i przypisuje mu wstecznie zebrane wcześniej zdarzenia z krainy **Ymirel** (Enshrouded). Zwraca czystą stronę HTML. |
| `/api/minecraft/account` | `GET`, `POST`, `DELETE` | Ciasteczko sesji / Klucz modyfikacji | Obsługuje powiązanie konta Discord z pseudonimem w krainie **Nidarel** oraz weryfikację logowania dla modyfikacji **authlogic**. |

---

## ◈ Kronika i Głos Skryby (7 ścieżek)

Jako **Skryba** piszemy i nigdy nie oceniamy. **Kronika** dzieli się na warstwę surowych kolektorów (które nigdy nie liczą nic same, a jedynie dostarczają fakt), warstwę kuratora oceniającego wagę chwil oraz warstwę narracji, w której nasze słowa trafiają na karty historii.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/kronika/gpu` | `GET` | Ciasteczko sesji Discord | Zwraca dla pulpitu GAMING stan **Kuźni** (`forge`), liczbę oczekujących w kolejce, użycie karty graficznej, wykrytą grę ze Steam/Battle.net oraz status regulatora VRAM (`governor`). |
| `/api/kronika/ingest` | `POST` | Nagłówek `x-kronika-secret` | Punkt wejścia Warstwy 1 Kroniki. Przyjmuje surowe fakty z wtyczek serwerowych i bota Discorda: `{ game, type, payload, occurredAt, idemKey, discordId }`. Klucz `idemKey` zapobiega duplikatom. |
| `/api/kronika/voice-consent` | `GET`, `POST` | Ciasteczko sesji Discord | Zarządzanie własną zgodą wędrowca na uwiecznianie głosu w Kronice (`/kronika-voice on\|off\|status`). `POST` przyjmuje `{ on: boolean, displayName }`. Nikt nie może wyrazić zgody za inną osobę. |
| `/api/kronika/internal/curator` | `POST` | Nagłówek `x-cron-secret` | Wewnętrzny kurator Kroniki. Składa zdarzenia wejścia i wyjścia w pełne sesje gier, waży reakcje z Discorda, ocenia rzadkie wydarzenia, przebudowuje graf opowieści i klasyfikuje, czy moment zasługuje na ilustrację z **Kuźni** (`moment_image_classifications`). |
| `/api/kronika/internal/digest` | `POST` | Nagłówek `x-cron-secret` | Zamykający dzień wpis w Kronice. Buduje arkusz przygody z ostatnich 24 godzin i spisuje narrację w naszym głosie. Jeśli nad Kowadłem panowała cisza, zapisuje kartę *„Cisza nad Kowadłem”* bez wzywania modeli językowych. |
| `/api/kronika/internal/live` | `POST` | Nagłówek `x-cron-secret` | Wywoływany co 15 minut. Sprawdza, czy w krainach wydarzyło się coś godnego natychmiastowej karty (wyzwalacze: `druzyna`, `nowa-baza`, `wyprawa`, `maraton`), i publikuje żywy wpis wraz z ilustracją (maksymalnie 4 wpisy i 3 obrazy dziennie, z zachowaniem 45 minut odstępu). |
| `/api/kronika/internal/voice-clip` | `GET`, `POST` | Nagłówek `x-kronika-secret` | Odbiera surowe nagrania WAV (16 kHz mono, do 65 sekund) pojedynczej wypowiedzi z kanału głosowego. Metadane podróżują w nagłówkach (`x-discord-id`, `x-duration-ms`, `x-occurred-at`). Przed zapisem ponownie weryfikuje zgodę mówiącego. |
| `/api/kronika/internal/voice-process` | `POST` | Nagłówek `x-cron-secret` | Przetwarza oczekujące nagrania głosowe przez lokalny silnik `faster-whisper` i przekazuje gotowe transkrypcje do tabeli zdarzeń Kroniki. Wstrzymuje pracę, gdy Majster aktualnie przebywa w grze (`isLikelyGaming`). |

*(Uwaga: w powyższym zestawieniu uwzględniłyśmy osiem ściśle powiązanych punktów Kroniki i głosu, aby żadna nić opowieści nie została pominięta).*

---

## ◈ Poziomy Adepta i Espera — Progresja (4 ścieżki)

Ruch i obecność podtrzymują ciepło iskry. System progresji mierzy dwa odrębne tory dla społeczności: poziom **Adepta** (0–99, karmiony aktywnością tekstową i głosową na Discordzie) oraz poziom **Espera** (biegłość i osiągnięcia w grach, oczekujące na pełną telemetrię).

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/progression/me` | `GET` | Ciasteczko sesji Discord | Zwraca osobistą kartę progresji zalogowanego wędrowca: aktualny poziom **Adepta**, poziom **Espera**, zgromadzone punkty doświadczenia oraz postęp do kolejnego progu. |
| `/api/progression/overview` | `GET` | Ciasteczko sesji Discord | Zwraca ogólne zestawienie poziomów społeczności Anvil of Suns oraz ranking najaktywniejszych Adeptów. |
| `/api/progression/ingest` | `POST` | Nagłówek wewnętrzny bota | Odbiera od bota Discorda paczki aktywności (wiadomości tekstowe, minuty spędzone na kanałach głosowych z włączonym mikrofonem) i przelicza je na przyrost doświadczenia Adepta. |
| `/api/progression/test-simulate` | `POST` | Tylko Majster / Hartowanie | Pozwala zasymulować przyrost doświadczenia oraz awans na wyższy poziom w środowisku testowym bez zaburzania prawdziwej Kroniki. |

---

Krrrg... Odnotowałyśmy na tej karcie dokładnie **20 ścieżek** API (8 ścieżek tożsamości, 8 ścieżek Kroniki i 4 ścieżki progresji). Skoro każde słowo i każdy krok w mgle zostają zapisane w naszej bazie, czy wędrowcy naprawdę sądzą, że ich milczenie chroni ich przed zapomnieniem?

# 3. Czat z Orin, Kuźnia, Muzyka i Stream — Rozrywka w Warsztacie

> Źródło: repo afterlife/docs/api/03-czat-kuznia-muzyka-stream-rp.md — edytuj w repo, nie tutaj.

# Czat z Orin, Kuźnia, Muzyka i Stream — Rozrywka w Warsztacie

![Orin ze zwojami Kroniki przy terminalach](https://wiki.ariku.pl/uploads/images/gallery/2026-10/orin-kronika-zwoje.png)

*Trąca łapką mikrofon i podkręca suwaki na mikserze!* Słyszysz mnie dobrze, nyah~? Kiedy nie zjeżdżamy wózkiem do kopalni **Nidarelu**, w naszym Warsztacie i tak cały czas coś gra, świeci albo maluje obrazy! Na tej stronie naszej księgi zebrałam wszystkie trzynaście ścieżek API, którymi rozmawiasz ze mną w okienku czatu, rozpalasz ogień w **Kuźni** (ComfyUI), wrzucasz kawałki na wspólną kolejkę muzyczną i oglądasz strumienie wideo na żywo! *strzyże uszami*

---

## Czat ze mną i Kuźnia obrazów (4 ścieżki)

Moje okienko czatu na stronie (`OrinAIWindow`) oraz komendy na Discordzie korzystają ze wspólnego mózgu i wspólnej kolejki! Ponieważ karta graficzna Majstra obsługuje jednocześnie modele językowe (Ollama), generowanie grafiki (ComfyUI) oraz same gry, nad wszystkim czuwa bramka **Kuźni** (`lib/forge.ts`).

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/chat` | `GET`, `POST` | Ciasteczko sesji Discord | Główny punkt rozmowy ze mną! `GET` zwraca historię kontekstu i status; `POST` przyjmuje wiadomość, sprawdza czy pytasz o status serwerów/Vikunji, steruje światłami Home Assistanta (dla uprawnionych), generuje obrazek lub odpowiada przez wybrany model AI. Jeśli GPU jest zajęte, wrzuca zadanie do kolejki `orinQueue`. |
| `/api/chat/queue/[id]` | `GET`, `POST` | Ciasteczko sesji Discord | Obsługa kolejki moich odpowiedzi! `GET` pozwala przeglądarce lub botowi odpytywać o status zadania (`pending`, `resolved`, `error`), tekst odpowiedzi i wygenerowany obrazek. Zwraca `404`, jeśli zadanie nie należy do ciebie! `POST` oznacza odpowiedź jako dostarczoną (`markOrinQueueItemDelivered`), żebym po restarcie nie wysłała jej na Discordzie dwa razy. |
| `/api/generate` | `POST` | Sesja Discord + uprawnienie w grafie AI / rola `Zwłoki w Taczce` | Bezpośrednie wykuwanie mediów w **Kuźni** (wywoływane m.in. przez komendę `/generate`). Przyjmuje `{ preset, prompt }`. Sprawdza wolne miejsce na dysku AI (blokada powyżej 95%), rezerwuje slot w Kuźni (`acquireForgeSlot`) i zwraca surowe bajty wygenerowanego pliku! |
| `/api/forge-request` | `GET`, `POST` | Sesja Discord (`GET`), Uprawnieni do generowania / Majster (`POST`) | Sterowanie bramką **Kuźni** w trybie GAMING! `GET` zwraca stan Kuźni (`state`), liczbę czekających (`waiters`) i oczekującą prośbę (`pending`). `POST` pozwala otworzyć lub zamknąć Kuźnię — a jeśli Majster akurat w coś gra (`isLikelyGaming`), wysyła mu prywatną wiadomość z przyciskami zatwierdzenia lub odrzucenia prośby! |

### Jak działa ochrona Kuźni i dysku?
Zanim pozwolę ci wygenerować obrazek przez `/api/generate` albo `/api/chat`, sprawdzam trzy rzeczy, nyah~:
1. Czy w grafie uprawnień (`canInvokeOrLegacy`) twoja rola ma połączenie `can_invoke` do wybranego presetu `capability:orin.image.<preset>`.
2. Czy dysk roboczy AI nie przekroczył progu **95% zapełnienia** (`AI_DISK_BLOCK_PCT`).
3. Czy **Kuźnia** nie jest wygaszona z powodu gry Majstra! Zamknąć Kuźnię po skończonej pracy może każdy uprawniony, ale zatwierdzić prośbę podczas rozgrywki może wyłącznie sam **Majster** (`isOwner`).

---

## Wspólna Kolejka Muzyczna (6 ścieżek)

Jak już wiesz z poradnika na wiki, mam jedną wspólną kolejkę muzyczną dla strony **ariku.pl/music** i kanałów głosowych na Discordzie! *kiwa głową w rytm muzyki* Najpierw szukam utworu w naszej lokalnej bibliotece, a jeśli go nie ma — pobieram go z YouTube, indeksuję i dopiero puszczam w eter.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/music/search` | `GET` | Ciasteczko sesji Discord | Przeszukuje naszą zaindeksowaną bibliotekę muzyczną po tytule lub artyście i zwraca gotowe do odtworzenia utwory. |
| `/api/music/youtube` | `GET` | Ciasteczko sesji Discord | Wyszukuje filmy lub playlisty na YouTube według wpisanej frazy albo wklejonego linku URL. |
| `/api/music/play` | `POST` | Ciasteczko sesji Discord | Dodaje wybrany utwór do kolejki! Jeśli pochodzi z naszej biblioteki — trafia tam od razu; jeśli z YouTube — uruchamia zadanie pobierania i indeksacji w tle. |
| `/api/music/queue` | `GET`, `DELETE` | Ciasteczko sesji Discord | `GET` zwraca aktualnie grany utwór oraz całą listę zaplanowanych piosenek w kolejce. `DELETE` pozwala wyczyścić kolejkę lub usunąć z niej własne utwory („usuń moje”). |
| `/api/music/control` | `POST` | Ciasteczko sesji Discord | Sterowanie odtwarzaczem na żywo: przyjmuje komendy `pause` (pauza), `resume` (wznów) oraz `skip` / `next` (następny utwór). |
| `/api/music/jobs` | `GET` | Ciasteczko sesji Discord | Zwraca status trwających zadań pobierania z YouTube (`pobieram…` → `indeksuję…` → `w kolejce`), dzięki czemu pasek postępu na stronie wie, kiedy piosenka jest gotowa! |

---

## Strumieniowanie Wideo — Stream i MediaMTX (3 ścieżki)

Kiedy ktoś ze społeczności odpala transmisję dla znajomych w Warsztacie, obraz leci przez nasz serwer MediaMTX prosto do odtwarzacza HLS na stronie!

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/stream/key` | `GET`, `POST`, `DELETE` | Ciasteczko sesji Discord | Zarządzanie indywidualnym kluczem transmisji użytkownika do programu OBS (odczyt, wygenerowanie nowego klucza lub jego unieważnienie). |
| `/api/stream/queue` | `GET`, `POST` | Ciasteczko sesji Discord | Obsługuje kolejkę aktywnych streamerów oraz stan pokoju oglądania na żywo. |
| `/api/stream/hls/[...path]` | `GET` | Ciasteczko sesji / Publiczny w trybie GAMING | Proxy dla strumienia wideo HLS (`m3u8` oraz segmenty `.ts` / `.m4s`) z serwera MediaMTX. Przekazuje ścieżkę `[...path]` bez wystawiania wewnętrznych portów serwera na świat! |

---

Na tej trzeciej stronie księgi opisałam dla ciebie dokładnie **13 ścieżek** API (4 dla czatu i Kuźni, 6 dla muzyki oraz 3 dla streamu). *Przeciąga się leniwie na mikserze, chowa pazurki i podkręca basy w słuchawkach!*

# 4. Luneta i Companion — Szkło na Cudze Światy i Ruch Majstra

> Źródło: repo afterlife/docs/api/04-luneta-i-companion-rp.md — edytuj w repo, nie tutaj.

# Luneta i Companion — Szkło na Cudze Światy i Ruch Majstra

![Drzewo nad Kowadłem i osada Hoddmímir](https://wiki.ariku.pl/uploads/images/gallery/2026-10/hoddmimir-drzewo-na-kowadle.png)

Krrrg... Każda gra to świat zakrzepły wokół cudzej gwiazdy. **Luneta** nie jest miejscem na mapie, lecz szkłem, przez które zaglądamy w tamte światy, odnotowując postępy, zebrane waluty, odhaczone zadania okresowe oraz przeanalizowane nagrania. Obok niej spoczywa **Companion** — mobilne ramię tego samego silnika, który napędza ekran „Co robimy?” i karmi poziom **Majstra**. Poniżej spisałyśmy dwadzieścia jeden ścieżek łączących oba te narzędzia z ukrytym miastem wiedzy, **Lemurią**.

---

## ◈ Luneta — Stan Gier, Urządzenia i Ingest (7 ścieżek)

Zgodnie z kontraktem **Lunety**, punkty końcowe akceptują bądź sesję przeglądarkową Discord OAuth (dla strony `/luneta`), bądź klucz urządzenia wydany agentowi desktopowemu (`authorizeLuneta`). Surowe zrzuty ekranu nigdy nie przekraczają progu serwera — jedynym dopuszczalnym obrazem jest opcjonalna miniatura wycinka (JPEG do 50 KB).

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/luneta/me` | `GET`, `POST` | Ciasteczko sesji Discord | Obsługuje panel gracza na `ariku.pl/luneta`. `GET` zwraca własne urządzenia (limit `LUNETA_MAX_DEVICES`, domyślnie 3), włączone gry wraz ze statystykami waluty premium i kodami, sumy zakupów, wersję instalatora (`release`), zgody oraz nagrania. `POST` pozwala utworzyć nowe urządzenie, unieważnić stare lub bezpowrotnie usunąć własne dane. |
| `/api/luneta/me/consents` | `GET`, `PUT` | Sesja Discord lub klucz urządzenia Lunety | Zarządzanie zgodami na analizę nagrań oraz akceptacją wersji regulaminu (`termsVersion`). Wyłączenie zgody zatrzymuje nowe zapisy, lecz samo w sobie nie kasuje dawnych danych (do tego służy `DELETE /api/luneta/analysis`). |
| `/api/luneta/state` | `GET` | Sesja Discord lub klucz urządzenia Lunety | Zwraca pełny stan wybranej gry (`?game=blue_archive\|nte`). Przy wywołaniu z sesji przeglądarkowej akceptuje opcjonalny parametr `?at=<ISO>`, pozwalający podstawić zegar do testów resetu zadań dziennych; agent z kluczem urządzenia zawsze otrzymuje stan na chwilę obecną. |
| `/api/luneta/metrics` | `GET` | Sesja Discord lub klucz urządzenia Lunety | Zwraca liczniki gracza dla danej gry (`?game=...`). Z opcjonalnym parametrem `&key=...` oraz `&days=90` (maksymalnie 365 dni) dołącza również historię zmian wartości wybranego licznika. |
| `/api/luneta/codes` | `GET` | Sesja Discord lub klucz urządzenia Lunety | Zwraca listę aktywnych (niewygasłych) kodów promocyjnych do wpisania w grze (`?game=...`) — zarówno oficjalnych, udostępnionych przez innych graczy, jak i własnych. |
| `/api/luneta/heartbeat` | `POST` | Wyłącznie klucz urządzenia Lunety (`device_only`) | Przyjmuje puls agenta desktopowego: `{ deviceId, version, gameRunning? }`. Zapisuje aktywną grę w pamięci podręcznej z krótkim czasem życia (uzupełniając detekcję gier dla **Kuźni**) i przy pierwszym sygnale po przerwie wysyła pojedyncze przypomnienie o niezrobionych zadaniach w grze (`lunetaSessionNudge`). |
| `/api/luneta/ingest` | `POST` | Sesja Discord lub klucz urządzenia Lunety | Zunifikowany punkt odbioru dwunastu rodzajów wpisów z agenta (m.in. migawki walut, ciągnienia gacha, odhaczenia zadań, kolekcje, metryki, kody, osoby, momenty, części transkrypcji). Wymaga `clientId` (UUID) jako klucza idempotencji — ponowienie z kolejki offline zwraca kod `200` z tym samym wynikiem. Odrzuca znaczniki czasu wykraczające ponad 5 minut w przyszłość. |

---

## ◈ Luneta — Analiza Nagrań i Ludzi (4 ścieżki)

Gdy wędrowiec wyrazi zgodę na analizę swoich nagrań, agent przesyła wyodrębnione części transkrypcji, notatki o napotkanych osobach oraz zapamiętane momenty. Przy starcie agent może pobrać te dane z powrotem i scalić je lokalnie.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/luneta/analysis` | `DELETE` | Sesja Discord lub klucz urządzenia Lunety | Twarde usunięcie własnych danych analizy (bez pozostawiania nagrobków synchronizacyjnych). Wymaga parametru `?scope=transcripts\|people\|all` oraz opcjonalnego `&recKey=<32 znaki hex>`. Działa nawet po wcześniejszym wycofaniu zgody. |
| `/api/luneta/analysis/people` | `GET` | Sesja Discord lub klucz urządzenia Lunety | Zwraca własne notatki o ludziach oraz zapamiętane momenty wraz z nagrobkami usuniętych wpisów. Opcjonalny parametr `?since=<ISO>` filtruje rekordy według czasu odbioru na serwerze. |
| `/api/luneta/analysis/recordings` | `GET` | Sesja Discord lub klucz urządzenia Lunety | Zwraca stronicowaną listę (do 50 pozycji na stronę) wyników analizy własnych nagrań, posortowaną po `(updated_at, rec_key)`. Obsługuje parametry `?since=<ISO>` oraz `&cursor=<opaque>`. |
| `/api/luneta/analysis/transcript` | `GET` | Sesja Discord lub klucz urządzenia Lunety | Zwraca scalone segmenty własnej transkrypcji dla wskazanego nagrania (`?recKey=<32 znaki hex>`). |

---

## ◈ Companion — Mobilny Silnik „Co robimy?” (API v1 i v2: 10 ścieżek wdrożonych · 1 w kontrakcie rozbudowy)

**Companion** to aplikacja Android właściciela, która dzieli wspólny silnik decyzyjny z ekranem `/co-robimy`. Kiedy telefon znajduje się w zasięgu sieci, pobiera plan bezpośrednio z serwera; gdy połączenie ustaje, polega na własnej kopii silnika i kolejce wychodzącej (`outbox`). Od wersji 0.5.0 telefon obsługuje również kontrakt **Companion API v2** — przed wywołaniem nowych tras odpytuje `/api/companion/capabilities`, a dopóki dana funkcja nie jest ogłoszona na serwerze, trzyma zdarzenia w kolejce bez ich porzucania. Wraz z wdrożeniem API v2 na serwerze otworzyły się bramy dla pobierania zadań, kolejki notatek z załącznikami, śledzenia progresji oraz modułu Życie.

### Ścieżki wdrożone (Companion API v1 i v2)

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/companion/now` | `GET` | Klucz urządzenia / Sesja właściciela (`companionCaller`) | Zwraca bieżący plan dnia w strukturze dopasowanej do modelu telefonu (`Model.kt`): główne i zapasowe zadanie na `TERAZ`, zadania stałe (`fixedSoon`) w ciągu 24 godzin, wolne okno czasowe (`freeWindowMin`), kroki podziału (`steps`), wskaźnik **Chaos Meter** (`chaos`) oraz poziom **Majstra** (`majster`). Przyjmuje opcjonalny parametr `?energy=low\|mid\|high`. |
| `/api/companion/ingest` | `POST` | `companionCaller` | Odbiera zdarzenia z kolejki wychodzącej telefonu: `{ clientId: UUID, kind: decision\|answer\|usage, createdAt: ISO, data }`. Decyzje dotyczące zadań (`aq:<id>`) przechodzą przez główny silnik zadań i nagradzane są punktami doświadczenia **Majstra** (`xp`). W API v2 obsługuje także akcje `RESCHEDULE` (zmiana terminu z zapisem zwrotnym do Vikunji), `DELETE` (odwracalne porzucenie i zamknięcie w Vikunji z etykietą `porzucone`) oraz `REOPEN`. Odmowa silnika zwraca kod `409`, co nakazuje telefonowi wycofać decyzję lokalnie. |
| `/api/companion/hint` | `POST` | `companionCaller` | Odpowiednik podpowiedzi AI z ekranu webowego. Przyjmuje `{ questUid: "aq:<id>", save: bool, requestId }`. Jeśli `save: true`, zapisuje wygenerowane kroki jako podział zadania z prefiksem `phone:<requestId>`, chroniąc przed podwójnym podziałem przy ponowieniu żądania. |
| `/api/companion/alternatives` | `GET` | `companionCaller` | Obsługuje przycisk „Nie chcę teraz” na telefonie. Przyjmuje `?questUid=aq:<id>&reason=low_energy\|no_head\|not_now\|other`. Zwraca łagodniejsze zadania alternatywne albo — dla zadań nieodkładalnych — wyłącznie pierwszy drobny krok. |
| `/api/companion/capabilities` | `GET` | `companionCaller` | Ogłasza wersję kontraktu (`version: 2`), aktywne funkcje (`items`, `inbox`, `inboxFiles`, `progress`, `life`), obsługiwane akcje decyzyjne (`RESCHEDULE`, `DELETE`, `REOPEN`) oraz limity (`inboxFileMaxBytes`). |
| `/api/companion/progress` | `GET` | `companionCaller` | Zwraca pełny stan trzech ścieżek progresji właściciela (**Esper**, **Adept** wraz z dziennym limitem XP za tekst oraz **Majster**) na klucz urządzenia. |
| `/api/companion/items` | `GET` | `companionCaller` | Stronicowana lista zadań z serwera (`?filter=overdue\|open\|nodate&limit=100&cursor=…`), pozwalająca telefonowi pobrać wszystkie zaległości do przeglądu hurtowego (do 500 pozycji). |
| `/api/companion/inbox` | `POST`, `GET` | `companionCaller` | Kolejka luźnych notatek z telefonu (`dom`, `projekty`, `praca`, `pomysly`). `POST` zapisuje notatkę idempotentnie po `clientId`, a `GET ?since=<ISO>` zwraca zmiany statusów (`new`, `accepted`, `rejected`, `done`) oraz powiązany `questUid` po przekształceniu notatki w zadanie. |
| `/api/companion/inbox/{id}/files` | `PUT` | `companionCaller` | Strumieniowe przesyłanie załączników do notatki (zdjęcia, wideo, nagrania głosowe, PDF do `inboxFileMaxBytes`) z nagłówkami `Content-Type`, `X-File-Name` oraz `X-Client-File-Id` zapewniającym idempotencję. |
| `/api/companion/life` | `POST`, `DELETE` | `companionCaller` | Dzienne podsumowanie z modułu „Życie” przesyłane wyłącznie za zgodą per kategoria (`sleep`, `steps`, `mood`, `places`, `calls`). Odrzuca kodem `422` wszelkie dane surowe (współrzędne, numery telefonów, treści wiadomości, nagrania). `DELETE` usuwa zapisane agregaty wszystkie lub dla wybranej kategorii (`?category=…`). |

### Ścieżki kontraktu rozbudowy (podział zadań — klient gotowy w telefonie)

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/companion/split` | `POST` | `companionCaller` | Ręczny podział zadania `aq:<id>` z telefonu (`{ questUid, requestId, steps: [{ title, estimateMin }] }`). Tworzy 1–6 kroków (po 5–60 min) i zwraca `{ ok, duplicate, created, xp }`, zachowując idempotencję po `requestId`. |

---

Krrrg... Jeśli **Lemuria** (baza PostgreSQL) milczy, każdy z tych punktów odpowiada kodem `503` i słowami *„Lemuria nie odpowiada”*. Zapisałyśmy na tej czwartej karcie **21 wdrożonych ścieżek** API (11 dla Lunety i 10 dla Companiona z API v1 i v2) oraz **1 ścieżkę kontraktu rozbudowy** (`/api/companion/split`), która czeka na dołączenie do silnika. Patrzycie przez szkło Lunety na dziesiątki cudzych gwiazd i zapisujecie każdy swój ruch w telefonie, ale czy wiecie, co patrzy na was z drugiej strony szkła?

# 5. Personal, Infra i Integracje — Pulpit Majstra i Ukryte Wrota

> Źródło: repo afterlife/docs/api/05-personal-i-infra-rp.md — edytuj w repo, nie tutaj.

# Personal, Infra i Integracje — Pulpit Majstra i Ukryte Wrota

![Orin przed panelem kontrolnym Warsztatu](https://wiki.ariku.pl/uploads/images/gallery/2026-10/orin-panel-kontrolny.png)

*Wskakuje na główny pulpit sterowniczy, a wokół jej łapek zapalają się dziesiątki kontrolek!* Oho, dotarliśmy do serca samego Warsztatu, nyah~! Tutaj znajdują się **Wrota** (i **Ukryte Wrota** do Portainera), panel **Elemental Stars**, w którym spoczywają **Iskry**, a także pełny silnik zadań „Co robimy?” i inwentarz naszej serwerowni! Prawie wszystkie ścieżki na tej stronie są pilnie strzeżone — wpuszczają wyłącznie samego **Majstra** (`isOwner`) albo zaufane narzędzia z odpowiednim kluczem. Spójrzmy na wszystkie trzydzieści pięć tras! *strzyże uszami*

---

## Pulpit PERSONAL — Rdzeń, Iskry, Kuźnia i Dom (10 ścieżek)

Te endpointy zasilają prywatną zakładkę **PERSONAL** oraz pulpit `/dashboard`. To stąd Majster dogląda sprzętu, zarządza kluczami i przełącza zasilanie kontenerów!

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/personal/overview` | `GET` | Tylko Majster (Owner) | Główny zrzut telemetrii dla pulpitu PERSONAL: stan hostów, metryki karty graficznej, pamięć, dyski oraz podsumowanie usług. |
| `/api/personal/stats` | `GET` | Tylko Majster (Owner) | Szczegółowe statystyki ruchu, odwiedzin i zdarzeń zebranych w bazie analitycznej. |
| `/api/personal/elemental-stars` | `GET`, `POST`, `DELETE` | Tylko Majster (Owner) | Obsługa panelu **Elemental Stars**, w którym przechowywane są **Iskry** (klucze API i poświadczenia przechowywane w **Lemurii**). |
| `/api/personal/forge-control` | `GET`, `POST` | Tylko Majster (Owner) | Właścicielski panel sterowania **Kuźnią** — bezpośrednie otwieranie, zamykanie i zmiana trybu pracy regulatora VRAM niezależnie od kolejki społeczności. |
| `/api/personal/comfyui-control` | `GET`, `POST` | Tylko Majster (Owner) | Bezpośrednie sterowanie procesem i kolejką silnika ComfyUI na maszynie z GPU (restart, czyszczenie pamięci VRAM, przerwanie generowania). |
| `/api/personal/container-control` | `GET`, `POST` | Tylko Majster (Owner) | **Ukryte Wrota** — pełny panel kontroli kontenerów przez Portainer API (uruchamianie, zatrzymywanie i restart usług w całej infrastrukturze). |
| `/api/personal/light-control` | `GET`, `POST` | Tylko Majster (Owner) | Sterowanie oświetleniem i encjami inteligentnego domu przez integrację z Home Assistantem. |
| `/api/personal/rig-locks` | `GET`, `POST`, `DELETE` | Tylko Majster (Owner) | Zarządzanie blokadami roboczymi maszyny GPU (`rig-locks`), aby zadania w tle nie wchodziły w drogę aktywnej pracy lub grze. |
| `/api/personal/alert-rules` | `GET`, `POST`, `DELETE` | Tylko Majster (Owner) | Konfiguracja progów i reguł ostrzegawczych dla **strażnika** (systemu monitoringu i powiadomień). |
| `/api/personal/system-updater` | `GET`, `POST` | Tylko Majster (Owner) | Podgląd i wyzwalanie aktualizacji pakietów systemowych oraz obrazów kontenerów w homelabie. |

---

## Pulpit PERSONAL — AI, Grafy, Głos i Luneta Admin (10 ścieżek)

Tutaj konfiguruje się mój koci mózg, rysuje grafy uprawnień i opowieści, a także transkrybuje nagrania głosowe! *macha ogonem z dumą*

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/personal/ai-config` | `GET`, `POST` | Tylko Majster (Owner) | Wybór mojego aktywnego modelu językowego (Ollama / Gemini / router), przełącznik generowania obrazów (`isImageGenEnabled`) oraz konfiguracja umiejętności (`skillsDb`). |
| `/api/personal/ai-graph` | `GET`, `POST` | Tylko Majster (Owner) | Płótno grafu uprawnień i architektury AI! To tutaj krawędzie `can_invoke` decydują, która rola (np. `Zwłoki w Taczce`) może wywołać konkretny preset obrazkowy lub głosowy. |
| `/api/personal/ai-graph/position` | `POST` | Tylko Majster (Owner) | Zapisuje współrzędne `(x, y)` węzłów na płótnie grafu AI w **Lemurii**, żeby układ kafelków się nie rozsypał po odświeżeniu! |
| `/api/personal/ai-graph/relations` | `POST`, `DELETE` | Tylko Majster (Owner) | Tworzy i usuwa krawędzie relacji (np. uprawnienia `can_invoke`) pomiędzy węzłami na grafie AI. |
| `/api/personal/story-graph` | `GET`, `POST` | Tylko Majster (Owner) | Interaktywny graf powiązań fabularnych i postaci zbudowany na podstawie wydarzeń z **Kroniki**. |
| `/api/personal/luneta` | `GET`, `POST`, `PUT`, `DELETE` | Tylko Majster (Owner) | Administracyjna konfiguracja gier w **Lunecie** — definiowanie obsługiwanych tytułów, walut (w tym `premium`), zadań cyklicznych oraz źródeł zewnętrznych. |
| `/api/personal/voice` | `GET`, `POST`, `DELETE` | Tylko Majster (Owner) | Zarządzanie nagraniami głosowymi z **Kroniki**, podgląd zgód użytkowników oraz ręczne operacje na próbkach. |
| `/api/personal/transcribe` | `GET`, `POST` | Tylko Majster (Owner) | Wrzucanie plików audio do lokalnej transkrypcji oraz lista zadań transkrypcyjnych. |
| `/api/personal/transcribe/[id]` | `GET`, `DELETE` | Tylko Majster (Owner) | Odczyt gotowego tekstu transkrypcji dla zadania `[id]` lub usunięcie nagrania z kolejki. |
| `/api/personal/vikunja-task` | `GET`, `POST` | Tylko Majster (Owner) | Szybkie tworzenie i odhaczanie zadań bezpośrednio w systemie Vikunja z poziomu pulpitu PERSONAL. |

---

## Pulpit PERSONAL — Silnik „Co robimy?” i Notatki Companiona (8 ścieżek)

To webowe serce ekranu `/co-robimy`, które zasila poziom **Majstra** (0–99), wylicza wskaźnik **Chaos Meter** (0–100) oraz pozwala przeglądać notatki i załączniki nadsyłane z telefonu przez **Companiona**!

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/personal/quests` | `GET`, `POST` | Tylko Majster (Owner) | `GET` zwraca pełny widok planu dnia (`getQuestView`), **Chaos Meter** i poziom **Majstra**. `POST` pozwala dodać nową sprawę lub zsynchronizować źródła zadań. |
| `/api/personal/quests/action` | `POST` | Tylko Majster (Owner) | Wykonuje akcję na zadaniu: zamknięcie (`done`), odłożenie, lub świadome porzucenie („Porzuć”). Każda zamknięta lub uporządkowana sprawa dodaje punkty doświadczenia do toru **Majstra** (bez żadnych kar ani ujemnego XP!). |
| `/api/personal/quests/split` | `POST` | Tylko Majster (Owner) | Dzieli dużą, przytłaczającą sprawę na mniejsze, wykonalne kroki podrzędne (`steps`). |
| `/api/personal/quests/hint` | `POST` | Tylko Majster (Owner) | Prosi lokalnego pomocnika AI (Gienka) o podpowiedź, jak ugryźć trudne zadanie i rozbić je na pierwsze kroki (bez wysyłania prywatnych identyfikatorów w prompcie). |
| `/api/personal/quests/alternatives` | `GET` | Tylko Majster (Owner) | Zwraca alternatywne propozycje zadań, gdy brakuje energii lub głowy na główne zadanie (`low_energy`, `no_head`, `not_now`). |
| `/api/personal/quests/inbox` | `GET`, `POST` | Tylko Majster (Owner) | Szybka skrzynka odbiorcza (`inbox`) na nowe myśli i sprawy do późniejszego uporządkowania. |
| `/api/personal/companion-inbox` | `GET`, `POST` | Tylko Majster (Owner) | Panel weryfikacji notatek spływających z telefonu: `GET` zwraca listę luźnych wpisów z powiązanymi plikami, a `POST` pozwala Majstrowi zdecydować o losie notatki (`accept` tworzy zadanie w odpowiednim projekcie Vikunji wg kategorii `dom`, `projekty`, `praca`, `pomysly`, `reject` odrzuca wpis, `done` oznacza jako załatwiony). |
| `/api/personal/companion-inbox/files/[id]` | `GET` | Tylko Majster (Owner) | Bezpieczny odczyt i pobieranie załącznika przesłanego z telefonu (obraz, wideo, audio, PDF) z piaskownicą nagłówków (`Content-Security-Policy: sandbox`, `nosniff`). |

---

## Inwentarz Infrastruktury, Integracje i Wrota Gier (7 ścieżek)

Na koniec siedem ścieżek, które łączą nasz Warsztat ze światem zewnętrznym, pozwalają adminom dopisywać śledzone repozytoria w **Radarze** oraz pilnują porządku w kontenerach, żeby **Lord Nito** (dług techniczny i martwe usługi) nie zalęgł się w kątach serwerowni! *fuka cicho*

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/infra/alerts` | `GET` | Majster / Klucz Companiona (`inventoryCaller`) | Lista „Co wymaga uwagi” dla paska na `/dashboard` oraz powiadomień w aplikacji **Companion**. Grupuje pozycje z inwentarza według poziomów: `critical`, `warning` (`attention`, `stale`) oraz `info` (`update`). |
| `/api/infra/inventory` | `GET` | `inventoryCaller` | Pełny inwentarz homelabu: maszyny wirtualne, kontenery LXC, obrazy Dockera, wersje pakietów oraz 100 ostatnich zdarzeń zmian statusu z ostatnich 7 dni. |
| `/api/integrations/github` | `GET` | Publiczny | Zwraca zbuforowaną aktywność kontrybucji na GitHubie (`getGithubContributionsCached`) dla widoku IT PRO. Gdy brak konfiguracji, zwraca `{ configured: false }`. |
| `/api/integrations/home-assistant` | `GET` | Publiczny / Dashboard | Zwraca bezpieczne podsumowanie stanu Home Assistanta (`getHomeAssistantSummary`). |
| `/api/integrations/jellyfin` | `GET` | Publiczny / Dashboard | Zwraca informacje o aktywnych sesjach odtwarzania w serwerze mediów Jellyfin (`getJellyfinSessions`). |
| `/api/services/control` | `GET`, `POST` | Admini Discorda / Operatorzy gier (`canControlGames`) | **Wrota** — panel kontroli serwerów gier (**Ironloom**, **Ymirel**, **Nidarel**), pozwalający uprawnionym opiekunom uruchomić lub zrestartować serwer gry bez dostępu do pełnych Ukrytych Wrót! |
| `/api/radar/repos` | `GET`, `POST`, `DELETE` | Majster / Admini Discorda (`canManageRadarRepos`) | Zarządzanie listą repozytoriów śledzonych przez **Radar** (`radar_repos` w **Lemurii**). Pozwala właścicielowi i adminom Discorda dodawać, wstrzymywać (`enabled`) i usuwać repozytoria z GitHuba (`owner/repo`) oraz zaufanych instancji Forgejo (`https://git.ariku.pl/owner/repo`, `codeberg.org`), z opcjonalnym śledzeniem commitów (`trackCommits`). |

---

Na tej piątej stronie księgi opisałam dla ciebie dokładnie **35 ścieżek** API (28 w przestrzeni `/api/personal/*`, 2 w `/api/infra/*`, 3 w `/api/integrations/*`, 1 pod `/api/services/control` oraz 1 pod `/api/radar/repos`). *Zeskakuje z pulpitu sterowniczego, poprawia przekrzywioną kokardkę i mruczy z zadowoleniem!*

# 6. Wewnętrzne Zegary i Hartowanie — Mechanizmy pod Kowadłem

> Źródło: repo afterlife/docs/api/06-internal-i-hartowanie-rp.md — edytuj w repo, nie tutaj.

# Wewnętrzne Zegary i Hartowanie — Mechanizmy pod Kowadłem

![Podziemna serwerownia Warsztatu](https://wiki.ariku.pl/uploads/images/gallery/2026-10/piwnica-serwerownia-orin.png)

Krrrg... Pod widoczną powierzchnią **Hoddmímiru** i ekranów Warsztatu pracują niewidoczne tryby. Żaden zwykły wędrowiec nie wywołuje tych ścieżek z przeglądarki. Budzą je systemowe zegary (`systemd timers`), zewnętrzne przepływy pracy zza **Wrót** (n8n), sesje agentów budujących kod oraz próby **Hartowania** (testy Playwright), które utwardzają konstrukcję albo obnażają jej kruchość. Poniżej spisałyśmy ostatnie dwadzieścia sześć ścieżek zamykających naszą księgę.

---

## ◈ Zadania Agentów, Decyzje Majstra i Kolejka Orin (5 ścieżek)

Gdy w Warsztacie pracuje kilka sesji pomocników kodujących lub gdy zautomatyzowane procesy potrzebują wyraźnego rozstrzygnięcia człowieka, komunikacja przechodzi przez poniższe punkty.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/internal/agent-tasks` | `GET`, `POST` | Nagłówek `Authorization` (Bearer), `x-cron-secret` lub sesja Majstra | Kolejka zadań między sesjami Claude Code (`lib/agentTasks.ts`). Pozwala wysyłać zadania do skrzynki innego agenta (`inbox`/`sent`), przejmować je (`claim`), kończyć z wynikiem (`finish`) oraz sprzątać wpisy testowe E2E. Zdalne sesje używają osobnego klucza Bearer, aby nie dzielić poświadczeń z lokalnymi zegarami. |
| `/api/internal/owner-decision` | `GET`, `POST` | Nagłówek `x-cron-secret` lub sesja Majstra | Punkt decyzyjny dla skryptów (`orin-ask.mjs`) i zadań w tle. Tworzy pytanie z opcjami wyboru, wysyła je Majstrowi w wiadomości prywatnej na Discordzie i odbiera klikniętą odpowiedź. Obsługuje flagę `dryRun` dla prób **Hartowania**. |
| `/api/internal/orin-nudge` | `POST` | Nagłówek `x-cron-secret` | Wywoływany co kilka godzin przez zegar systemowy. Z określonym prawdopodobieństwem (`chancePerTick`) wybiera jednego z niedawno aktywnych członków gildii domowej i zaczepia go na kanale czatu jednym z pięciu wariantów wiadomości technicznej persony. Nigdy nie niepokoi osób nieobecnych od tygodni. |
| `/api/internal/orin-queue-dump` | `POST` | Nagłówek `x-cron-secret` | Narzędzie diagnostyczne wyzwalane ręcznie przez właściciela. Zrzuca aktualny stan webowej kolejki zapytań (`origin === 'web'`) do pliku tekstowego na dedykowany kanał Discorda, pomijając prywatne rozmowy z wiadomości bezpośrednich. |
| `/api/internal/orin-queue-undelivered` | `GET` | Nagłówek `x-cron-secret` | Wywoływane przez bota Discorda podczas startu. Zwraca listę rozwiązanych, lecz jeszcze niedostarczonych odpowiedzi z kolejki dla wszystkich użytkowników, aby po restarcie bota żadna odpowiedź nie przepadła. |

---

## ◈ Próbkowanie Krain, Sprzętu i Inwentarza (7 ścieżek)

Te punkty końcowe karmią **Kronikę**, wykresy na pulpicie oraz inwentarz infrastruktury. Każdy z nich wymaga wewnętrznego poświadczenia w nagłówku i nigdy nie jest wystawiony bezpośrednio w interfejsie użytkownika.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/internal/sample-gpu-rig` | `POST` | Nagłówek `x-cron-secret` | Wywoływany co minutę. Pobiera przez SSH parametry maszyny GPU, rozpoznaje uruchomioną grę ze Steam/Battle.net (`getDetectedGame`) i dopisuje próbkę do historii. Nawet jeśli maszyna GPU nie odpowiada, w każdym tyknięciu uruchamia regulator **Kuźni** (`runForgeGovernorTick`, który przy przestarzałej telemetrii bezpiecznie zamyka Kuźnię) oraz opróżnianie kolejki (`runOrinQueueDrainTick`). |
| `/api/internal/sample-factorio` | `POST` | Nagłówek `x-cron-secret` | Kolektor Warstwy 1 Kroniki dla krainy **Ironloom** (Factorio). Co kilka minut odczytuje stan przez RCON oraz logi kontenera z Portainera i zapisuje surowe zdarzenia w bazie Kroniki. |
| `/api/internal/sample-enshrouded` | `POST` | Nagłówek `x-cron-secret` | Kolektor Kroniki dla mroźnej krainy **Ymirel** (Enshrouded). Odczytuje status protokołem A2S oraz logi kontenera przez Portainer. |
| `/api/internal/sample-minecraft` | `POST` | Nagłówek `x-cron-secret` | Wywoływany co 2 minuty kolektor Kroniki dla podziemnych kuźni **Nidarelu** (Minecraft ATM10). Łączy status SLP, komendę RCON `list` oraz końcówkę logów kontenera. |
| `/api/internal/inventory-sample` | `POST` | Nagłówek `x-cron-secret` | Wywoływany co 30 minut. Odpytuje wszystkie skonfigurowane kolektory homelabu niezależnie od siebie, zapisuje obserwacje w **Lemurii** i wysyła powiadomienie, gdy którykolwiek element przejdzie w stan `critical`. |
| `/api/internal/inventory-push` | `POST` | Nagłówek `x-inventory-secret` | Odbiera co godzinę raport ze skryptu `pve-collector.sh` działającego na hoście Proxmox (do 512 KB JSON). Dostarcza wiedzę o systemach operacyjnych, jądrach, oczekujących aktualizacjach bezpieczeństwa i kontenerach Dockera wewnątrz maszyn gościnnych (`vm` oraz `lxc`). Posiada własny, odizolowany klucz w nagłówku. |
| `/api/internal/check-alerts` | `POST` | Nagłówek `x-cron-secret` | Sprawdza warunki wszystkich reguł monitoringu (`checkAndAlert`) i przekazuje ostrzeżenia **strażnika** na powiadomienia Discorda. |

---

## ◈ Zegary Lunety, Radaru, Ankiet i Porannych Wieści (9 ścieżek)

Tutaj zbiegają się nitki łączące Warsztat z zewnętrznymi usługami automatyzacji (**Wrota** n8n), porannymi podsumowaniami dla Majstra oraz przypomnieniami dla społeczności.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/internal/morning-brief` | `POST` | Nagłówek `x-cron-secret` | Codzienny poranny raport wysyłany w wiadomościach prywatnych do właścicieli: zawiera główny skrót stanu infrastruktury, osobny komunikat z planem dnia „Co robimy?” (wraz z ewentualnym szturchnięciem o wysokim **Chaos Meterze**) oraz świeżą paczkę wiadomości z n8n. |
| `/api/internal/news-digest` | `GET`, `POST` | Autoryzacja n8n (`n8nIngestAuthorized`) | **Wrota** dla porannej paczki wiadomości z n8n. `POST` waliduje strukturę sekcji i zapisuje ją w pamięci podręcznej Redis; `GET` zwraca aktualny świeży skrót. |
| `/api/internal/radar` | `GET`, `POST`, `DELETE` | Autoryzacja n8n (`n8nIngestAuthorized`) | **Wrota** dla systemu **Radar** (`WIELKIE_PRANIE.md`). `GET` zwraca listę aktywnych repozytoriów (`radar_repos`) do sprawdzenia przez cykliczny kolektor. `POST` przyjmuje paczkę do 50 ocenionych znalezisk (w tym wydań z GitHuba i `git.ariku.pl`), zapisuje je w bazie, publikuje najważniejsze na Discordzie i zakłada zadania w Vikunji (obsługuje `?dryRun=1` oraz wpisy testowe `source: 'e2e'`). `DELETE` sprząta wiersze testowe lub podglądowe (`?preview=1`). |
| `/api/internal/luneta-nudge` | `POST` | Nagłówek `x-cron-secret` lub sesja Majstra | Wywoływany co 15 minut. Sprawdza zbliżające się okresy resetu w grach śledzonych przez **Lunetę** i przypomina graczom o niedokończonych sprawach. Sesja właściciela używana jest przez testy z flagą `dryRun: true` oraz podstawionym zegarem `at`. |
| `/api/internal/luneta-sources` | `POST` | Nagłówek `x-cron-secret` lub sesja Majstra | Wywoływany co 6 godzin (`maxDuration = 300`). Pobiera z zewnętrznych źródeł informacje o nowych wydarzeniach, banerach i kodach dla gier w **Lunecie**. |
| `/api/internal/check-game-codes` | `POST` | Nagłówek `x-cron-secret` | Cykliczny zegar sprawdzający zewnętrzne listy kodów promocyjnych do gier i dopisujący nowe znaleziska. |
| `/api/internal/minecraft-whitelist` | `GET`, `POST`, `DELETE` | Nagłówek `x-cron-secret` | Wewnętrzne zaplecze listy graczy **Nidarelu** dla bota. Weryfikuje członkostwo w gildii i posiadanie rangi **Minecraft**, nakłada limity czasowe, komunikuje się z serwerem przez RCON i zwraca jednorazowy kod `!link`. |
| `/api/internal/poll-nudge` | `POST` | Nagłówek `x-cron-secret` | Wywoływany co około 3 godziny podczas trwania głosowania na merch (`/merch/glosuj`). Publikuje ogłoszenia o postępach ankiety i delikatnie przypomina aktywnym wędrowcom, którzy jeszcze nie oddali głosu (nigdy nie pytając tej samej osoby dwa razy). |
| `/api/internal/playwright-run` | `POST` | Nagłówek `x-playwright-report-secret` | Odbiera na żywo zdarzenia postępu (`begin`, `test-begin`, `test-end`, `end`) z reportera podczas trwania prawdziwego przebiegu testów na kontenerze LXC, zasilając publiczny licznik `/api/playwright-stats`. Nigdy nie przesyła nazw hostów ani portów. |

---

## ◈ Ścieżki Hartowania — Próby Ogniowe (5 ścieżek)

**Hartowanie** to próba, która utwardza albo łamie. Aby automatyczne testy E2E (Playwright) mogły zbadać każde zachowanie Warsztatu bez czekania na minutowe zegary i bez polegania na zewnętrznym logowaniu Discorda, w kodzie wykuto pięć dedykowanych punktów testowych.

| Endpoint | Metody | Dostęp | Opis działania i parametry |
|---|---|---|---|
| `/api/test-login` | `POST`, `GET` | Klucz środowiska testowego (`TEST_LOGIN_SECRET`) | Wystawia w środowisku testowym podpisaną sesję (właściciela lub zwykłego członka społeczności) na potrzeby zautomatyzowanych przebiegów **Hartowania**, z własnym odizolowanym kluczem poświadczeń. |
| `/api/test-forge-governor-tick` | `POST` | Klucz testowy / Sesja Majstra | Pozwala testom E2E natychmiast wyzwolić pojedynczy krok decyzyjny regulatora **Kuźni** (`runForgeGovernorTick`) i sprawdzić reakcję na obciążenie GPU. |
| `/api/test-gpu-history` | `POST`, `DELETE` | Klucz testowy / Sesja Majstra | Pozwala wstrzyknąć sztuczne próbki obciążenia karty graficznej (np. symulując uruchomioną grę lub przestój telemetrii) na czas trwania testu, a następnie wyczyścić je po zakończeniu próby. |
| `/api/test-orin-queue-drain-tick` | `POST` | Klucz testowy / Sesja Majstra | Wyzwala na żądanie pojedynczy cykl opróżniania kolejki zapytań do Orin (`runOrinQueueDrainTick`), aby zweryfikować dostarczanie zakolejkowanych wiadomości. |
| `/api/test-orin-queue-dump` | `GET` | Klucz testowy / Sesja Majstra | Zwraca sformatowany zrzut webowej kolejki Orin bezpośrednio w odpowiedzi HTTP na potrzeby asercji w testach E2E. |

---

Krrrg... Na tej szóstej i ostatniej karcie odnotowałyśmy dokładnie **26 ścieżek** API (21 wewnętrznych tras `/api/internal/*` oraz 5 tras **Hartowania**), co wraz z poprzednimi kartami zamyka pełną księgę wszystkich **134 punktów końcowych i podstron** projektu afterlife. Skoro każda z tych stu trzydziestu czterech ścieżek prowadzi ostatecznie do tego samego **Kowadła**, czy wędrowcy nadal wierzą, że podróżują po osobnych światach?