← Indeks

BDO bez BDO: rejestrowanie odbioru odpadów bez zgadywania statusu

Projekt w budowie, nie zlecenie klienckie: własny system do odbioru odpadów, oddzielony od integracji z rządowym BDO.

Wpis oznaczony jako w budowie. To nie jest zlecenie dla klienta, tylko własny projekt, który rozwijam etapami (kolejne wersje demo widać w historii commitów). Poniżej opisuję stan, do którego doszedł na teraz.

Warsztat samochodowy, myjnia, mały zakład produkcyjny - każdy z nich ma obowiązek rejestrować odbiór odpadów w rządowym systemie BDO (Baza Danych o Odpadach). W praktyce sprowadza się to do pilnowania kart przekazania, statusów i mas odpadu, ręcznie, w przeglądarce, często pod koniec dnia, kiedy już nikt nie pamięta szczegółów.

Punkt wyjścia

Chciałem sprawdzić, czy da się zbudować warstwę nad BDO, która pokazuje właścicielowi firmy tylko to, co ma do zrobienia dzisiaj, zamiast surowych ekranów rządowego systemu. Problem nie był w samym CRUD-zie, tylko w tym, że BDO jest zewnętrznym źródłem prawdy, które może się mylić, spóźniać albo zwracać status, którego aplikacja jeszcze nie zna.

Nie chciałem, żeby błąd integracji albo nieznany status z BDO po cichu pokazywał zielony ekran "wszystko gra". To musiało się dać rozróżnić: czy dane są świeże, czy aplikacja tylko zgaduje.

Co zrobiłem

Rozdzieliłem stan odbioru odpadu od stanu integracji z BDO. Własny model domenowy (Pickup) nie wie nic o typach ani statusach BDO - dostaje gotowe zdarzenie domenowe od warstwy pośredniej, która najpierw zapisuje surowy, niezmienny odczyt z zewnątrz, potem dopiero tłumaczy go na coś, co rozumie reszta aplikacji:

BdoGateway -> ExternalPickupSnapshot -> ExternalSnapshot -> SyncService
                                                  -> ReconciliationService -> Pickup

Dzięki temu snapshot bez rozpoznanego mapowania nie psuje lokalnego stanu, tylko trafia do kolejki "wymaga uwagi" (AttentionItem) zamiast być zgadywany. Ten sam mechanizm obsługuje rozbieżność masy po odbiorze: jeśli waga zgłoszona przez kierowcę różni się od tej zapisanej w BDO, aplikacja nie wybiera sama, tylko czeka na decyzję człowieka.

panel "dzisiaj", karta z rozbieżnością masy 180 kg -> 187 kg
Widok startowy: co wymaga decyzji, zanim cokolwiek innego

Do testów jest MockBdoGateway, który symuluje zdarzenia z BDO bez dotykania prawdziwego systemu. RealBdoGateway na sandboksie rządowego BDO działa tylko do odczytu, poza jedną, celowo ograniczoną operacją tworzenia planowanej karty przekazania. Każde pole, którego nazwa sugeruje token, sekret czy nagłówek autoryzacji, jest redagowane, zanim trafi do logu albo audytu.

Czego świadomie nie zrobiłem

Bez harmonogramu automatycznych operacji zapisu do BDO - to zbyt ryzykowne przy systemie rządowym, na którym firma odpowiada prawnie za treść zgłoszeń. Synchronizacja jest ręczna, jedno kliknięcie, jeden odczyt na raz, celowo serializowany, żeby nie było dwóch równoległych prób zapisu tego samego stanu.

Bez zgadywania nieznanych statusów BDO. Gdy integracja zwróci coś, czego mapper nie rozpoznaje, aplikacja mówi to wprost zamiast pokazywać fałszywy zielony status.

Stan obecny

Backend (FastAPI) i frontend (React) działają razem w publicznym demo, z danymi przykładowymi, bez połączenia z prawdziwym BDO. Migracje idą przez Alembic, z rozpoznawaniem nieznanego schematu bazy - baza, której nie da się jednoznacznie rozpoznać, jest odrzucana, nie zgadywana. Reszta, czyli realny sandbox BDO i pełne raportowanie, jest w trakcie.