Kontrola vsech 180 operaci proti falesnemu iDoklad API a round trip 331 modelu SDK v obou smerech. - SdkNullablePropertyConverter doplnuje cteni NullableProperty<T>. Konvertor SDK umi jen zapis, takze PATCH s takovou polozkou koncil prazdnou 500 uz pri cteni tela. Tykalo se 29 modelu. Zapis zustava na konvertoru SDK, odchozi payload se nemeni. - Datum uvnitr NullableProperty se normalizuje na UTC stejne jako zbytek serializace. - ListModifiers parsuje datum ve filtru s AdjustToUniversal a AssumeUniversal. Filtr se zonou se drive posouval o offset. - POST /attachments kontroluje FileName a FileBytes, SDK na ne sahalo bez kontroly na null a vracelo neosetrenou 500. - ExceptionHandlingMiddleware ma posledni zachyt, zadny request uz nekonci prazdnou 500. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
73 lines
3.8 KiB
Markdown
73 lines
3.8 KiB
Markdown
# Revize všech endpointů po opravě datumů
|
|
|
|
Kontrola navazuje na [datumy-utc.md](datumy-utc.md). Cílem bylo najít další místa se stejnou
|
|
povahou chyby, tedy vstup, který služba přijme, ale SDK nebo iDoklad ho odmítne, případně
|
|
tichý posun hodnoty.
|
|
|
|
## Jak se to ověřovalo
|
|
|
|
1. Reflexní round trip všech 331 modelů SDK (Post, Patch, Get) přesně tím nastavením
|
|
serializace, které používá služba: serializace odpovědi i deserializace requestu.
|
|
2. Běh služby proti falešnému iDoklad API, které zachytává odchozí requesty. Projeto všech
|
|
180 operací z OpenAPI dokumentu a zkontrolováno, co se skutečně odesílá.
|
|
3. Porovnání klienta `iDoklad.cs` proti OpenAPI dokumentu služby, cesta i HTTP metoda.
|
|
|
|
## Nálezy a opravy
|
|
|
|
### 1. PATCH padal na NullableProperty (vážné)
|
|
|
|
Patch modely používají `NullableProperty<T>`, aby šlo odlišit nevyplněnou položku od položky
|
|
nastavené na null. Konvertor SDK `NullablePropertyJsonConverter` umí jen zápis, jeho `ReadJson`
|
|
vyhazuje `NotImplementedException`, protože SDK Patch modely nikdy nedeserializuje. Tato služba
|
|
je deserializovat musí, takže PATCH s takovou položkou skončil prázdnou 500 už při čtení těla.
|
|
|
|
Týkalo se to 29 modelů, mimo jiné `IssuedInvoicePatchModel`, `ReceivedInvoicePatchModel`,
|
|
`ProformaInvoicePatchModel`, `ContactPatchModel` a `CreditNotePatchModel`. Endpoint spadl podle
|
|
toho, které položky klient poslal, takže se chyba projevovala nepravidelně.
|
|
|
|
Oprava: `Infrastructure/SdkNullablePropertyConverter.cs` čtení doplňuje, zápis nechává na
|
|
konvertoru SDK, takže odchozí payload se nemění. Zaregistrováno v `SdkContractResolver`.
|
|
|
|
Ověřeno, že sémantika zůstává správná: položka vynechaná v těle requestu se do iDokladu
|
|
neodešle. PATCH tedy nepřepisuje pole, která klient neuvedl.
|
|
|
|
### 2. Datum uvnitř NullableProperty nebylo v UTC
|
|
|
|
Když je na položce konvertor, Newtonsoft předá hodnotu jako řetězec a `DateTimeZoneHandling`
|
|
se na ni neuplatní. Datum uvnitř `NullableProperty<DateTime>` proto zůstávalo `Unspecified`
|
|
a narazilo by na stejnou kontrolu SDK jako u vydaných faktur. Konvertor hodnotu normalizuje
|
|
stejným pravidlem jako zbytek serializace.
|
|
|
|
### 3. Filtr s časovou zónou posouval čas (tiché)
|
|
|
|
`Client/ListModifiers.cs` parsoval datum ve filtru bez příznaků zóny. Filtr
|
|
`(DateOfTaxing~gte~2024-01-01T00:00:00Z)` se do iDokladu odeslal jako `2024-01-01 01:00:00`,
|
|
tedy posunutý o hodinu, a `+02:00` se posunulo o dvě. Chyba nic nenahlásila, jen vracela jiná
|
|
data. Opraveno na `AdjustToUniversal | AssumeUniversal`.
|
|
|
|
### 4. POST /attachments vracel prázdnou 500
|
|
|
|
`AttachmentUploadModel` nemá žádné validační atributy a SDK sahá na jméno souboru bez kontroly
|
|
na null. Chybějící `FileName` nebo `FileBytes` tedy skončily neošetřenou `NullReferenceException`.
|
|
Doplněna kontrola v `IntegrationController`, chybějící pole nyní vrací 400.
|
|
|
|
### 5. Poslední záchyt v middleware
|
|
|
|
`ExceptionHandlingMiddleware` má nově i `catch (Exception)`. Neočekávaná chyba se zaloguje
|
|
a vrátí jako 400 nebo 500 s typem výjimky v těle. Žádný request už nekončí prázdnou 500,
|
|
ze které nebylo poznat vůbec nic.
|
|
|
|
## Co bylo v pořádku
|
|
|
|
- Query parametr `lastCheck` u `GET /system/code-books/changes`. Binder MVC normalizuje
|
|
hodnotu na UTC správně, `Z` i offset i tvar bez zóny dávají správný okamžik.
|
|
- Serializace odpovědí. Round trip 331 modelů proběhl bez chyby v obou směrech.
|
|
- Klient `iDoklad.cs`. Ze 177 rozpoznaných volání neodpovídá službě ani jedno špatnou cestou
|
|
nebo metodou.
|
|
|
|
## Výsledek
|
|
|
|
Všech 180 operací proti falešnému iDoklad API: 125 vrátilo 200, 55 vrátilo 400 kvůli
|
|
záměrně neúplnému testovacímu tělu, žádná nevrátila 5xx. Původní tělo z logu klienta,
|
|
které chybu odstartovalo, projde a do iDokladu odejde se správnými datumy.
|