Wdrożenie KSeF przestaje być projektem integracyjnym w momencie, w którym faktura okazuje się nie plikiem, a zdarzeniem prawnym z numerem i datą nadanymi poza naszym systemem. Schema FA(3) jest najłatwiejszą częścią pracy. Trudne jest to, co następuje po odebraniu dokumentu: ustalenie, czy widzieliśmy go już wcześniej, czy wolno go zaksięgować i kto odpowiada za skutek tej decyzji.
Faktura jest zdarzeniem, nie plikiem
Plany wdrożenia opisują KSeF jako kanał wymiany: wystawiamy XML, wysyłamy, odbieramy. Opis jest poprawny i prawie bezużyteczny, bo pomija to, co zmienia się w modelu danych. Dokument potwierdzony przez system centralny istnieje w obiegu prawnym niezależnie od stanu naszej aplikacji. Nie ma wersji roboczej, nie ma cofnięcia, nie ma „poprawimy przy zamknięciu miesiąca". System księgowy przestaje być właścicielem faktury i staje się jej odbiorcą, który musi umieć udowodnić, co z nią zrobił i kiedy.
To zmienia trzy rzeczy naraz. Pobieranie przestaje być jednym zadaniem cyklicznym, bo strumień jest per NIP, każdy podmiot ma własny stan, własny znacznik postępu i własny zakres uprawnień; u nas obsługa wielu podmiotów opiera się na Row-Level Security w PostgreSQL i regułach ABAC per NIP, a nie na filtrze w zapytaniu aplikacyjnym. Model dokumentu przestaje być wewnętrzną sprawą, bo jego kształt narzuca XSD, którego nie negocjujemy. A ślad audytowy przestaje być logiem diagnostycznym: prowadzimy go jako łańcuch skrótów SHA-256 tylko do dopisywania, z triggerem bazodanowym blokującym UPDATE i DELETE, bo w sporze z organem znaczenie ma nie to, co system pokazuje dziś, lecz to, czego nie mógł zmienić.
Dlaczego deduplikacja jest wymogiem, a nie optymalizacją
W typowej integracji deduplikacja pojawia się w backlogu jako usprawnienie: mniej pracy, mniej hałasu. Przy fakturach ustrukturyzowanych jest odwrotnie, to warunek poprawności księgi. Pobieranie z systemu centralnego jest operacją sieciową, więc będzie się powtarzać: po timeoucie, po restarcie procesu, po ręcznym ponowieniu przez operatora, po zmianie zakresu dat. Jeśli ta sama faktura wejdzie dwukrotnie, efektem nie jest zdublowany rekord w tabeli, ale zdublowany koszt w rozliczeniu i deklaracja, której nie da się obronić.
Dlatego przyjmujemy, że pobranie jest idempotentne z założenia, a nie w wyniku ostrożności operatora. Tożsamość dokumentu bierze się z numeru KSeF, nie z nazwy pliku ani z pary numer plus kontrahent. Ponowne przetworzenie tego samego dokumentu jest legalną, oczekiwaną operacją bez efektu ubocznego. Import jest transakcyjny: dokument albo istnieje w księgach w całości, albo nie istnieje wcale, bo stan częściowy jest tu gorszy niż brak stanu. Ta sama zasada dotyczy generowania JPK_V7M(3), deklaracja odtworzona z tych samych danych musi być identyczna, inaczej nie mamy generatora, tylko kolejne źródło rozbieżności.
Idempotencja jest też jedynym mechanizmem, który pozwala bezpiecznie ponawiać komunikację z bramką MF. Kanał REST z szyfrowaniem AES i RSA zachowuje się jak każdy inny kanał zdalny: czasem odpowiada wolno, czasem nie odpowiada wcale, a brak odpowiedzi nie znaczy, że operacja się nie wykonała. System, który tego nie zakłada, na produkcji rozstrzyga tę niepewność ręcznie, w piątek po południu.
Co robi bramka zgodności i dlaczego parser jest jej częścią
Między odebraniem dokumentu a jego zaksięgowaniem umieściliśmy bramkę, przez którą nic nie przechodzi bez sprawdzenia. Wykonuje walidację XSD wobec schemy FA(3), kontrolę sumy kontrolnej NIP (mod 11), sprawdzenie kontrahenta na białej liście KAS, rozpoznanie przypadków mechanizmu podzielonej płatności i deduplikację. Każde z tych sprawdzeń istnieje, bo jego brak ma konkretny koszt: odliczenie zakwestionowane z powodu numeru rachunku spoza wykazu, płatność wykonana bez MPP tam, gdzie był obowiązkowy, korekta deklaracji z powodu dokumentu policzonego dwa razy.
Parser XML jest częścią tej samej bramki, nie warstwą poniżej. Dokument przychodzi ze źródła, którego nie kontrolujemy, a XML jest formatem z historią: encje zewnętrzne, rozwijanie encji, odwołania do zasobów lokalnych. Parser skonfigurowany domyślnie potrafi przy odpowiednio przygotowanym pliku przeczytać plik z dysku serwera albo wykonać żądanie sieciowe z jego wnętrza. Używamy więc parsera odpornego na XXE na poziomie biblioteki (defusedxml), a nie zapisu w polityce bezpieczeństwa, że „nie przetwarzamy niezaufanych plików". Ta sama logika dotyczy załączników: skan antywirusowy działa fail-closed, więc plik nieprzeskanowany jest plikiem odrzuconym, a nie plikiem przyjętym warunkowo. Typy MIME są na liście dozwolonych, nie na liście zakazanych.
Warto zauważyć, kto tu jest adresatem. Żadne z tych sprawdzeń nie chroni przed atakiem ukierunkowanym na organizację. Chronią przed rutyną: przed dokumentem wprowadzonym w pośpiechu, przed ponowieniem po awarii, przed uploadem z komputera, którego nikt nie sprawdzał.
Gdzie kończy się rola modelu
Dekretacja to najbardziej oczywisty kandydat na automatyzację i najgorsze miejsce na pełną automatyzację. W obiegu dokumentów, który utrzymujemy, model podpowiada konto, wymiar kosztowy i przypisanie do projektu, ale wynik jest propozycją, którą zatwierdza człowiek. Nie z powodu ostrożności, lecz z powodu podziału odpowiedzialności: skutek błędnej dekretacji jest podatkowy i ponosi go podatnik, a nie dostawca modelu. Automat, który księguje samodzielnie, nie usuwa tej odpowiedzialności, usuwa tylko moment, w którym ktoś ją świadomie przyjął.
Reszta konstrukcji wynika z tej samej zasady. Przed wysłaniem czegokolwiek do modelu następuje redakcja danych osobowych, bo dokument księgowy zawiera więcej niż kwoty. Routing OCR idzie od modelu tańszego do frontierowego tylko wtedy, gdy pewność odczytu jest niska, bo koszt per dokument jest parametrem projektu, nie ciekawostką. A wszystko, co model zaproponował i co człowiek zatwierdził, zostaje w tym samym łańcuchu audytowym, w którym leżą faktury.
Czego nie da się dokupić
Konektor kupuje się w tygodniach. To realna oszczędność i nie ma powodu jej lekceważyć: transport, autoryzacja, obsługa schemy, ponawianie. Nie kupuje się natomiast trzech rzeczy, a to one decydują o powodzeniu wdrożenia.
Pierwsza to odwzorowanie własnego modelu dokumentów na semantykę FA(3). Schema jest sztywna, a rzeczywistość firmy nie: rabaty, zaliczki, korekty wielopozycyjne, sprzedaż w walutach, usługi rozliczane w cyklach. Każda z tych rzeczy ma poprawne przedstawienie w schemie i kilka niepoprawnych, które przechodzą walidację.
Druga to jakość danych podstawowych. Bramka zgodności nie naprawia rejestru kontrahentów, ona go ujawnia. Wdrożenia rozjeżdżają się nie na integracji, ale na kilkuset rekordach z błędnym NIP-em, zdublowanym kontrahentem i rachunkiem, którego nie ma w wykazie.
Trzecia to decyzja organizacyjna: kto zatwierdza, w jakim czasie, i co się dzieje, gdy nie zatwierdzi. Systemu obiegu nie da się skonfigurować bez odpowiedzi na to pytanie, a odpowiedź nie jest techniczna. Zespoły, które traktują KSeF jako zadanie integracyjne, dochodzą do tego pytania na końcu, kiedy harmonogram jest już wykorzystany na formaty.
Sprawdzalnym testem gotowości nie jest udana wysyłka pierwszej faktury. Jest nim odpowiedź na pytanie, co zrobi system, gdy ta sama faktura przyjdzie po raz drugi, i czy da się pokazać, kto rozstrzygnął, że wolno ją zaksięgować.