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

221 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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
---
<objective>
## 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
</objective>
<context>
## 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
</context>
<skills>
## 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`
</skills>
<acceptance_criteria>
## 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`
```
</acceptance_criteria>
<tasks>
<task type="auto">
<name>Zadanie 1: Utwórz `ShopproOrderSyncStateRepository`</name>
<files>src/Modules/Settings/ShopproOrderSyncStateRepository.php</files>
<action>
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
</action>
<verify>
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.
</verify>
<done>AC-3 spełnione: nowe repozytorium z poprawnym kontraktem istnieje</done>
</task>
<task type="auto">
<name>Zadanie 2: Zaktualizuj `ShopproOrdersSyncService` — zamień zależność</name>
<files>src/Modules/Settings/ShopproOrdersSyncService.php</files>
<action>
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
</action>
<verify>
`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.
</verify>
<done>AC-1, AC-2 spełnione: serwis używa poprawnego repozytorium</done>
</task>
<task type="auto">
<name>Zadanie 3: Zaktualizuj `Application.php` — wstrzyknij `ShopproOrderSyncStateRepository`</name>
<files>src/Core/Application.php</files>
<action>
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`
</action>
<verify>
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.
</verify>
<done>AC-4 spełnione: Application.php tworzy poprawne repozytorium dla shopPRO</done>
</task>
</tasks>
<boundaries>
## 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
</boundaries>
<verification>
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
</verification>
<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>
<output>
Po zakończeniu utwórz `.paul/phases/02-bug-fixes/02-03-SUMMARY.md`
</output>