update
This commit is contained in:
176
.paul/phases/62-import-reimport-safety/62-01-PLAN.md
Normal file
176
.paul/phases/62-import-reimport-safety/62-01-PLAN.md
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
phase: 62-import-reimport-safety
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- src/Modules/Settings/ShopproOrdersSyncService.php
|
||||
- src/Modules/Orders/OrderImportRepository.php
|
||||
autonomous: true
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Naprawa dwóch problemów z re-importem zamówień:
|
||||
1. Rozróżnienie "Import" vs "Aktualizacja" w activity log dla shopPRO (analogicznie do Allegro) + deduplikacja
|
||||
2. Ochrona danych lokalnych (płatności, historia statusów, przesyłki) przed nadpisaniem przy re-imporcie — dla obu źródeł (shopPRO i Allegro)
|
||||
|
||||
## Purpose
|
||||
Obecnie re-import zamówienia kasuje DELETE+INSERT dane, które mogły zostać dodane lokalnie w orderPRO (ręczna płatność, zmiana statusu, przesyłka). Dodatkowo shopPRO loguje identyczne wpisy "Import zamówienia" przy każdym re-imporcie zamiast rozróżniać import od aktualizacji.
|
||||
|
||||
## Output
|
||||
- shopPRO activity log: "Import zamowienia z shopPRO" vs "Zaktualizowano zamowienie z shopPRO (re-import)" + deduplikacja jak Allegro
|
||||
- `upsertOrderAggregate` przy UPDATE pomija replace płatności, historii statusów i przesyłek (chroni dane lokalne)
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Source Files
|
||||
@src/Modules/Settings/ShopproOrdersSyncService.php (linia 205-259: importOneOrder — brak rozróżnienia create/update w activity log)
|
||||
@src/Modules/Settings/AllegroOrderImportService.php (linia 58-103: wzorcowa implementacja — rozróżnia import/aktualizacja + shouldSkipDuplicate)
|
||||
@src/Modules/Orders/OrderImportRepository.php (linia 25-64: upsertOrderAggregate — zawsze DELETE+INSERT na wszystkich relacjach)
|
||||
@src/Modules/Orders/OrdersRepository.php (linia 765-813: shouldSkipDuplicateImportActivity — istniejąca logika deduplikacji)
|
||||
</context>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: shopPRO activity log rozróżnia import od aktualizacji
|
||||
```gherkin
|
||||
Given zamówienie z shopPRO już istnieje w orderPRO
|
||||
When cron re-importuje to zamówienie (source_updated_at się zmieniło)
|
||||
Then w activity log pojawia się "Zaktualizowano zamowienie z shopPRO (re-import)" zamiast "Import zamowienia z shopPRO"
|
||||
```
|
||||
|
||||
## AC-2: shopPRO activity log deduplikuje identyczne wpisy
|
||||
```gherkin
|
||||
Given zamówienie z shopPRO zostało właśnie zaimportowane/zaktualizowane
|
||||
When cron próbuje re-importować z tym samym source_updated_at
|
||||
Then nowy wpis w activity log NIE jest tworzony (shouldSkipDuplicateImportActivity)
|
||||
```
|
||||
|
||||
## AC-3: Re-import nie kasuje lokalnych płatności
|
||||
```gherkin
|
||||
Given zamówienie ma płatność dodaną ręcznie w orderPRO
|
||||
When cron re-importuje to zamówienie z shopPRO lub Allegro
|
||||
Then ręcznie dodana płatność nie jest usunięta
|
||||
And płatności z importu są nadal poprawnie zapisywane przy pierwszym imporcie
|
||||
```
|
||||
|
||||
## AC-4: Re-import nie kasuje lokalnej historii statusów
|
||||
```gherkin
|
||||
Given zamówienie ma zmianę statusu wykonaną w orderPRO
|
||||
When cron re-importuje to zamówienie
|
||||
Then lokalna historia statusów nie jest usunięta
|
||||
And historia statusów z importu jest poprawnie zapisywana przy pierwszym imporcie
|
||||
```
|
||||
|
||||
## AC-5: Re-import nie kasuje lokalnych przesyłek importowych
|
||||
```gherkin
|
||||
Given zamówienie ma przesyłki zaimportowane lub utworzone w orderPRO
|
||||
When cron re-importuje to zamówienie
|
||||
Then przesyłki z order_shipments nie są usunięte
|
||||
And przesyłki z importu są poprawnie zapisywane przy pierwszym imporcie
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Activity log shopPRO — rozróżnienie import/aktualizacja + deduplikacja</name>
|
||||
<files>src/Modules/Settings/ShopproOrdersSyncService.php</files>
|
||||
<action>
|
||||
W metodzie `importOneOrder()` (linia 239-246) zmienić blok activity log analogicznie do AllegroOrderImportService (linia 71-94):
|
||||
|
||||
1. Po linii 234 (po sprawdzeniu `$save['created']`) dodać logikę:
|
||||
- Ustalić `$wasCreated = !empty($save['created'])`
|
||||
- Ustalić `$summary`:
|
||||
- Jeśli `$wasCreated`: `'Import zamowienia z shopPRO'`
|
||||
- Jeśli nie: `'Zaktualizowano zamowienie z shopPRO (re-import)'`
|
||||
2. Rozszerzyć `$details` o pola potrzebne do deduplikacji:
|
||||
- `'source_updated_at' => $sourceUpdatedAt`
|
||||
- `'created' => $wasCreated`
|
||||
- `'trigger' => 'orders_sync'`
|
||||
- `'trigger_label' => 'Synchronizacja zamowien'`
|
||||
3. Owinąć `recordActivity()` w warunek `shouldSkipDuplicateImportActivity()`:
|
||||
```php
|
||||
if (!$this->orders->shouldSkipDuplicateImportActivity((int) ($save['order_id'] ?? 0), $details)) {
|
||||
$this->orders->recordActivity(...);
|
||||
}
|
||||
```
|
||||
|
||||
Wzorzec: AllegroOrderImportService linia 71-94.
|
||||
</action>
|
||||
<verify>Przegląd kodu: shopPRO importOneOrder używa shouldSkipDuplicateImportActivity i rozróżnia summary</verify>
|
||||
<done>AC-1 i AC-2 satisfied</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: upsertOrderAggregate — pominięcie replace płatności/historii/przesyłek przy UPDATE</name>
|
||||
<files>src/Modules/Orders/OrderImportRepository.php</files>
|
||||
<action>
|
||||
W metodzie `upsertOrderAggregate()` (linia 25-64):
|
||||
|
||||
1. Przenieść wywołania `replacePayments`, `replaceShipments` i `replaceStatusHistory` do bloku warunkowego `if ($created)`:
|
||||
```php
|
||||
$this->replaceAddresses($orderId, $addresses);
|
||||
$this->replaceItems($orderId, $items);
|
||||
$this->replaceNotes($orderId, $notes);
|
||||
|
||||
if ($created) {
|
||||
$this->replacePayments($orderId, $payments);
|
||||
$this->replaceShipments($orderId, $shipments);
|
||||
$this->replaceStatusHistory($orderId, $statusHistory);
|
||||
}
|
||||
```
|
||||
|
||||
2. Logika:
|
||||
- Adresy i pozycje (items) — nadpisywane ZAWSZE (dane pochodzą ze źródła, nie są edytowane lokalnie)
|
||||
- Notatki — nadpisywane ZAWSZE (pochodzą ze źródła)
|
||||
- Płatności — tylko przy INSERT (ręczne płatności dodane w orderPRO nie zostaną skasowane)
|
||||
- Przesyłki (order_shipments) — tylko przy INSERT (lokalne przesyłki nie zostaną skasowane)
|
||||
- Historia statusów — tylko przy INSERT (lokalne zmiany statusów nie zostaną skasowane)
|
||||
|
||||
Ta zmiana dotyczy OBIE źródeł (shopPRO i Allegro) bo obie korzystają z tego samego repozytorium.
|
||||
</action>
|
||||
<verify>Przegląd kodu: replacePayments, replaceShipments, replaceStatusHistory wywoływane tylko gdy $created === true</verify>
|
||||
<done>AC-3, AC-4 i AC-5 satisfied</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- AllegroOrderImportService.php — Allegro już ma poprawną logikę activity log, nie modyfikować
|
||||
- OrdersRepository.php — shouldSkipDuplicateImportActivity() działa poprawnie, reuse bez zmian
|
||||
- Logika kursora (ShopproOrderMapper, ShopproOrderSyncStateRepository) — nie modyfikować
|
||||
- Tabele DB — brak migracji
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Brak kolumny `origin` w tabelach (to byłby etap 2, poza zakresem)
|
||||
- Nie zmieniamy logiki replace dla adresów, pozycji ani notatek (te dane pochodzą wyłącznie ze źródła)
|
||||
- Nie dodajemy nowego merge/diff — po prostu pomijamy replace przy update
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] shopPRO importOneOrder rozróżnia "Import" vs "Zaktualizowano (re-import)" w summary
|
||||
- [ ] shopPRO importOneOrder używa shouldSkipDuplicateImportActivity
|
||||
- [ ] upsertOrderAggregate: replacePayments/replaceShipments/replaceStatusHistory wywołane tylko przy $created
|
||||
- [ ] upsertOrderAggregate: replaceAddresses/replaceItems/replaceNotes wywołane zawsze (bez zmian)
|
||||
- [ ] Brak zmian w AllegroOrderImportService
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Activity log shopPRO rozróżnia import od aktualizacji
|
||||
- Duplikaty activity log eliminowane przez shouldSkipDuplicateImportActivity
|
||||
- Re-import nie kasuje lokalnych płatności, przesyłek ani historii statusów
|
||||
- Pierwsze importowanie zapisuje wszystkie dane normalnie
|
||||
- Brak regresji w imporcie Allegro
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/62-import-reimport-safety/62-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user