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>
3.8 KiB
Revize všech endpointů po opravě datumů
Kontrola navazuje na 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
- 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.
- 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á.
- Porovnání klienta
iDoklad.csproti 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
lastCheckuGET /system/code-books/changes. Binder MVC normalizuje hodnotu na UTC správně,Zi 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.