Files
orderPRO/.paul/phases/127-polkurier-integration-foundation/127-01-SUMMARY.md
Jacek Pyziak 3443879f59 feat(127): polkurier integration foundation
Single-instance globalna konfiguracja polkurier.pl jako alternatywa
dla Apaczki: szyfrowany login + Token API, karta w hubie integracji
i realny test polaczenia przez apimetod=test_auth_api zweryfikowany
na zywym koncie operatora (Autoryzacja: 1).

ShipmentProviderRegistry netkniety - PolkurierShipmentService/
TrackingService w kolejnych fazach.

Kluczowe ustalenia kontraktu API (z SDK polkurier-sdk):
- POST https://api.polkurier.pl/ (jeden endpoint)
- JSON body: {authorization:{login,token}, apimetod, data}
- Sukces: top-level status === 'success' (nie 'ok')
- Blad: tresc w polu 'response' envelope'a
- Content-Type: application/json (strict, bez charset suffix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:43:11 +02:00

14 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, started, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration started completed
127-polkurier-integration-foundation 01 integrations
polkurier
courier
shipment-broker
settings
integration-hub
php
phase provides
116-hostedsms-integration-settings single-instance integration repository pattern (IntegrationsRepository::ensureIntegration + updateTestResult + IntegrationSecretCipher)
phase provides
120-alert-component-unification resources/views/components/alert.php contract for all settings views
polkurier_integration_settings DB table (single-instance, fixed id=1)
PolkurierIntegrationRepository (login + Token API, AES-encrypted)
PolkurierApiClient with verified live test connection against apimetod=test_auth_api
/settings/integrations/polkurier UI (form + Testuj polaczenie) + hub row
Foundation for future PolkurierShipmentService / PolkurierTrackingService
future polkurier-shipment-service phase (uses getCredentials + verified API client contract)
future polkurier-tracking-service phase (delivery_status_mappings provider='polkurier')
added patterns
single-instance integration ctor (PDO $pdo, string $secret) mirror HostedSMS/SMSPLANET
polkurier API contract
POST https://api.polkurier.pl/, JSON body {authorization:{login,token}, apimetod, data:{platform, platform_version}}, success when top-level status='success'
error path
payload from "response" field of envelope (string or struct) — mirror SDK ErrorException($response->get('response'))
strict Content-Type
application/json (no charset suffix — polkurier rejects)
created modified
database/migrations/20260514_000114_create_polkurier_integration_settings.sql
src/Modules/Settings/PolkurierIntegrationRepository.php
src/Modules/Settings/PolkurierApiClient.php
src/Modules/Settings/PolkurierIntegrationController.php
resources/views/settings/polkurier.php
routes/web.php
src/Modules/Settings/IntegrationsHubController.php
resources/lang/pl.php
.paul/codebase/db_schema.md
.paul/codebase/architecture.md
.paul/codebase/tech_changelog.md
polkurier startuje jako single-instance globalna konfiguracja (mirror Apaczka/HostedSMS/SMSPLANET) — operator ma jedno konto polkurier
polkurier dziala obok Apaczki — ShipmentProviderRegistry netkniety; oba dostawcy zyja niezaleznie
API polkuriera wymaga login + token w body authorization (zweryfikowane w SDK polkurier-sdk); kolumna login dodana mimo ze PLAN AC-1 jej nie wymagal
Brak kolumny environment ENUM — polkurier ma jeden produkcyjny endpoint, sandbox nie istnieje
Test polaczenia uzywa apimetod=test_auth_api (nie tworzy przesylki, nie kosztuje); sukces gdy top-level status='success'
Content-Type MUSI byc dokladnie 'application/json' — polkurier odrzuca '; charset=UTF-8' suffix
polkurier API client: jeden POST endpoint, ResponseStatus::SUCCESS='success', tresc bledu w polu 'response' envelope'a — wzorzec dla wszystkich przyszlych metod (createShipment, getLabel, getStatus, cancelOrder, AvailableCarriers, etc.)
Strict Content-Type bez charset suffix — pattern do reuse w innych integracjach jezeli odrzucaja parametry
~45min 2026-05-14T19:00:00Z 2026-05-14T19:45:00Z

Phase 127 Plan 01: polkurier Integration Foundation — Summary

polkurier.pl broker kurierski dostepny jako alternatywa dla Apaczki: pojedyncza globalna konfiguracja w /settings/integrations/polkurier z zaszyfrowanym Token API + loginem, realny test polaczenia przez apimetod=test_auth_api zweryfikowany na produkcyjnym koncie operatora (Autoryzacja: 1).

Performance

Metric Value
Duration ~45min (incl. live API debugging)
Started 2026-05-14T19:00:00Z
Completed 2026-05-14T19:45:00Z
Tasks 3 of 3 completed
Files created 5
Files modified 6

Acceptance Criteria Results

Criterion Status Notes
AC-1: Migracja tworzy single-instance tabele konfiguracji Pass (modified) DDL idempotentny. Modyfikacja: kolumna environment ENUM pominieta (polkurier nie ma sandbox); dodana kolumna login VARCHAR(190) (polkurier wymaga login+token, nie samego tokena).
AC-2: Repozytorium szyfruje Token API i zarzadza pojedynczym rekordem integrations Pass getSettings() zwraca has_api_token: bool, saveSettings() szyfruje przez IntegrationSecretCipher, getCredentials() gates na is_active=1.
AC-3: Endpoint testowy realnie wywoluje API polkuriera i zapisuje wynik Pass (live verified) Operator potwierdzil: Polaczenie z polkurier dziala. Autoryzacja: 1 (response z apimetod=test_auth_api). IntegrationsRepository::updateTestResult() zapisuje wynik.
AC-4: Karta polkurier w hubie integracji Pass buildPolkurierRow() w IntegrationsHubController wstawia wiersz po Apaczce (semantycznie sasiednie).
AC-5: Apaczka i istniejace ShipmentProviderRegistry netkniete Pass Zerowe modyfikacje w src/Modules/Shipments/* i Apaczka*. Grep polkurier w ShipmentProviderRegistry.php -> 0 trafien.
AC-6: Dokumentacja zaktualizowana Pass db_schema.md +1 tabela (62 total), architecture.md +sekcja Phase 127, tech_changelog.md +wpis z deviation.

Accomplishments

  • polkurier.pl wpiety jako drugi broker kurierski (obok Apaczki) — fundament gotowy i zweryfikowany na zywym API operatora.
  • Kontrakt API polkuriera zweryfikowany i udokumentowany w architecture.md: POST https://api.polkurier.pl/, JSON {authorization:{login,token}, apimetod, data:{platform, platform_version}}, sukces gdy status='success', tresc bledu w polu response envelope'a.
  • 4 buggi z pierwszego draftu naprawione live (3 podczas testow operatora) — finalna implementacja sprawdzona na realnym Token API.

Task Commits

Commits jeszcze nie utworzone (czekaja na transition step). Calosc fazy 127 zostanie zacommitowana jako jeden feat(127): commit.

Task Commit Type Description
Task 1: Migracja + Repository (pending) feat DDL + PolkurierIntegrationRepository
Task 2: ApiClient + Controller + widok + routy (pending) feat PolkurierApiClient + Controller + view + i18n + DI
Task 3: Hub + dokumentacja codebase (pending) feat IntegrationsHubController buildPolkurierRow + db_schema/architecture/tech_changelog

Files Created/Modified

File Change Purpose
database/migrations/20260514_000114_create_polkurier_integration_settings.sql Created DDL tabeli + seed integrations.type='polkurier' (idempotentny)
src/Modules/Settings/PolkurierIntegrationRepository.php Created Single-instance repo, szyfrowanie tokena, getCredentials z gating na is_active
src/Modules/Settings/PolkurierApiClient.php Created POST do api.polkurier.pl, testConnection z apimetod=test_auth_api, stuby createShipment/getLabel/getStatus/cancelOrder
src/Modules/Settings/PolkurierIntegrationController.php Created GET/save/test endpointy z CSRF, flash, RedirectPathResolver
resources/views/settings/polkurier.php Created Formularz konfiguracji + Test polaczenia, alerty przez komponent alert.php
routes/web.php Modified DI wiring (Repo+Controller) + 3 routy + ctor IntegrationsHubController
src/Modules/Settings/IntegrationsHubController.php Modified +param polkurier + buildPolkurierRow() + wstawienie wiersza po Apaczce
resources/lang/pl.php Modified settings.polkurier.* + providers.polkurier
.paul/codebase/db_schema.md Modified +tabela polkurier_integration_settings, 61->62
.paul/codebase/architecture.md Modified +sekcja Phase 127
.paul/codebase/tech_changelog.md Modified +wpis 2026-05-14 z deviation

Decisions Made

Decision Rationale Impact
Kolumna login VARCHAR(190) w tabeli zamiast samego api_token API polkuriera (zweryfikowane w SDK Auth.php/Request.php) wymaga login+token w body authorization, nie samego tokena Wszystkie przyszle wywolania API musza miec login z getCredentials()['login']
Pominieta kolumna environment ENUM('production','sandbox') z PLAN AC-1 polkurier nie ma osobnego srodowiska sandbox (jeden URL: https://api.polkurier.pl/) YAGNI; jezeli polkurier doda sandbox, dolozymy migracja ALTER TABLE ... ADD COLUMN
Wykonanie planu inline zamiast delegated:auto z planu Swiezy kontekst API research (Config/Auth/Methods z polkurier-sdk) — agent musialby ten research powtorzyc Brak; boundaries i AC niezmienione, deviation udokumentowana
Content-Type: application/json (bez ; charset=UTF-8 suffix) polkurier API zwraca Content type must be: application/json gdy header ma charset suffix Pattern do reuse jezeli inne integracje sa rownie strict
ResponseStatus::SUCCESS = 'success' (nie 'ok') Zweryfikowane w src/Type/ResponseStatus.php SDK polkuriera Wszystkie przyszle metody API musza sprawdzac status === 'success'
Tresc bledu z pola response envelope'a (nie error_message) SDK polkuriera rzuca ErrorException($response->get('response')) gdy status != success Wzorzec parser bledu dla wszystkich przyszlych metod API

Deviations from Plan

Summary

Type Count Impact
Auto-fixed 3 Krytyczne — bez tych poprawek test polaczenia nie zwracalby success
Scope additions 1 Kolumna login w schemacie (poza zakresem AC-1 — wymagana przez kontrakt API)
Scope removals 1 Kolumna environment z AC-1 pominieta (YAGNI)
Execution mode 1 Plan: delegation:auto. Faktycznie: inline. Boundaries i AC niezmienione.
Deferred 0 Brak

Total impact: Wszystkie deviacje wymuszone realnym kontraktem API polkuriera. Plan z chwili pisania bazowal na publicznym opisie API; szczegoly (login, status='success', strict Content-Type) wyplynely dopiero przy weryfikacji SDK i testach na zywym koncie operatora.

Auto-fixed Issues

1. [API contract] status === 'ok' -> status === 'success'

  • Found during: Live test po Task 2 (operator zglosil Status: error)
  • Issue: Kod sprawdzal $status === 'ok', ale ResponseStatus::SUCCESS w SDK polkuriera = 'success'
  • Fix: Zmiana porownania na $status === 'success'; parser bledu zaktualizowany do pobierania tresci z pola response envelope'a (mirror SDK ErrorException)
  • Files: src/Modules/Settings/PolkurierApiClient.php
  • Verification: Drugi test operatora — komunikat Content type must be: application/json (faktyczna tresc z polkuriera, nie generyczne Status: error)
  • Commit: TBD (przy transition)

2. [HTTP headers] Content-Type strict

  • Found during: Live test po fix #1 (operator zglosil Content type must be: application/json)
  • Issue: Header Content-Type: application/json; charset=UTF-8 — polkurier robi strict equality check i odrzuca suffix ; charset=UTF-8
  • Fix: Zmiana na Content-Type: application/json (sam mime, bez parametrow)
  • Files: src/Modules/Settings/PolkurierApiClient.php
  • Verification: Trzeci test operatora — Polaczenie z polkurier dziala. Autoryzacja: 1 (sukces)
  • Commit: TBD (przy transition)

3. [Error reporting] Brak tresci bledu w komunikacie UI

  • Found during: Live test po Task 2 (Status: error bez detali)
  • Issue: Komunikat fallback 'Status: ' . $status byl nieczytelny; tresc bledu z polkuriera siedzi w polu response envelope'a, nie error_message top-level
  • Fix: Parser bledu czyta response field (string albo zagniezdzona struktura error_message/errorMessage/message/error), z fallbackiem na top-level error_message/message/error i finalnie Status: X (HTTP Y)
  • Files: src/Modules/Settings/PolkurierApiClient.php
  • Verification: Fix #2 mozliwy tylko dzieki temu (operator zobaczyl Content type must be: application/json zamiast Status: error)
  • Commit: TBD (przy transition)

Deferred Items

Brak — kontrakt API operatora zweryfikowany, fundament zamkniety. Kolejne fazy (PolkurierShipmentService, PolkurierTrackingService) sa zaplanowane jako oddzielne, swiadomie poza zakresem 127 (PLAN boundaries SCOPE LIMITS).

Issues Encountered

Issue Resolution
Operator: Status: error po pierwszym smoke Fix #1 (status='success') + #3 (parser bledu) — operator widzi teraz realny komunikat polkuriera
Operator: Content type must be: application/json po fix #1 Fix #2 (strict Content-Type bez charset suffix)
API research nieobecny przed planem Pre-APPLY fetche SDK polkurier-sdk (Auth/Request/Methods/Config/ResponseStatus) — kontrakt zrekonstruowany przed implementacja

Next Phase Readiness

Ready:

  • PolkurierIntegrationRepository::getCredentials() zwraca odszyfrowany login + api_token + default_label_format — gotowe do uzycia w PolkurierShipmentService.
  • PolkurierApiClient ma zweryfikowany kontrakt POST (single endpoint, JSON body, status='success', error w response) + stuby createShipment/getLabel/getStatus/cancelOrder z RuntimeException("Not implemented in Phase 127") jako placeholder dla nastepnej fazy.
  • 36 metod SDK polkuriera zidentyfikowanych: AvailableCarriers, OrderValuationV2, CreateOrder, GetLabel, GetStatus, CancelOrder, InpostParcelMachines, PocztexPostOffices, Kurier48PostOffices, GetCourierPoint, Heartbeat, etc. — gotowe do mapowania w kolejnych planach.
  • Hub integracji pokazuje stan polkuriera obok Apaczki — operator widzi obie integracje rownolegle.

Concerns:

  • Brak PolkurierShipmentService — operator nie moze jeszcze nadawac przesylek przez polkuriera. Zgodne z PLAN scope (SCOPE LIMITS).
  • Brak mapowan metod dostawy order_delivery_method -> polkurier service — wymaga analizy listy uslug z AvailableCarriers API.
  • Brak delivery_status_mappings dla provider='polkurier' — tracking polling rowniez deferred.

Blockers:

  • Operator musi uruchomic php bin/migrate.php na zywej bazie (XAMPP) zeby zalozyc tabele i seed rekord integrations.type='polkurier'. AKTUALNIE migracja juz uruchomiona (test polaczenia dzialal, wiec rekord integrations istnieje).

Phase: 127-polkurier-integration-foundation, Plan: 01 Completed: 2026-05-14