--- phase: 02-bug-fixes plan: 03 type: execute wave: 1 depends_on: [] files_modified: - src/Modules/Settings/ShopproOrderSyncStateRepository.php - src/Modules/Settings/ShopproOrdersSyncService.php - src/Core/Application.php autonomous: true --- ## Cel Wydzielenie dedykowanego `ShopproOrderSyncStateRepository` i zastąpienie nim błędnego wstrzyknięcia `AllegroOrderSyncStateRepository` w `ShopproOrdersSyncService`. ## Uzasadnienie `ShopproOrdersSyncService` zarządza kursorem synchronizacji shopPRO przez klasę nazwianą `AllegroOrderSyncStateRepository`. To błędna zależność — stan shopPRO jest zapisywany przez klasę Allegro. Przy dodaniu kolejnych integracji shopPRO problem się zwielokrotnia. Docelowo każda integracja ma własne, poprawnie nazwane repozytorium. ## Wyjście - Nowy `ShopproOrderSyncStateRepository` (ta sama tabela `integration_order_sync_state`, ta sama logika `integration_id`-scoped) - `ShopproOrdersSyncService` wstrzykuje `ShopproOrderSyncStateRepository` zamiast `AllegroOrderSyncStateRepository` - `Application.php` tworzy i przekazuje `ShopproOrderSyncStateRepository` do serwisu ## Kontekst projektu @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md ## Pliki źródłowe @src/Modules/Settings/AllegroOrderSyncStateRepository.php @src/Modules/Settings/ShopproOrdersSyncService.php @src/Core/Application.php ## Wymagane skille (z SPECIAL-FLOWS.md) | Skill | Priorytet | Kiedy wywołać | Załadowany? | |-------|-----------|---------------|-------------| | /code-review | required | Po implementacji, przed UNIFY | ○ | | sonar-scanner | required | Po APPLY, przed UNIFY | ○ | **BLOKUJĄCE:** Wymagane skille MUSZĄ być wywołane przed UNIFY. ## Checklist - [ ] /code-review wywołany po implementacji - [ ] sonar-scanner uruchomiony, wyniki sprawdzone i zaktualizowane w `DOCS/todo.md` ## AC-1: `ShopproOrdersSyncService` nie zależy od `AllegroOrderSyncStateRepository` ```gherkin Given plik `ShopproOrdersSyncService.php` When sprawdzam import i konstruktor Then nie ma żadnego odwołania do `AllegroOrderSyncStateRepository` — ani importu, ani typehinta ``` ## AC-2: `ShopproOrdersSyncService` korzysta z `ShopproOrderSyncStateRepository` ```gherkin Given plik `ShopproOrdersSyncService.php` When sprawdzam konstruktor i metody wywołujące state Then zmienna `$syncState` ma typ `ShopproOrderSyncStateRepository` i jest poprawnie wstrzyknięta ``` ## AC-3: `ShopproOrderSyncStateRepository` ma identyczny kontrakt publiczny co `AllegroOrderSyncStateRepository` ```gherkin Given nowy plik `ShopproOrderSyncStateRepository.php` When sprawdzam publiczne metody Then istnieją: `getState(int $integrationId)`, `markRunStarted(int, DateTimeImmutable)`, `markRunSuccess(int, DateTimeImmutable, ?string, ?string)`, `markRunFailed(int, DateTimeImmutable, string)` ``` ## AC-4: `Application.php` wstrzykuje `ShopproOrderSyncStateRepository` ```gherkin Given plik `Application.php`, linia tworzenia `ShopproOrdersSyncService` When sprawdzam przekazywane zależności Then zamiast `new AllegroOrderSyncStateRepository($this->db)` jest `new ShopproOrderSyncStateRepository($this->db)` ``` ## AC-5: Brak regresji — zachowanie synchronizacji shopPRO nie zmienia się ```gherkin Given działający mechanizm synchronizacji shopPRO (tabela `integration_order_sync_state`, logika kursorowa) When uruchamiam cron lub ręczną synchronizację shopPRO Then dane stanu są nadal poprawnie odczytywane i zapisywane do tej samej tabeli z tym samym `integration_id` ``` Zadanie 1: Utwórz `ShopproOrderSyncStateRepository` src/Modules/Settings/ShopproOrderSyncStateRepository.php Utwórz nowy plik `src/Modules/Settings/ShopproOrderSyncStateRepository.php`. Klasa ma być funkcjonalnie identyczna z `AllegroOrderSyncStateRepository` — ta sama tabela `integration_order_sync_state`, ta sama logika `resolveColumns()`, ten sam `upsertState()`. Skopiuj implementację i zmień tylko: - Nazwę klasy: `ShopproOrderSyncStateRepository` (zamiast `AllegroOrderSyncStateRepository`) - Namespace pozostaje `App\Modules\Settings` - Deklaracja `final class ShopproOrderSyncStateRepository` Uwagi: - Zachowaj `final` — klasa nie jest przewidziana do dziedziczenia - Zachowaj identyczny kontrakt publiczny (te same sygnatury metod, te same typy zwracane) - Nie zmieniaj nazw kolumn w tabeli ani logiki `resolveColumns()` — tabela jest wspólna, ale dane są scopowane przez `integration_id` - Nie dodawaj żadnej nowej logiki — to tylko rename bez zmiany zachowania Plik `src/Modules/Settings/ShopproOrderSyncStateRepository.php` istnieje i zawiera `final class ShopproOrderSyncStateRepository`. `php -l src/Modules/Settings/ShopproOrderSyncStateRepository.php` — brak błędów składni. Publiczne metody: `getState`, `markRunStarted`, `markRunSuccess`, `markRunFailed` — wszystkie obecne. AC-3 spełnione: nowe repozytorium z poprawnym kontraktem istnieje Zadanie 2: Zaktualizuj `ShopproOrdersSyncService` — zamień zależność src/Modules/Settings/ShopproOrdersSyncService.php W `ShopproOrdersSyncService.php`: 1. Usuń import (use): `use App\Modules\Settings\AllegroOrderSyncStateRepository;` (jeśli istnieje jako osobna linia — plik jest w tym samym namespace więc może go nie mieć) 2. Zmień typ parametru w konstruktorze: ```php // PRZED: private readonly AllegroOrderSyncStateRepository $syncState, // PO: private readonly ShopproOrderSyncStateRepository $syncState, ``` 3. Nie zmieniaj nazwy zmiennej `$syncState` — żaden inny kod w pliku nie wymaga zmian. Uwagi: - Nie zmieniaj żadnych wywołań metod na `$this->syncState` — kontrakt jest identyczny - Nie zmieniaj kolejności parametrów konstruktora - Nie modyfikuj żadnej innej logiki w pliku `grep -n "AllegroOrderSyncStateRepository" src/Modules/Settings/ShopproOrdersSyncService.php` — brak wyników. `grep -n "ShopproOrderSyncStateRepository" src/Modules/Settings/ShopproOrdersSyncService.php` — obecny w typehintie konstruktora. `php -l src/Modules/Settings/ShopproOrdersSyncService.php` — brak błędów składni. AC-1, AC-2 spełnione: serwis używa poprawnego repozytorium Zadanie 3: Zaktualizuj `Application.php` — wstrzyknij `ShopproOrderSyncStateRepository` src/Core/Application.php W `Application.php`: 1. Dodaj import: `use App\Modules\Settings\ShopproOrderSyncStateRepository;` (w bloku use, razem z pozostałymi importami z Settings) 2. Znajdź miejsce tworzenia `ShopproOrdersSyncService` (linia ~296–301): ```php $shopproSyncService = new ShopproOrdersSyncService( ... new AllegroOrderSyncStateRepository($this->db), ... ); ``` Zamień `new AllegroOrderSyncStateRepository($this->db)` na `new ShopproOrderSyncStateRepository($this->db)` — tylko w tym jednym miejscu (przy tworzeniu `ShopproOrdersSyncService`). 3. Sprawdź, czy `AllegroOrderSyncStateRepository` jest nadal używane gdzie indziej w `Application.php` (przy tworzeniu `AllegroOrderImportService` lub podobnych). Jeśli tak — nie usuwaj jego importu. Usuń import tylko jeśli nie ma innych użyć. Uwagi: - Zachowaj kolejność argumentów konstruktora `ShopproOrdersSyncService` bez zmian - Nie zmieniaj wierszy niezwiązanych z `ShopproOrdersSyncService` W okolicach tworzenia `ShopproOrdersSyncService`: `new ShopproOrderSyncStateRepository($this->db)` jest obecne. Import `use App\Modules\Settings\ShopproOrderSyncStateRepository;` istnieje. `php -l src/Core/Application.php` — brak błędów składni. AC-4 spełnione: Application.php tworzy poprawne repozytorium dla shopPRO ## NIE ZMIENIAJ - `src/Modules/Settings/AllegroOrderSyncStateRepository.php` — nie modyfikuj oryginalnej klasy Allegro (inne serwisy mogą jej używać) - Tabela bazy danych `integration_order_sync_state` — nie dodawaj nowych kolumn, nie zmieniaj schematu - Logiki biznesowej synchronizacji w `ShopproOrdersSyncService` — wyłącznie zmiana zależności - Żadnych innych plików poza listą `files_modified` ## LIMITY ZAKRESU - Nie refaktoryzuj `ShopproOrdersSyncService` ponad wymaganą zmianę zależności (jest na to osobny concern — "1192 lines god class") - Nie wydzielaj interfejsu `OrderSyncStateRepositoryInterface` — to osobna praca poza zakresem planu - Nie przenoś klasy do innego namespace ani modułu Przed deklaracją zakończenia planu: - [ ] Plik `ShopproOrderSyncStateRepository.php` istnieje z poprawnymi metodami publicznymi - [ ] `ShopproOrdersSyncService.php` nie zawiera żadnego odwołania do `AllegroOrderSyncStateRepository` - [ ] `Application.php` wstrzykuje `ShopproOrderSyncStateRepository` przy tworzeniu `ShopproOrdersSyncService` - [ ] `php -l` wszystkich 3 zmienionych plików PHP — brak błędów składni - Wszystkie 3 zadania ukończone - Wszystkie 5 kryteriów akceptacji spełnione - Brak błędów składni PHP - Wpis z CONCERNS.md (Tech Debt — ShopproOrdersSyncService Uses AllegroOrderSyncStateRepository) usunięty po naprawieniu Po zakończeniu utwórz `.paul/phases/02-bug-fixes/02-03-SUMMARY.md`