Pakowanie Kablowo: system magazynowy zbudowany z Claude Code
Case study budowy systemu pakowania dla firmy kablowej. FastAPI + Next.js, integracja BaseLinker, maszyna ESP8266 do kabli, drukarka Zebra. 30% oszczędności czasu.
LiveSales
Setki zamówień dziennie, dwa konta BaseLinker, maszyna do kabli. Jeden system ogarnia wszystko.
“Pakowanie kabli to nie jest standardowy fulfillment. Musisz odmierzyć, nawinąć, oznaczyć. Żaden gotowy WMS tego nie ogarnął. Napisaliśmy swój — i oszczędzamy 30% czasu pakowania dziennie.”
— Właściciel Kablowo, firma kablowa z Allegro/Amazon
Kablowo to firma sprzedająca kable elektryczne, peszle ochronne i akcesoria kablowe na polskich marketplace’ach. Pakowanie kabli jest inne niż pakowanie butów czy elektroniki — trzeba odmierzyć metraż, nawinąć na szpulę lub do pudełka, wydrukować etykietę z kodem MIX, zsynchronizować dwa konta BaseLinker i ogarnąć resztki materiału, które zostają po cięciu.
Żaden gotowy system nie obsługiwał tego workflow. Zbudowaliśmy własny — FastAPI + Next.js + ESP8266 + Zebra printer — i ten artykuł to pełne case study tego procesu.
30% oszczędności czasu
Na pełnej zmianie magazynowej — mierzalne, nie szacunkowe.
2 konta BaseLinker scalone
Pracownik widzi jeden strumień zamówień — system scala w tle.
Maszyna ESP8266
Automatyczne nawijanie i odmierzanie kabla sterowane z aplikacji.
Co sprzedaje Kablowo i dlaczego pakowanie kabli jest inne
Kablowo to firma e-commerce sprzedająca przez Allegro, Amazon PL i Erli. Główne kategorie produktów:
Kable elektryczne
YDYp, YKY, OMY, OWY, przewody instalacyjne. Sprzedawane na metry — klient zamawia 15m, 30m, 100m. Trzeba odmierzyć, nawinąć, oznakować.
Peszle i osłony
Peszle karbowane, rury ochronne, korytkowe. Różne średnice, kolory. Pakowane na sztuki lub metry.
Akcesoria i oleje
Złączki, taśmy izolacyjne, oleje techniczne. Standardowe pakowanie — ale często w zamówieniach mieszanych z kablami.
Dlaczego to nie jest standardowy fulfillment
Firma butów pakuje: weź z półki, włóż do kartonu, naklej etykietę. 60 sekund.
Firma kablowa pakuje:
- Sprawdź zamówienie — czy to kabel, peszle, mix?
- Odmierz metraż na maszynie (15m kabla YDYp 3x2.5)
- Nawiń na szpulę lub włóż do pudełka
- Jeśli zamówienie mieszane — zbierz kable + peszle + akcesoria z różnych stref magazynu
- Wydrukuj etykietę MIX z kodem grupowym
- Sprawdź czy zostały resztki kabla — jeśli tak, zaewidencjonuj
To jest 6 kroków zamiast 3. I każdy wymaga innego narzędzia. Dlatego gotowe WMS-y tego nie obsługują.
Wolumen: setki zamówień dziennie przez dwa oddzielne konta BaseLinker (konto A i B — historyczne powody, dwa osobne sklepy Allegro). Pracownik musi widzieć zamówienia z obu kont jako jeden strumień.
Dlaczego gotowe rozwiązania nie wystarczyły
Problem 1: Dwa konta BaseLinker
BaseLinker nie obsługuje natywnego mergowania zamówień z wielu kont. Pracownik musiał przełączać się między dwoma panelami, co generowało błędy i gubienie zamówień.
Nasze rozwiązanie: Równoległy fetch z obu kont przez asyncio.gather, merge po date_confirmed, zapis do lokalnej bazy z kolumną account (“A”/“B”). Pracownik widzi jeden ekran — system w tle wie, do którego konta odpalić trigger.
Problem 2: Brak widoków pakowania
BaseLinker pokazuje wszystkie zamówienia płasko. Ale w magazynie kablowym masz fizycznie oddzielne strefy: kable (skrętki) leżą gdzie indziej niż peszle, a oleje jeszcze gdzie indziej. Pracownik potrzebuje widoku filtrowanego po strefie produktu.
Nasze rozwiązanie: Cztery widoki pakowania:
- Skrętki — zamówienia zawierające tylko kable
- Peszle — zamówienia zawierające tylko peszle/osłony
- Mix — zamówienia mieszane (kable + peszle + inne)
- Inne — wszystko co nie pasuje do powyższych
Każdy produkt w katalogu BaseLinker ma custom field strefa (np. SKRETKI, PESZLE, OLIWY). System automatycznie kategoryzuje zamówienia na podstawie stref produktów w nich zawartych.
Problem 3: Integracja z maszyną do kabli
Maszyna do nawijania kabli to ESP8266 (mikrokontroler) sterujący silnikiem. Żaden gotowy WMS nie integruje się z custom hardware. Musieliśmy to zbudować od zera.
Problem 4: Etykiety MIX
Zamówienia mieszane wymagają specjalnej etykiety grupowej (kod MIX) wydrukowanej na drukarce Zebra. Pracownik z jednej strefy pakuje kable, z drugiej peszle — etykieta MIX łączy te paczki w jedno zamówienie.
Architektura systemu
Przepływ danych w systemie Pakowanie Kablowo
Stack technologiczny
| Warstwa | Technologia | Dlaczego |
|---|---|---|
| Backend | FastAPI (Python 3.12, async) | Asynchroniczny I/O idealny do parallel fetch z 2 kont BL |
| Frontend | Next.js 16 (React 19, TypeScript) | Server Components + client hydration, shadcn/ui, Tailwind 4 |
| Baza danych | PostgreSQL (SQLAlchemy 2.0 async) | Alembic migracje, auto-migrate on startup |
| Cache | Redis (graceful fallback) | 30s TTL zamówienia, 5min produkty, invalidacja po mutacji |
| Real-time | WebSocket | Broadcast order_updated do wszystkich klientów po każdej mutacji |
| Hardware | ESP8266 via HTTP | Persistent connection pooling, 1s polling, 2s timeout |
| Drukarka | Zebra (ZPL) | Print Agent na Windows PC, headless reprint przez API |
| Skanery | Barcode scanners / telefony | Multi-device picking sync via /api/collected |
Scalanie dwóch kont BaseLinker
Kluczowy element architektury: dwa niezależne konta BaseLinker scalane transparentnie.
┌─────────────────┐ asyncio.gather() ┌─────────────────┐
│ BaseLinker A │ ──────────────────────>│ │
│ (konto główne) │ │ FastAPI │
│ │ │ merge by │ ──> Jedna lista
│ BaseLinker B │ ──────────────────────>│ date_confirmed │ zamówień
│ (konto dodatkowe)│ │ │
└─────────────────┘ └─────────────────┘
Każde zamówienie w bazie ma kolumnę account (“A” lub “B”). Gdy pracownik odpala trigger (np. drukuj spis, drukuj etykietę), system automatycznie wybiera odpowiedniego klienta BaseLinker na podstawie order.account.
Background jobs
Synchronizacja działa w tle bez udziału pracownika:
- Co 5 minut: odświeżanie zamówień z obu kont BL
- Co 60 minut: synchronizacja katalogu produktów
- Raz dziennie: audyt stref (sprawdzenie czy każdy produkt ma przypisaną strefę)
Widoki pakowania — jak pracownik korzysta z systemu
Pracownik magazynu otwiera aplikację na tablecie lub telefonie i widzi cztery zakładki:
Skrętki
Zamówienia zawierające tylko kable. Pracownik przy maszynie do nawijania widzi listę kabli do odmierzenia. Każdy item ma długość w metrach, SKU i strefę.
Peszle
Zamówienia zawierające tylko peszle i osłony. Osobna strefa magazynowa, inny typ pakowania.
Mix
Zamówienia mieszane — kable + peszle + akcesoria. Wymagają etykiety MIX z kodem grupowym. Pracownicy z różnych stref pakują swoje części i łączą je kodem.
Inne
Zamówienia z produktami bez przypisanej strefy lub z kategorii specjalnych. Fallback dla wszystkiego co nie pasuje do 3 głównych widoków.
Flow pakowania krok po kroku
Skanowanie kodu kreskowego
Pracownik skanuje kod EAN produktu skanerem Zebra lub telefonem. System automatycznie zaznacza item jako zebrany (picked).
Odmierzanie na maszynie ESP
Dla kabli: aplikacja wysyła komendę do ESP8266 z metrażem. Maszyna nawija kabel na szpulę lub do pudełka. Automatyczne odliczanie odpadu.
Wybór gabarytu
Pracownik wybiera rozmiar paczki: A (mała), B (średnia), C (duża), 2xC (podwójna). Wpływa na koszt wysyłki.
Trigger: spis + etykieta
Pracownik klika “Spis” i “Etykieta” — system odpala makro w BaseLinker (na właściwym koncie A/B). Drukarka Zebra drukuje etykietę.
Ewidencja resztek
Jeśli po cięciu został kawałek kabla — pracownik rejestruje resztkę w module resztek. System automatycznie dopasowuje ją do kolejnego zamówienia.
Maszyna do nawijania kabli — ESP8266
To jest serce operacji kablowej. ESP8266 to mikrokontroler Wi-Fi za kilkadziesiąt złotych, który steruje silnikiem DC nawijającym kabel.
Co robi maszyna
- Odmierza długość kabla — z dokładnością do 0.1m (encoder na kole)
- Nawija na szpulę (tryb
szpula) lub wkłada do pudełka (trybpudełko) - Automatycznie odejmuje odpad — każde cięcie generuje ~0.5m odpadu (nóż + zapas). System to odlicza
- Hamuje precyzyjnie — rampa prędkości w dół, żeby kabel nie wyskoczył ze szpuli
Endpointy maszyny
| Endpoint | Metoda | Co robi |
|---|---|---|
| /api/esp/status | GET | Status maszyny: IDLE, RUNNING, PAUSED, ERROR. Polling co 1s |
| /api/esp/start | POST | Start cięcia: meters, mode (szpula/pudełko), waste_meters |
| /api/esp/stop | POST | Natychmiastowe zatrzymanie (emergency stop) |
| /api/esp/resume | POST | Wznowienie po zatrzymaniu (dociąga brakujące metry) |
| /api/esp/config | GET/POST | Konfiguracja: PWM speed, ramp up/down, hamulec, watchdog |
Parametry konfiguracji
Maszyna ma kilkanaście parametrów konfiguracyjnych, które admin ustawia przez panel:
- PWM speed — prędkość obrotowa silnika (0-255)
- Ramp up — czas rozruchu (ms) — żeby kabel się nie zerwał przy starcie
- Ramp down — czas hamowania (ms) — precyzyjne zatrzymanie
- Brake mode — typ hamulca: elektroniczny (PWM reverse) lub mechaniczny
- Watchdog — auto-stop po X sekundach bez impulsów encodera (zacięcie kabla)
- Waste offset — stały odpad na cięcie (domyślnie 0.5m)
Persistent connection pooling
ESP8266 to mikrokontroler z ograniczonymi zasobami (80 KB RAM). Każde nowe połączenie TCP to obciążenie. Dlatego nasz backend utrzymuje persistent httpx client z connection poolingiem:
_client = httpx.AsyncClient(
base_url="http://192.168.1.113",
timeout=2.0, # status polling — krótki timeout
limits=httpx.Limits(max_connections=2, max_keepalive_connections=1),
)
Frontend odpytuje status maszyny co 1 sekundę (hook useESP). Dzięki persistent connection nie ma narzutu TCP handshake przy każdym request.
Dodatkowy debounce: 3 kolejne faile zanim system zadeklaruje maszynę jako offline (unika fałszywych alarmów przy chwilowym zacięciu Wi-Fi).
Wykres wydajności
Wydajność maszyny ESP8266 vs ręczne cięcie kabla
Czas w sekundach na 100 metrów kabla
Kluczowy insight: Maszyna ESP eliminuje etap “odmierzania długości” całkowicie — encoder mierzy metry w trakcie nawijania. Ręcznie trzeba odmierzyć, zaznaczyć, dociągnąć. Z maszyną: wpisujesz 15m, klikasz Start, kabel nawija się sam.
Drukarka Zebra i skanery kodów kreskowych
Etykiety ZPL
System generuje etykiety w formacie ZPL (Zebra Programming Language) — format natywny dla drukarek termicznych Zebra. Etykieta 100x150mm (4x6”) zawiera:
Kod MIX (4 znaki)
Generowany automatycznie — łączy paczki z różnych stref w jedno zamówienie. Pracownicy szukają siebie nawzajem po tym kodzie.
Numer zamówienia + pole dodatkowe
ID z BaseLinker + opcjonalny kod pola dodatkowego (custom field).
Lista pozycji
Ilość × nazwa produktu. Dynamiczny font — więcej pozycji = mniejsza czcionka.
Print Agent na Windows
Drukarka Zebra jest podłączona do PC z Windows. Na PC działa Print Agent — mały serwis HTTP, który:
- Przyjmuje komendę ZPL z backendu FastAPI
- Przekazuje ją do drukarki Zebra przez Windows Print API
- Raportuje status (online/offline, kolejka wydruku)
- Auto-restart w razie awarii
Endpointy drukowania:
GET /api/print/mix-label/{order_id}— renderuje etykietę HTML (otwiera print dialog w przeglądarce)POST /api/print/mix-label/{order_id}/headless— drukuje bezpośrednio na Zebrze (headless, bez przeglądarki)GET /api/print/agent-status— health check agentaGET /api/print/agent-printers— lista dostępnych drukarek
Skanery kodów kreskowych i telefon Zebra
Pracownicy magazynu używają skanerów Zebra (handheld) i telefonów z czytnikiem kodów do pickowania zamówień. System multi-device sync (/api/collected) pozwala na:
- Skanowanie kodu EAN produktu → automatyczne zaznaczenie jako “zebrane” (picked)
- Wielourządzeniowy sync — 4 koszyki pickingowe, każdy z własnym skanerem
- Identyfikacja urządzenia/użytkownika — wiadomo kto co zebrał
- Auto-cleanup — po spakowaniu zamówienia, stan zebranych itemów się resetuje
Skan → Pick
Skanuj kod kreskowy produktu. System automatycznie zaznacza pozycję w zamówieniu jako zebraną. Real-time update na ekranach wszystkich pracowników.
Telefon Zebra
Urządzenia Zebra z wbudowanym skanerem i ekranem. Pracownik widzi listę do zebrania + skanuje bezpośrednio. Jedno urządzenie na cały flow.
Integracja z BaseLinker API — jakie zapytania wykonujemy
System komunikuje się z BaseLinker przez custom async client z kolejką priorytetową. Oto dokładna lista metod API, z których korzystamy:
Metody API BaseLinker
| Metoda API | Priorytet | Zastosowanie | Częstotliwość |
|---|---|---|---|
| getOrders | NORMAL | Pobieranie zamówień ze statusem “do pakowania”. Paginacja po 100. | Co 5 min (cron) + na żądanie |
| getInventoryProductsList | LOW | Katalog produktów — nazwy, SKU, EAN, warianty. Paginacja po 100. | Co 60 min (cron) |
| getInventoryProductsData | HIGH | Szczegóły produktu: custom fields (strefa, waga, opakowanie zbiorcze), zdjęcia, warianty. Batch po 100 ID. | Przy sync zamówień |
| getInventoryProductsStock | HIGH | Stany magazynowe — ile sztuk/metrów na stanie w danym magazynie. | Na żądanie (panel admin) |
| addInventoryDocument | CRITICAL | Tworzenie dokumentu magazynowego (przyjęcie/wydanie) w trybie draft. | Przy operacjach stockowych |
| addInventoryDocumentItems | CRITICAL | Dodanie pozycji do dokumentu (produkt, ilość, cena). | Przy operacjach stockowych |
| setInventoryDocumentStatusConfirmed | CRITICAL | Zatwierdzenie dokumentu — dopiero wtedy zmienia się stan magazynowy. | Po dodaniu pozycji |
| runOrderMacroTrigger | CRITICAL | Odpalenie makra na zamówieniu: “spis” (lista pakowania), “etykieta” (label wysyłkowy). | Przy każdym spakowaniu |
| setOrderStatus | CRITICAL | Zmiana statusu zamówienia (np. “do pakowania” → “spakowane”). | Przy zmianie statusu |
| runProductMacroTrigger | CRITICAL | Makro produktowe — aktualizacja danych, zdjęć, cen w katalogu. | Na żądanie (admin) |
| updateInventoryProductsStock | CRITICAL | Korekta stanów magazynowych (set_stock). Używane po mini-inwentaryzacji i operacjach stockowych. | Przy korekcie stanu |
| getInventoryDocuments | NORMAL | Lista dokumentów magazynowych (przyjęcia, wydania, korekty) z filtrami po typie i dacie. | Panel admin |
System priorytetów i rate limiting
Nasz BaseLinker client to nie jest zwykły wrapper na requests.post(). To asynchroniczny klient z kolejką priorytetową:
Rate limiter
30 zapytań / 60 sekund (sliding window) per konto. BaseLinker zwraca HTTP 429 przy przekroczeniu — nasz client automatycznie czeka i retry z exponential backoff (1s → 2s → 4s, max 3 próby).
Auto-retry
Retry tylko dla 429 (rate limit) i 5xx (server error). Błędy logiczne (400, 404) nigdy nie są retryowane — to by maskowało bugi.
Timeout
60 sekund na jedno zapytanie. BaseLinker bywa wolny przy dużych batchach (500+ zamówień) — krótszy timeout powodował fałszywe faile.
Dynamic trigger engine
Trigger ID nie są hardcoded w kodzie. Są w zmiennej środowiskowej jako JSON:
ACCOUNT_A_TRIGGERS={"skretki.spis":44364, "skretki.etykieta":44365, "mix.spis":44366, "mix.etykieta":44367}
GET /api/triggers/available skanuje JSON dict po prefixie widoku. Dodanie nowego triggera = edycja zmiennej + restart. Zero zmian w kodzie.
Wykres oszczędności czasu pakowania
Czas pakowania 20 zamówień: ręcznie vs z aplikacją
Porównanie w minutach — realne dane z magazynu Kablowo
Co dokładnie oszczędzamy
Skrętki (kable): Największa oszczędność — maszyna ESP eliminuje ręczne odmierzanie. Zamiast mierzyć, zaznaczać, ciągnąć kabel — pracownik wpisuje metraż i klika Start.
Mix (zamówienia mieszane): Etykiety MIX z automatycznym kodem grupowym eliminują szukanie siebie nawzajem po magazynie. Pracownik z jednej strefy widzi kod “AB7K”, pracownik z drugiej strefy szuka tego samego kodu — i łączą paczki.
Picking (zbieranie): Skanery kodów kreskowych eliminują ręczne sprawdzanie listy. Skan → pick → następny. Bez czytania nazw i porównywania.
Etykietowanie Zebra: Headless printing eliminuje przełączanie okien, szukanie drukarki, formatowanie. Klik → etykieta na Zebrze. 5 sekund.
Łącznie: ~39% oszczędności czasu na pełnej zmianie pakowania (20 zamówień per batch). Na skali miesiąca to kilkadziesiąt godzin roboczych.
Zdjęcia i dokumentacja pakowania
System posiada pełny moduł mediów do dokumentacji operacji magazynowych:
Zdjęcia w checklistach
Każdy krok checklisty może wymagać zdjęcia jako dowodu wykonania. Max 10 MB per zdjęcie.
Video dokumentacja
Nagrania wideo procesu pakowania lub odbioru transportu. Max 50 MB per video.
Media transportowe
Zdjęcia załadunków, pojazdów, dowodów dostawy. Powiązane z konkretnymi kursami.
Pliki organizowane są automatycznie: YYYY/MM/DD/{uuid}-{oryginalna_nazwa}. UUID zapewnia unikalność, oryginalna nazwa pozwala na identyfikację. Każdy plik ma tracking: kto uploadował, kiedy, jaki typ MIME.
Struktura wewnętrznego API
Cały backend to FastAPI z czystym podziałem na warstwy: Router (HTTP) → Service (logika) → Repository (baza danych).
Drzewo endpointów
Format odpowiedzi
Każdy endpoint zwraca ustandaryzowany JSON:
{
"status": "SUCCESS",
"data": { ... },
"count": 42
}
Lub w przypadku błędu:
{
"status": "ERROR",
"detail": "Order not found",
"error_code": "ERR_NOT_FOUND"
}
Pełna dokumentacja Swagger
Wygenerowaliśmy pełną dokumentację API w formacie OpenAPI 3.0, dostępną jako interaktywny Swagger UI: Dokumentacja API Pakowanie Kablowo.
Swagger zawiera wszystkie endpointy, schematy request/response, kody błędów i przykłady. Dokumentacja jest standalone — nie jest podpięta do produkcyjnego backendu.
Podsumowanie
Kluczowe metryki
Powiązane artykuły
Ten system to nie tylko jeden monolit — składa się z kilku wyspecjalizowanych modułów. Każdy z nich ma swój osobny artykuł:
Moduł resztek kablowych
Auto-matching resztek do zamówień. Rezerwacja, zużycie, oszczędności materiałowe.
Konfiguracja magazynu
Regały, półki, strefy, mapowanie produktów i quiz lokalizacji dla pracowników.
Checklisty i kontrola jakości
Szablony kontroli, protokoły wydania, upload zdjęć i video jako dowody.
Cały system zbudowaliśmy z Claude Code w kilka tygodni. ROI zwrócił się w pierwszym miesiącu — głównie dzięki oszczędności czasu pakowania i redukcji strat materiałowych na resztkach kablowych.
Zainteresowany automatyzacją danych?
LiveSales pomoże Ci zaoszczędzić czas i podejmować lepsze decyzje biznesowe dzięki automatycznym raportom i dashboardom.
Skontaktuj się z namiPodobał Ci się ten artykuł?
Subskrybuj, aby dostawać powiadomienia o nowych artykułach.
Bez spamu. Możesz się wypisać w każdej chwili.
Przeczytaj również
Resztki kablowe: moduł automatycznego dopasowania do zamówień
Jak zarządzać resztkami kabli w magazynie e-commerce. Auto-matching do zamówień, rezerwacja, zużycie częściowe. Moduł resztek w systemie Pakowanie Kablowo.
Checklisty: kontrola jakości i protokoły wydania przesyłek
Moduł checklist w systemie Pakowanie Kablowo. Szablony kontroli jakości, protokoły wydania przewoźnikom, upload zdjęć i video, historia wykonania.
Ekosystem narzędzi: gdy sprzedaż, magazyn i Allegro Ads rozmawiają
Jak połączyliśmy narzędzie Allegro Ads z magazynem i działem sprzedaży. Magazyn wie co się sprzedaje, sprzedaż wie co na stanie — lepsze decyzje.