Chybova hlaseni konektoru rikaji, co se stalo, a kam to slo

Duvod od sluzby jde primo do hlasky: z tela odpovedi se vytahne detail,
error_description, message, title, error i seznam missingHeaders. Retezec,
ktery vypada jako JSON, se rozbaluje dal - sluzba iDoklad presne takhle
predava telo od iDokladu samotneho. Kdyz sluzba nenapsala nic, rekne se to.

401 a 403 uz nejsou jedna hlaska. 401 = udaje sluzba dostala a neuznala je.
403 = tvar udaju je v poradku, zakazuje se samo volani.

V kazde hlasce je cela adresa vcetne serveru (ScriptRequestInfo.url),
bez query - v query muze byt tajemstvi. Zaklad adresy je z konfigurace
a konektor ho smi prepsat, takze se neda odvodit z toho, kde je nasazeny
portal. Adresa je videt i na karte konektoru a v odpovedi na test, i kdyz
overeni projde.

Tlacitko Logy na karte konektoru a historie poslednich peti overeni.
Odpoved sluzby dosud existovala jen v odpovedi na test, tedy do prekresleni
stranky, a v logu containeru. Do logu containeru se nikdo divat nechodi.
Zaznam se uklada i pri uspechu, jinak by neslo poznat, jestli konektor nesel
nikdy, nebo prestal jit ve chvili, kdy nekdo sahnul na udaje.

