Files
orderPRO/.paul/phases/02-bug-fixes/02-03-PLAN.md
Jacek Pyziak 87203c4321 fix(02-bug-fixes): fix 3 known bugs from CONCERNS.md
Phase 02 plans 02-01, 02-02, 02-03:

- fix(02-01): dead condition in AllegroShipmentService ZPL page size
  Both ternary branches returned 'A6'; ZPL now correctly returns 'ZPL'

- fix(02-02): add last_status_checked_at cursor to AllegroStatusSyncService
  New migration adds orders.last_status_checked_at DATETIME NULL with
  composite index (source, source_updated_at). findOrdersNeedingStatusSync()
  filters by cursor; markOrderStatusChecked() records timestamp on success.

- fix(02-03): replace AllegroOrderSyncStateRepository in ShopproOrdersSyncService
  New ShopproOrderSyncStateRepository (same table, correct class name).
  Application.php wires correct repository to correct service.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 00:26:07 +01:00

9.6 KiB
Raw Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
02-bug-fixes 03 execute 1
src/Modules/Settings/ShopproOrderSyncStateRepository.php
src/Modules/Settings/ShopproOrdersSyncService.php
src/Core/Application.php
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

<acceptance_criteria>

AC-1: ShopproOrdersSyncService nie zależy od AllegroOrderSyncStateRepository

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

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

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

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ę

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`

</acceptance_criteria>

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 ~296301):
   ```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

<success_criteria>

  • 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 </success_criteria>
Po zakończeniu utwórz `.paul/phases/02-bug-fixes/02-03-SUMMARY.md`