wip(06-sonarqube-quality): 6 planów SonarQube Quality utworzonych
Plany dla php:S112, S1142, S1192, S3776, S1448, S138 — gotowe do APPLY. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
298
.paul/phases/06-sonarqube-quality/06-05-PLAN.md
Normal file
298
.paul/phases/06-sonarqube-quality/06-05-PLAN.md
Normal file
@@ -0,0 +1,298 @@
|
||||
---
|
||||
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
|
||||
---
|
||||
|
||||
<objective>
|
||||
## 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).
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
|
||||
## Source Files
|
||||
@src/Modules/Settings/ShopproOrdersSyncService.php
|
||||
@src/Modules/Settings/AllegroIntegrationController.php
|
||||
@routes/web.php
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## 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)
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Wydziel ShopproOrderMapper z ShopproOrdersSyncService</name>
|
||||
<files>
|
||||
src/Modules/Settings/ShopproOrderMapper.php,
|
||||
src/Modules/Settings/ShopproOrdersSyncService.php
|
||||
</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>
|
||||
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)
|
||||
</verify>
|
||||
<done>AC-1 satisfied: ShopproOrderMapper istnieje z metodami mapowania; ShopproOrdersSyncService go używa</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Wydziel ShopproProductImageResolver i finalizuj ShopproOrdersSyncService</name>
|
||||
<files>
|
||||
src/Modules/Settings/ShopproProductImageResolver.php,
|
||||
src/Modules/Settings/ShopproOrdersSyncService.php,
|
||||
src/Modules/Cron/CronHandlerFactory.php
|
||||
</files>
|
||||
<action>
|
||||
**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.
|
||||
</action>
|
||||
<verify>
|
||||
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
|
||||
</verify>
|
||||
<done>AC-2, AC-3 satisfied: ShopproProductImageResolver wydzielony; ShopproOrdersSyncService ≤20 metod</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<what-built>
|
||||
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.
|
||||
</what-built>
|
||||
<how-to-verify>
|
||||
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
|
||||
</how-to-verify>
|
||||
<resume-signal>Wpisz "approved" aby kontynuować do podziału AllegroIntegrationController, lub opisz błędy</resume-signal>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Podziel AllegroIntegrationController na 3 kontrolery</name>
|
||||
<files>
|
||||
src/Modules/Settings/AllegroIntegrationController.php,
|
||||
src/Modules/Settings/AllegroStatusMappingController.php,
|
||||
src/Modules/Settings/AllegroDeliveryMappingController.php,
|
||||
routes/web.php
|
||||
</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>
|
||||
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
|
||||
</verify>
|
||||
<done>AC-4, AC-5 satisfied: AllegroIntegrationController ≤15 metod; nowe kontrolery poprawne; routes zaktualizowane</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## 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
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- 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
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Po zakończeniu utwórz `.paul/phases/06-sonarqube-quality/06-05-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user