--- phase: 06-sonarqube-quality plan: 05 type: execute wave: 3 depends_on: ["06-04"] files_modified: - src/Modules/Settings/ShopproOrdersSyncService.php - src/Modules/Settings/ShopproOrderMapper.php - src/Modules/Settings/ShopproProductImageResolver.php - src/Modules/Settings/AllegroIntegrationController.php - src/Modules/Settings/AllegroStatusMappingController.php - src/Modules/Settings/AllegroDeliveryMappingController.php autonomous: false --- ## Goal Rozdzielić 2 z 3 god classes przekraczające 20 metod — eliminacja naruszeń SonarQube php:S1448. - `ShopproOrdersSyncService` (39 metod) → 3 klasy - `AllegroIntegrationController` (30 metod) → 3 kontrolery ## Purpose God classes naruszają SRP i S1448. `ShopproOrdersSyncService` z 39 metodami i 1192 liniami jest najtrudniejszą do testowania klasą w projekcie. Podział ułatwia izolowane modyfikacje integracji Shoppro bez ryzyka regresi w całym module. ## Output 5 nowych klas/kontrolerów, `ShopproOrdersSyncService` spada do ~15 metod, `AllegroIntegrationController` do ~12. S1448 spada z 6x do 1x (ShopproIntegrationsController pozostaje na następny plan). ## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md ## Source Files @src/Modules/Settings/ShopproOrdersSyncService.php @src/Modules/Settings/AllegroIntegrationController.php @routes/web.php ## Required Skills (from SPECIAL-FLOWS.md) | Skill | Priority | When to Invoke | Loaded? | |-------|----------|----------------|---------| | sonar-scanner | required | Po APPLY, przed UNIFY | ○ | | /code-review | optional | Po implementacji, przed UNIFY | ○ | ## Skill Invocation Checklist - [ ] sonar-scanner uruchomiony po zakończeniu APPLY - [ ] /code-review rozważyć (duże zmiany strukturalne) ## AC-1: ShopproOrderMapper wydzielony ```gherkin Given ShopproOrdersSyncService zawiera 15+ metod mapujących (mapOrderAggregate, mapAddresses, mapItems, etc.) When wydzielasz je do src/Modules/Settings/ShopproOrderMapper.php Then ShopproOrderMapper zawiera wszystkie metody mapowania; ShopproOrdersSyncService wstrzykuje go przez konstruktor ``` ## AC-2: ShopproProductImageResolver wydzielony ```gherkin Given ShopproOrdersSyncService zawiera resolveProductImagesForOrder() i fetchPrimaryProductImageUrl() When wydzielasz je do src/Modules/Settings/ShopproProductImageResolver.php Then ShopproProductImageResolver obsługuje image fetching; ShopproOrdersSyncService używa go przez konstruktor ``` ## AC-3: ShopproOrdersSyncService ma ≤20 metod ```gherkin Given ShopproOrdersSyncService ma 39 metod When wydzielono ShopproOrderMapper i ShopproProductImageResolver Then ShopproOrdersSyncService ma ≤20 metod (sync + orchestration + state management) ``` ## AC-4: AllegroIntegrationController podzielony ```gherkin Given AllegroIntegrationController ma 30 metod (status mapping, delivery mapping, main settings) When wydzielasz AllegroStatusMappingController i AllegroDeliveryMappingController Then każdy kontroler ma ≤15 metod; routes/web.php zaktualizowane ``` ## AC-5: Brak regresji ```gherkin Given Shoppro sync i Allegro integration działają przed podziałem When podział jest czysto strukturalny (move method, nie zmiana logiki) Then sync Shoppro importuje zamówienia; mapowania Allegro zapisują się; OAuth działa ``` Task 1: Wydziel ShopproOrderMapper z ShopproOrdersSyncService src/Modules/Settings/ShopproOrderMapper.php, src/Modules/Settings/ShopproOrdersSyncService.php Przeczytaj ShopproOrdersSyncService dokładnie. Zidentyfikuj metody mapujące dane zamówień. **Metody do przeniesienia do ShopproOrderMapper:** Przenieś wszystkie private metody których jedynym zadaniem jest konwersja danych API → struktury wewnętrzne: - mapOrderAggregate() — główna metoda mapowania - mapAddresses() — mapowanie adresów - mapItems() — mapowanie pozycji - mapPayments() — mapowanie płatności - mapShipments() — mapowanie wysyłek - mapNotes() — mapowanie notatek - buildInvoiceAddress() — budowanie adresu faktury - normalizeOrderId(), normalizePaidFlag(), mapPaymentStatus(), sanitizePlainText() - buildDeliveryMethodLabel(), formatMoneyCompact(), normalizeMediaUrl() - toFloatOrNull(), toFloatOrDefault(), readPath(), readSinglePath(), composeName() - hasAddressData(), resolveInvoiceRequested(), parsePickupPoint() **ShopproOrderMapper (nowy plik):** - namespace App\Modules\Settings - class ShopproOrderMapper - Konstruktor przyjmuje zależności potrzebne metodom (np. ShopproOrderSyncStateRepository jeśli potrzebne) - Przenieś metody bez zmiany logiki (tylko zmień z private na public te, które sync() wywołuje bezpośrednio) **ShopproOrdersSyncService (aktualizacja):** - Dodaj private ShopproOrderMapper $mapper; w konstruktorze - CronHandlerFactory tworzy ShopproOrdersSyncService — sprawdź src/Modules/Cron/CronHandlerFactory.php i zaktualizuj kompozycję - Zastąp wywołania $this->mapOrderAggregate() → $this->mapper->mapOrderAggregate() - Usuń przeniesione metody z ShopproOrdersSyncService UWAGA: Sprawdź CronHandlerFactory.php — musi przekazać nowy ShopproOrderMapper do konstruktora. php -l src/Modules/Settings/ShopproOrderMapper.php php -l src/Modules/Settings/ShopproOrdersSyncService.php php -l src/Modules/Cron/CronHandlerFactory.php grep -c "function " src/Modules/Settings/ShopproOrdersSyncService.php — powinno być ≤25 (po Task 1, przed Task 2) AC-1 satisfied: ShopproOrderMapper istnieje z metodami mapowania; ShopproOrdersSyncService go używa Task 2: Wydziel ShopproProductImageResolver i finalizuj ShopproOrdersSyncService src/Modules/Settings/ShopproProductImageResolver.php, src/Modules/Settings/ShopproOrdersSyncService.php, src/Modules/Cron/CronHandlerFactory.php **ShopproProductImageResolver (nowy plik):** - Przenieś z ShopproOrdersSyncService: - resolveProductImagesForOrder() - fetchPrimaryProductImageUrl() - Konstruktor przyjmuje ShopproApiClient (potrzebny do fetch) - namespace App\Modules\Settings **ShopproOrdersSyncService (finalizacja):** - Dodaj private ShopproProductImageResolver $imageResolver; - Zastąp $this->resolveProductImagesForOrder() → $this->imageResolver->resolveProductImagesForOrder() - Po Task 1 + Task 2 ShopproOrdersSyncService powinien mieć ≤20 metod **CronHandlerFactory.php (aktualizacja):** - Sprawdź gdzie tworzona jest instancja ShopproOrdersSyncService - Dodaj nowe zależności: new ShopproOrderMapper(...), new ShopproProductImageResolver($shopproApiClient) - Przekaż do konstruktora ShopproOrdersSyncService Sprawdź czy ShopproOrderMapper też potrzebuje ShopproApiClient lub innych zależności — jeśli tak, przekaż z CronHandlerFactory. php -l src/Modules/Settings/ShopproProductImageResolver.php php -l src/Modules/Settings/ShopproOrdersSyncService.php php -l src/Modules/Cron/CronHandlerFactory.php grep -c "function " src/Modules/Settings/ShopproOrdersSyncService.php — ≤20 AC-2, AC-3 satisfied: ShopproProductImageResolver wydzielony; ShopproOrdersSyncService ≤20 metod ShopproOrdersSyncService podzielony na 3 klasy: - ShopproOrderMapper (metody mapowania danych) - ShopproProductImageResolver (pobieranie zdjęć produktów) - ShopproOrdersSyncService (orchestrator, ≤20 metod) CronHandlerFactory zaktualizowany z nowymi zależnościami. 1. Uruchom aplikację (XAMPP) 2. Przejdź do Ustawień → Integracje → ShopPRO 3. Uruchom ręczny import zamówień (jeśli dostępny) lub uruchom cron 4. Sprawdź logi crona: importy Shoppro działają bez błędów 5. Sprawdź że zamówienia pojawiają się / nie ma regresji Wpisz "approved" aby kontynuować do podziału AllegroIntegrationController, lub opisz błędy Task 3: Podziel AllegroIntegrationController na 3 kontrolery src/Modules/Settings/AllegroIntegrationController.php, src/Modules/Settings/AllegroStatusMappingController.php, src/Modules/Settings/AllegroDeliveryMappingController.php, routes/web.php Przeczytaj AllegroIntegrationController i routes/web.php dokładnie. **Podział metod:** AllegroStatusMappingController (nowy): - saveStatusMapping() - saveStatusMappingsBulk() - deleteStatusMapping() - syncStatusesFromAllegro() - buildImportImageWarningMessage() (private helper) - reasonLabel() (private helper) AllegroDeliveryMappingController (nowy): - saveDeliveryMappings() - loadDeliveryServices() - (prywatne helpery potrzebne tym metodom) AllegroIntegrationController (zostaje z): - index() - save() - saveImportSettings() - startOAuth() - oauthCallback() - refreshOAuthToken() - importSingleOrder() - (prywatne walidatory i helpery potrzebne tym metodom) **Nowe pliki kontrolerów:** - Skopiuj konstruktor i zależności z AllegroIntegrationController - namespace App\Modules\Settings - Przenieś metody bez zmiany logiki **routes/web.php:** - Utwórz instancje nowych kontrolerów (ten sam wzorzec co istniejące) - Przepnij route definicje dla: - status mapping routes → AllegroStatusMappingController - delivery mapping routes → AllegroDeliveryMappingController - AllegroIntegrationController obsługuje resztę Sprawdź które zależności ($this->repository, $this->translator etc.) są potrzebne każdemu kontrolerowi. php -l src/Modules/Settings/AllegroIntegrationController.php php -l src/Modules/Settings/AllegroStatusMappingController.php php -l src/Modules/Settings/AllegroDeliveryMappingController.php php -l routes/web.php grep -c "function " src/Modules/Settings/AllegroIntegrationController.php — ≤15 AC-4, AC-5 satisfied: AllegroIntegrationController ≤15 metod; nowe kontrolery poprawne; routes zaktualizowane ## DO NOT CHANGE - Logika biznesowa w żadnej z przenoszonych metod - Publiczne sygnatury metod (nazwy, parametry) - Pliki widoków i SCSS - ShopproIntegrationsController — zakres następnego planu (06-06 jeśli powstanie) - Inne moduły (Orders, Shipments, Auth, etc.) ## SCOPE LIMITS - Podział 2 klas (ShopproOrdersSyncService + AllegroIntegrationController) - ShopproIntegrationsController pomijamy w tym planie (30 metod — podobny refactoring) - Nie zmieniaj publicznych URL routes — tylko który controller je obsługuje - CronHandlerFactory — tylko minimalne zmiany potrzebne dla nowych dependencies Przed zamknięciem planu: - [ ] php -l na wszystkich nowych i zmodyfikowanych plikach - [ ] ShopproOrdersSyncService: grep -c "function " ≤20 - [ ] AllegroIntegrationController: grep -c "function " ≤15 - [ ] ShopproOrderMapper.php istnieje z metodami mapowania - [ ] ShopproProductImageResolver.php istnieje - [ ] AllegroStatusMappingController.php i AllegroDeliveryMappingController.php istnieją - [ ] routes/web.php poprawny składniowo - [ ] Checkpoint human-verify zaliczony (Shoppro sync działa) - [ ] sonar-scanner — S1448 violations zmalały - 4 nowe pliki PHP - ShopproOrdersSyncService ≤20 metod - AllegroIntegrationController ≤15 metod - Zero błędów składniowych - Shoppro import działa (human-verify passed) - SonarQube S1448 spada z 6 do ≤2 Po zakończeniu utwórz `.paul/phases/06-sonarqube-quality/06-05-SUMMARY.md`