--- phase: 01-tech-debt plan: 02 type: execute wave: 1 depends_on: [] files_modified: - src/Core/Support/StringHelper.php - src/Modules/Settings/AllegroOrderImportService.php - src/Modules/Settings/AllegroOrdersSyncService.php - src/Modules/Settings/AllegroOrderSyncStateRepository.php - src/Modules/Settings/AllegroIntegrationRepository.php - src/Modules/Settings/AllegroStatusMappingRepository.php - src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php - src/Modules/Settings/CompanySettingsRepository.php - src/Modules/Settings/InpostIntegrationRepository.php - src/Modules/Settings/IntegrationsRepository.php - src/Modules/Settings/ShopproIntegrationsRepository.php - src/Modules/Settings/ShopproOrdersSyncService.php - src/Modules/Settings/ShopproPaymentStatusSyncService.php - src/Modules/Orders/OrdersController.php - src/Modules/Orders/OrdersRepository.php - src/Modules/Settings/SettingsController.php - .paul/codebase/CONCERNS.md autonomous: true --- ## Cel Ekstrakcja zduplikowanych prywatnych metod pomocniczych (`nullableString()`, `normalizeDateTime()`, `normalizeColorHex()`) z 15+ klas do jednej klasy `StringHelper` w `src/Core/Support/`. Zamiana wszystkich wywołań prywatnych metod na wywołania statyczne. ## Uzasadnienie Te same metody są copy-paste w 12+ klasach. Narusza to regułę projektu przeciwko duplikowaniu kodu (CLAUDE.md) oraz zasadę SRP. Ryzyko rozbieżności jeśli jedna kopia zostanie zmieniona a inne nie. ## Wynik - Nowy plik `src/Core/Support/StringHelper.php` z 3 metodami statycznymi - 15 plików — usunięte prywatne metody, zamienione wywołania na `StringHelper::*` - Wpis o tym błędzie usunięty z `.paul/codebase/CONCERNS.md` ## Kontekst projektu @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md ## Istniejące pliki w Core/Support Już istnieją: `src/Core/Support/Env.php`, `Flash.php`, `Logger.php`, `Session.php` — wzorzec dla `StringHelper.php`. ## Wzorzec implementacji helperów `nullableString()` — trim + zwróć null jeśli pusty string: ```php private function nullableString(string $value): ?string { $trimmed = trim($value); return $trimmed === '' ? null : $trimmed; } ``` `normalizeDateTime()` — trim, walidacja, formatowanie do `Y-m-d H:i:s`: ```php private function normalizeDateTime(string $value): ?string { $trimmed = trim($value); if ($trimmed === '') { return null; } try { return (new DateTimeImmutable($trimmed))->format('Y-m-d H:i:s'); } catch (\Exception $e) { return null; } } ``` `normalizeColorHex()` — walidacja regex `#RRGGBB`, fallback `#64748b`: ```php private function normalizeColorHex(string $value): string { $trimmed = trim($value); if (preg_match('/^#[0-9a-fA-F]{6}$/', $trimmed) === 1) { return strtolower($trimmed); } return '#64748b'; } ``` ## Wymagane Skille (z SPECIAL-FLOWS.md) | Skill | Priorytet | Kiedy wywołać | Załadowany? | |-------|-----------|---------------|-------------| | /feature-dev | required | Przed implementacją | ○ | | /code-review | required | Po implementacji, przed UNIFY | ○ | **BLOKUJĄCE:** Wymagane skille MUSZĄ być załadowane przed uruchomieniem APPLY. ## Lista do odhaczenia - [ ] /feature-dev załadowany - [ ] /code-review załadowany (przed UNIFY) ## AC-1: StringHelper istnieje i zawiera wszystkie 3 metody ```gherkin Given plik src/Core/Support/StringHelper.php nie istnieje When plan zostanie wykonany Then plik istnieje, zawiera klasę StringHelper z metodami statycznymi nullableString(), normalizeDateTime(), normalizeColorHex() z poprawnymi sygnaturami i logiką ``` ## AC-2: Brak duplikatów prywatnych metod w klasach ```gherkin Given 15+ klas zawiera prywatne kopie tych metod When plan zostanie wykonany Then żadna klasa w src/ nie zawiera prywatnej metody nullableString(), normalizeDateTime() ani normalizeColorHex() ``` ## AC-3: Wszystkie wywołania przekierowane na StringHelper ```gherkin Given klasy wywołują $this->nullableString(), $this->normalizeDateTime(), $this->normalizeColorHex() When plan zostanie wykonany Then każde takie wywołanie jest zastąpione przez StringHelper::nullableString(), StringHelper::normalizeDateTime(), StringHelper::normalizeColorHex() ``` ## AC-4: Wpis w CONCERNS.md usunięty ```gherkin Given sekcja "[HIGH] Duplicated nullableString()..." istnieje w .paul/codebase/CONCERNS.md When plan zostanie wykonany Then ta sekcja jest usunięta z pliku CONCERNS.md ``` ## AC-5: Brak błędów składniowych PHP ```gherkin Given zmodyfikowane pliki PHP When uruchomimy php -l na każdym zmodyfikowanym pliku Then każdy plik zwraca "No syntax errors detected" ``` Zadanie 1: Utwórz StringHelper z 3 metodami statycznymi src/Core/Support/StringHelper.php Utwórz nowy plik `src/Core/Support/StringHelper.php` z namespace `App\Core\Support`. Klasa `StringHelper` (final) z 3 publicznymi metodami statycznymi: 1. `nullableString(string $value): ?string` - trim($value), jeśli '' → return null, inaczej return trimmed 2. `normalizeDateTime(string $value): ?string` - trim($value), jeśli '' → return null - try { return (new DateTimeImmutable($trimmed))->format('Y-m-d H:i:s'); } - catch (\Exception) { return null; } - WAŻNE: użyj `use DateTimeImmutable;` w importach 3. `normalizeColorHex(string $value): string` - trim($value), jeśli pasuje do `/^#[0-9a-fA-F]{6}$/` → return strtolower($trimmed) - fallback: return '#64748b' Styl: `declare(strict_types=1)`, PascalCase dla klasy, brak konstruktora. php -l "src/Core/Support/StringHelper.php" zwraca "No syntax errors detected" AC-1 spełnione: StringHelper.php istnieje z 3 metodami statycznymi Zadanie 2: Zamień prywatne metody na StringHelper we wszystkich 15 plikach src/Modules/Settings/AllegroOrderImportService.php, src/Modules/Settings/AllegroOrdersSyncService.php, src/Modules/Settings/AllegroOrderSyncStateRepository.php, src/Modules/Settings/AllegroIntegrationRepository.php, src/Modules/Settings/AllegroStatusMappingRepository.php, src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php, src/Modules/Settings/CompanySettingsRepository.php, src/Modules/Settings/InpostIntegrationRepository.php, src/Modules/Settings/IntegrationsRepository.php, src/Modules/Settings/ShopproIntegrationsRepository.php, src/Modules/Settings/ShopproOrdersSyncService.php, src/Modules/Settings/ShopproPaymentStatusSyncService.php, src/Modules/Orders/OrdersController.php, src/Modules/Orders/OrdersRepository.php, src/Modules/Settings/SettingsController.php Dla każdego pliku z listy: 1. Dodaj `use App\Core\Support\StringHelper;` do sekcji importów (po istniejących `use` statements) - Tylko jeśli plik rzeczywiście używa co najmniej jednej z tych metod - Zachowaj alfabetyczną kolejność lub dodaj na końcu bloku use 2. Zamień wywołania: - `$this->nullableString(` → `StringHelper::nullableString(` - `$this->normalizeDateTime(` → `StringHelper::normalizeDateTime(` - `$this->normalizeColorHex(` → `StringHelper::normalizeColorHex(` 3. Usuń prywatną metodę z klasy: - Całą definicję `private function nullableString(...)` jeśli istnieje w pliku - Całą definicję `private function normalizeDateTime(...)` jeśli istnieje - Całą definicję `private function normalizeColorHex(...)` jeśli istnieje UWAGA: AllegroOrderImportService.php ma zarówno nullableString() jak i normalizeDateTime() — usuń obie. UWAGA: ShopproOrdersSyncService.php ma zarówno nullableString() jak i normalizeDateTime() — usuń obie. UWAGA: ShopproPaymentStatusSyncService.php ma zarówno nullableString() jak i normalizeDateTime() — usuń obie. NIE zmieniaj żadnej innej logiki. Tylko zamiana wywołań i usunięcie duplikatów. php -l na każdym z 15 zmodyfikowanych plików — brak błędów składniowych. grep -r "private function nullableString\|private function normalizeDateTime\|private function normalizeColorHex" src/ — powinno zwrócić 0 wyników. AC-2 i AC-3 spełnione: brak duplikatów, wszystkie wywołania na StringHelper:: Zadanie 3: Usuń wpis o błędzie z CONCERNS.md .paul/codebase/CONCERNS.md Usuń sekcję `### [HIGH] Duplicated nullableString() / normalizeDateTime() / normalizeColorHex() Helpers — 15+ copies` wraz z całą jej treścią (od linii `### [HIGH] Duplicated...` do następnej linii `---`). Usuń także poziomą linię `---` oddzielającą tę sekcję od następnej (zostaw jeden separator między Tech Debt a kolejną sekcją jeśli to potrzebne dla czytelności). NIE modyfikuj żadnych innych wpisów w CONCERNS.md. Otwórz CONCERNS.md — wpis o nullableString nie istnieje. Plik jest poprawnym Markdownem. AC-4 spełnione: wpis usunięty z CONCERNS.md ## DO NOT CHANGE - Logika biznesowa wewnątrz helperów — przepisz 1:1 do StringHelper, nie zmieniaj zachowania - Żadne inne metody w modyfikowanych klasach - Inne sekcje w CONCERNS.md - Testy, migracje, widoki, zasoby statyczne ## SCOPE LIMITS - Tylko 3 metody: nullableString, normalizeDateTime, normalizeColorHex - Nie refaktoryzuj innych prywatnych helperów przy okazji - Nie przenoś plików ani nie zmieniaj namespace'ów innych klas - Nie dodawaj nowych zależności (composer) Przed zamknięciem planu sprawdź: - [ ] php -l src/Core/Support/StringHelper.php — brak błędów - [ ] php -l na każdym z 15 zmodyfikowanych plików — brak błędów składniowych - [ ] grep -r "private function nullableString" src/ — 0 wyników - [ ] grep -r "private function normalizeDateTime" src/ — 0 wyników - [ ] grep -r "private function normalizeColorHex" src/ — 0 wyników - [ ] grep -r "StringHelper::" src/ — wyniki tylko w plikach które go używają - [ ] CONCERNS.md — wpis [HIGH] Duplicated helpers nie istnieje - [ ] Wszystkie kryteria akceptacji spełnione - StringHelper.php utworzony z 3 poprawnymi metodami statycznymi - 0 prywatnych kopii tych metod pozostało w src/ - Wszystkie wywołania przekierowane na StringHelper:: - CONCERNS.md zaktualizowany — wpis usunięty - Brak błędów składniowych PHP w zmodyfikowanych plikach Po zakończeniu utwórz `.paul/phases/01-tech-debt/01-02-SUMMARY.md`