Migrace 003_connector_checks.sql, endpoint GET /connectors/:id/checks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-08-25 07:06:14 +02:00
co-authored by Claude Opus 5
parent 6297bbf480
commit 5a124a53d8
14 changed files with 648 additions and 54 deletions
+51
View File
@@ -155,6 +155,56 @@ nahlas - test, ktery projde i se spatnymi udaji, by uzivateli rikal nepravdu.
Neuspesne overeni **neni chyba API**. Vraci se 200 s `ok: false` a popisem,
protoze vysledek "nefunguje to" je platna odpoved na otazku "funguje to?".
### Co ma stat v hlasce
Samotny kod odpovedi nikoho nikam nedovede. Hlaska proto nese tri veci:
1. **Duvod, ktery napsala sama sluzba.** Vytahne se z tela odpovedi
(`detail`, `error_description`, `message`, `title`, `error`, seznam
`missingHeaders`). Kdyz sluzba vlozi do `detail` cele JSON tela od te
skutecne sluzby za ni, rozbali se to dal. Kdyz sluzba nenapsala nic,
rekne se i to - prazdne telo je taky informace.
2. **Rozlisene 401 a 403.** Kazdy znamena neco jineho a rada za nim je opacna:
401 = sluzba udaje dostala a neuznala je, jde tedy o Client ID, Client Secret
nebo jejich platnost. 403 = tvar udaju v poradku, zakazuje se samo volani,
tedy nepovolena IP adresa, chybejici opravneni uctu nebo aplikace,
pod kterou se vola.
3. **Celou adresu vcetne serveru**, ne jen cestu. Zaklad adresy je
ze `SERVICES_BASE_URL` a konektor ho smi prepsat, takze
"`/apps/idoklad/account/agenda` vratilo 403" nerika, jestli se to vubec
trefilo na spravny stroj, nebo to zaridla cizi proxy cestou. Query se
do hlasky nedava, muze v ni byt tajemstvi.
Adresa se vraci i **pri uspechu** (`baseUrl` v odpovedi na test) a je videt
na karte konektoru i v hlavicce dialogu Logy. Hadat ji podle toho, kde je
nasazeny portal, nejde.
Co se **nedela**: sonda na `/health` vedle overeni. `/health` povoleni IP
adresy nevyzaduje, takze z toho, ze projde, se o IP nic nedozvis - byla by to
veta, ktera zni jako zaver a zadny neni.
Cele telo odpovedi zustava v `detail` a v portalu je u overeni konektoru
**rozbalene rovnou**. Slozeny toggle by u chyby, kterou nikdo necekal, jen
schoval to jedine, co ji vysvetluje.
### Historie overeni
Kazde overeni se ulozi ke konektoru, drzi se **poslednich pet** zaznamu
(`CHECK_HISTORY`). Zaznam nese cas, jestli proslo, co se overovalo, HTTP kod,
hlasku, cele telo odpovedi a ktere volani to bylo.
Uklada se i uspesne overeni. Bez nej se neda poznat, jestli konektor nesel
nikdy, nebo prestal jit ve chvili, kdy nekdo sahnul na udaje.
V portalu je to pod tlacitkem **Logy** na karte konektoru. Do te doby existovala
odpoved sluzby jen v odpovedi na test, tedy do prekresleni stranky, a v logu
containeru. Do logu containeru se nikdo divat nechodi, takze to bylo totez
jako nikde.
Historie se **nevraci v seznamu konektoru**, jen `checkCount`. Pet tel odpovedi
na konektor jsou desitky kilobajtu za neco, co vetsinu casu nikdo necte.
Cte se zvlast pres `/connectors/:id/checks`.
## API
| Metoda | Cesta | Popis |
@@ -167,6 +217,7 @@ protoze vysledek "nefunguje to" je platna odpoved na otazku "funguje to?".
| PATCH | `/api/dashboard/connectors/:id` | upravit |
| DELETE | `/api/dashboard/connectors/:id` | smazat |
| POST | `/api/dashboard/connectors/:id/test` | overit napojeni |
| GET | `/api/dashboard/connectors/:id/checks` | poslednich pet overeni |
## Stranky portalu
+49
View File
@@ -2,6 +2,55 @@
Nejnovejsi nahore.
## 2026-08-25 - chybova hlaseni konektoru rikaji, co se stalo
"Pristup zamitnut: GET /apps/idoklad/account/agenda vratilo HTTP 403.
Zkontrolujte pristupove udaje." Tahle hlaska je k nicemu. 403 muze byt
nepovolena IP adresa i spatne udaje a veta radi presne to, co v tu chvili
nepomuze. Duvod pritom sluzba do tela odpovedi napsala, jen se zahodil.
### Zmeneno
- **Duvod od sluzby jde primo do hlasky.** `src/scripts/http.ts` vytahne
z tela odpovedi `detail`, `error_description`, `message`, `title`, `error`
i seznam `missingHeaders`. Retezec, ktery vypada jako JSON, se rozbaluje
dal - nase sluzba iDoklad presne takhle predava telo od iDokladu samotneho.
Kdyz sluzba nenapsala nic, hlaska to rekne, misto aby to zamlcela.
- **401 a 403 uz nejsou jedna hlaska.** 401 = udaje sluzba dostala a neuznala,
IP adresa s tim nema co delat. 403 = tvar udaju je v poradku, zakazuje se
samo volani, tedy IP adresa, opravneni uctu nebo aplikace, pod kterou se vola.
- **Cela odpoved sluzby je u overeni konektoru rozbalena rovnou**
(`ErrorDetail` ma novy `defaultOpen`). U chyby, kterou nikdo necekal,
je slozeny toggle to same jako zadny detail.
### Pridano
- **Cela adresa vcetne serveru v kazde hlasce.** `ScriptRequestInfo` ma nove
`url` (origin a cesta, bez query - v query muze byt tajemstvi). Do te doby
hlaska rikala jen `/apps/idoklad/account/agenda`, coz nerekne, jestli se to
trefilo na spravny stroj, nebo to zaridla cizi proxy cestou. Zaklad adresy
je z konfigurace a konektor ho smi prepsat, takze se neda odvodit z toho,
kde je nasazeny portal. Adresa je videt i na karte konektoru, v hlavicce
dialogu Logy a v odpovedi na test i kdyz projde (`baseUrl`).
- **Tlacitko Logy na karte konektoru a historie poslednich peti overeni.**
Dosud odpoved sluzby existovala jen v odpovedi na test, tedy do prekresleni
stranky, a v logu containeru. Do logu containeru se nikdo divat nechodi.
Zaznam se uklada i pri uspechu, jinak by neslo poznat, jestli konektor nesel
nikdy, nebo prestal jit ve chvili, kdy nekdo sahnul na udaje.
Migrace `003_connector_checks.sql`, endpoint
`GET /api/dashboard/connectors/:id/checks`.
### Nedoreseno
Proc iDoklad vraci 403, zatim nevime. Vylouceno je to, co posilame: zadna
kombinace hlavicek (`Idempotency-Key`, `Accept`, User-Agent) 403 nevyvola,
sluzba na ne odpovida 401 jako na cokoliv jineho. Zbyva **zdrojova IP adresa
naseho containeru** nebo **403 od iDokladu samotneho**, ktere sluzba jen
predava dal. Rozhodne to telo te odpovedi, ktere je nove v portalu pod Logy.
Sonda na `/health` vedle overeni byla spatny napad a je pryc: `/health`
povoleni IP adresy nevyzaduje, takze z toho, ze projde, o IP nic neplyne.
## 2026-08-20 - vystup z vetve plati i za podminkou
Pri stavbe cesty "objednavka -> faktura" vyslo najevo, ze se bezny postup neda