Tryb raportowy
Tryb raportowy służy do pobierania dużych wolumenów danych analitycznych, poza modelem transakcyjnym trybu żądaniowego. Integrator zleca wygenerowanie raportu, a wynik trafia asynchronicznie do repozytorium raportów należącego do integratora.
Charakterystyka
- Tysiące danych analitycznych — wolumeny nieadekwatne dla synchronicznego trybu żądaniowego.
- W pełni asynchroniczne działanie — zlecenie zwraca
202 Acceptednatychmiast, generowanie odbywa się w tle. - Szyfrowanie kluczem integracyjnym — wynik szyfrowany end-to-end kluczem publicznym integratora (RSA/AES-GCM), zob. Szyfrowanie.
- Konfigurowalny cel dostarczenia — wynik trafia do magazynu docelowego wskazanego w zleceniu (pole
storage, rodzaj =storage.type): m.in. magazyn obiektowy (Azure Blob Storage), endpoint HTTP integratora (POST), katalog czy udział SMB. W każdym przypadku dane lądują po stronie integratora, nie w infrastrukturze KAMSOFT — KAMSOFT nie przechowuje kopii wyniku. Szczegóły: Cel dostarczenia raportu.
Przepływ informacji
flowchart LR
I["Aplikacja integratora"]:::integrator -- "Zlecenie" --> A["API.ERP"]:::api
A <--> D1["FK"]:::domain
A <--> D2["WMS"]:::domain
A <--> D3["HR"]:::domain
A -- "Raport — zapis obiektu" --> R["Magazyn obiektowy"]:::repo
R -. "odczyt / powiadomienie" .-> I
A -- "Raport — POST bezpośrednio" --> I
classDef integrator fill:#8BC34A,stroke:#558B2F,color:#000
classDef api fill:#03A9F4,stroke:#0277BD,color:#000
classDef domain fill:#FFA000,stroke:#E65100,color:#000
classDef repo fill:#FFFFFF,stroke:#333,color:#000
Sekwencja przetworzenia jednego zlecenia raportu:
sequenceDiagram
participant I as Aplikacja integratora
participant A as API.ERP
participant D as Systemy dziedzinowe (FK / WMS / HR / ESM)
participant R as Repozytorium raportów (integratora)
I->>A: Zlecenie (POST /v1/reports)
A-->>I: 202 Accepted + encryptedSessionKey
A->>D: Pobranie i agregacja danych źródłowych
D-->>A: Dane źródłowe
A->>A: Szyfrowanie wyniku (AES-256-GCM + RSA-OAEP)
alt Magazyn obiektowy
A->>R: Zapis zaszyfrowanego artefaktu
R-->>I: Powiadomienie (zdarzenie magazynu / odczyt po runAt)
else Endpoint HTTP
A->>I: POST — zaszyfrowany artefakt
I-->>A: 2xx (potwierdzenie odbioru)
end
Krok Powiadomienie (magazyn → integrator) odpowiada zdarzeniu gotowości pliku w magazynie integratora (np. zdarzenie Blob Storage po stronie integratora) — API.ERP nie wysyła dodatkowego callbacku; integrator sam nasłuchuje na swoim repozytorium lub odpytuje je po czasie wynikającym z runAt. W wariancie endpoint HTTP potwierdzeniem jest sam kod odpowiedzi 2xx (patrz niżej). Pełny opis zlecenia, szyfrowania i odszyfrowania wyniku: Raporty retrospektywne.
Cel dostarczenia raportu
Cel (magazyn docelowy) wskazuje się per żądanie, w polu storage zlecenia POST /v1/reports; storage.type wybiera rodzaj celu, a pole połączenia zależy od typu. Tryb raportowy obsługuje wszystkie typy — blob, http, local, smb — wg wspólnego modelu: Cel dostarczenia (storage.type). Dane są szyfrowane end-to-end kluczem integratora przed dostarczeniem, a dostarczany artefakt jest identyczny niezależnie od typu (bez osobnego manifestu; tożsamość raportu niesie nazwa pliku). Poniżej dwa najczęstsze warianty.
Magazyn obiektowy (Blob Storage)
API.ERP zapisuje zaszyfrowany artefakt raportu do kontenera wskazanego przez integratora, jako obiekt o nazwie {executionId}-{reportId}.{format} (tożsamość raportu niesie nazwa obiektu). Integrator konsumuje pliki asynchronicznie (nasłuch zdarzeń magazynu lub odczyt po runAt). To dotychczasowy, domyślny tryb.
Cel wskazuje się w polu storage zlecenia (POST /v1/reports):
{
"storage": {
"type": "blob",
"connectionString": "BlobEndpoint=https://<account>.blob.core.windows.net/;SharedAccessSignature=..."
}
}
Magazyn jest własnością integratora — KAMSOFT zapisuje do niego zaszyfrowany artefakt i nie przechowuje kopii wyniku.
Endpoint HTTP
Zamiast zapisu do magazynu, API.ERP wysyła wynik pojedynczym żądaniem HTTP POST na adres wskazany przez integratora. Jedno wywołanie = jeden gotowy raport.
Cel wskazuje się w polu storage zlecenia — z type: "http". Adres (i opcjonalny statyczny nagłówek Authorization) przekazuje się w connectionString, spójnie z pozostałymi typami:
{
"storage": {
"type": "http",
"connectionString": "https://integrator.example.com/api-erp/report"
// albo z nagłówkiem: "Url=https://integrator.example.com/api-erp/report;Authorization=<schemat> <wartość>"
}
}
Uwierzytelnianie a odroczony runAt
W trybie raportowym API.ERP przekazuje wyłącznie statyczny nagłówek Authorization podany w connectionString — nie generuje ani nie odświeża tokenów w chwili dostarczenia. Ponieważ raport bywa planowany na przyszłość (runAt nawet za kilka dni), token krótkotrwały (Bearer/JWT) się nie nadaje — wygaśnie przed dostarczeniem. Użyj poświadczenia ważnego w chwili dostarczenia (np. długoterminowy klucz/API key po stronie odbiorcy) albo endpointu niewymagającego tokenu czasowego. Uwierzytelnianie generowane przy wysyłce jest dostępne w trybie notyfikacyjnym/rozgłoszeniowym, a nie w raportowym.
- Metoda i adres:
POSTna jeden, stały URL integratora (zstorage.connectionString). - Body: zaszyfrowany artefakt raportu (ten sam ładunek, który trafiłby do magazynu — AES-256-GCM, klucz sesyjny zaszyfrowany RSA-OAEP kluczem publicznym integratora).
Content-Type: application/octet-stream. - Nagłówki żądania:
Authorization— statyczny nagłówek przekazywany bez zmian zstorage.connectionString(dowolny schemat); musi być ważny w chwili dostarczenia wgrunAt— zob. ostrzeżenie wyżej (token krótkotrwały się nie nadaje);ks-report-execution-id— identyfikator wykonania (executionId); klucz idempotencji i powiązania ze zleceniem (202 Accepted);ks-report-file— nazwa/tożsamość artefaktu ({executionId}-{reportId}.{format}) — odpowiednik nazwy obiektu w magazynie.
- Manifest nie jest wysyłany — spójnie z magazynem obiektowym (Blob), gdzie również zapisywany jest wyłącznie artefakt; tożsamość raportu niesie nazwa pliku.
- Odpowiedź: endpoint musi zwrócić 2xx dla powodzenia. Kod inny niż 2xx, brak połączenia lub przekroczenie czasu = niepowodzenie i ponowienie wg polityki retry; treść body błędu jest odczytywana i logowana po stronie API.ERP. Po wyczerpaniu prób zlecenie trafia do obsługi błędów (dead-letter) — zasady wspólne dla trybów wychodzących: Cel dostarczenia → Dostarczanie, ponawianie, idempotencja.
- Idempotencja: ponowienie oznacza, że integrator może otrzymać ten sam raport więcej niż raz — odbiorca rozróżnia duplikaty po
ks-report-execution-idi nie dubluje skutków.
Zarys żądania:
POST /receiveReport HTTP/1.1
Authorization: ApiKey <długoterminowy-klucz>
Content-Type: application/octet-stream
ks-report-execution-id: 8f3c1a20-...-e065
ks-report-file: 8f3c1a20-...-e065-cost-calculation-2026-07.csv
<zaszyfrowany artefakt raportu (bajty)>
Odbiorca odszyfrowuje artefakt kluczem prywatnym odpowiadającym PublicKeyPem przekazanemu w zleceniu (patrz Raporty retrospektywne).
Pełny kontrakt endpointu odbiorczego w formacie OpenAPI 3.0: API-ERP-Report-Receiver.yaml.
Ten sam wynik, różne cele
Wszystkie rodzaje celu (storage.type) to warianty tego samego dostarczenia — dostarczany artefakt jest identyczny niezależnie od typu (bez osobnego manifestu; tożsamość raportu niesie nazwa pliku). Cel wskazuje się w zleceniu polem storage (rodzaj = type, dane połączenia zależne od typu); zestaw dostępnych typów bywa ograniczany ustaleniami integracji.
Kiedy używać
Tryb raportowy pasuje do eksportów analitycznych, zestawień okresowych i danych o wolumenie zbyt dużym dla pojedynczej odpowiedzi HTTP w trybie żądaniowym — np. raporty kalkulacji kosztów, dane do systemów ankietowania czy badań klinicznych, gdzie kluczowe są przewidywalne okna czasowe (runAt) i szyfrowanie end-to-end, a nie natychmiastowa reakcja na pojedyncze zdarzenie (do tego służy tryb rozgłoszeniowy).