---
phase: 98-order-imported-first-only
plan: 01
subsystem: automation
tags: [automation, order-import, allegro, shoppro, backfill]

requires:
  - phase: 84-order-imported-automation-event
    provides: order.imported event + AutomationService trigger plumbing

provides:
  - First-import-only gating for order.imported automation event
  - One-shot CLI backfill: orders w_realizacji + shipment -> wyslane
affects: [automation rules, allegro import, shoppro sync]

tech-stack:
  added: []
  patterns: ["Producer-side gating of automation events using $wasCreated flag"]

key-files:
  created:
    - bin/backfill_shipped_status_98.php
  modified:
    - src/Modules/Settings/AllegroOrderImportService.php
    - src/Modules/Settings/ShopproOrdersSyncService.php

key-decisions:
  - "Gate order.imported na producencie, bez nowego eventu order.first_imported"
  - "Backfill jednorazowy w bin/, idempotentny, przez OrdersRepository::updateOrderStatus"

patterns-established:
  - "Pre-existing $wasCreated flag jest jedynym zrodlem prawdy o pierwszym imporcie"

duration: ~25min
started: 2026-04-13
completed: 2026-04-13
---

# Phase 98 Plan 01: Order Imported First-Only + Status Backfill

**Event automatyzacji `order.imported` ogranicza sie do pierwszego importu zamowienia, a uszkodzone historyczne zamowienia (w realizacji + posiadana przesylka) zostaly przywrocone do statusu "wyslane".**

## Performance

| Metric | Value |
|--------|-------|
| Duration | ~25 min |
| Tasks | 2/2 completed |
| Files modified | 3 (2 src + 1 new bin) |

## Acceptance Criteria Results

| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Allegro re-import nie odpala order.imported | Pass | Warunek `$wasCreated && ...` w AllegroOrderImportService.php |
| AC-2: ShopPRO re-import nie odpala order.imported | Pass | Warunek `$wasCreated &&` dodany w ShopproOrdersSyncService.php |
| AC-3: Pierwszy import nadal triggeruje event | Pass | Logika niezmieniona dla `$wasCreated === true` |
| AC-4: Backfill statusow | Pass | 4/4 zamowien (#275, #340, #396, #422) zaktualizowano; drugi run = 0 (idempotentny) |

## Accomplishments

- Producer-side gating eliminuje regresje statusu "wyslane" -> "w realizacji" przy ponownych importach
- Skrypt `bin/backfill_shipped_status_98.php` napisany defensywnie: uzywa `OrdersRepository::updateOrderStatus`, dzieki czemu kazda zmiana ma wpis w `order_status_history` i `order_activity_log`
- Dry-run/apply/--use-remote zgodne z konwencja innych skryptow w `bin/`
- Backfill na produkcyjnej (lokalnie, przez DB_HOST_REMOTE) bazie wykonany: 4 zamowienia naprawione

## Files Created/Modified

| File | Change | Purpose |
|------|--------|---------|
| `src/Modules/Settings/AllegroOrderImportService.php` | Modified | Gate trigger `order.imported` na `$wasCreated` |
| `src/Modules/Settings/ShopproOrdersSyncService.php` | Modified | Gate trigger `order.imported` na `$wasCreated` (zachowane `!$wasPaymentTransition`) |
| `bin/backfill_shipped_status_98.php` | Created | Jednorazowy backfill statusow z pelnym audit trail |

## Decisions Made

| Decision | Rationale | Impact |
|----------|-----------|--------|
| Gating po stronie producenta zamiast nowego eventu `order.first_imported` | Najmniejsza zmiana, bez wplywu na konfiguracje regul ani UI; semantyka eventu pozostaje zgodna z phase 84 | Reguly pobrania zamowienia automatycznie staja sie "first import only" |
| Backfill wykonywany przez `OrdersRepository::updateOrderStatus`, nie bezposrednim UPDATE | Zachowanie historii statusow i activity logu | Pelny audit trail dla recznej naprawy danych |
| Skrypt obsluguje `--use-remote` (DB_HOST_REMOTE) | Zgodnie z CLAUDE.md: DB_HOST_REMOTE dla operacji recznych agenta | Mozliwosc uruchomienia z lokalnego srodowiska bez zmiany runtime |

## Deviations from Plan

| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed | 0 | - |
| Scope additions | 0 | - |
| Deferred | 0 | - |

Plan wykonany dokladnie wg specyfikacji.

## Issues Encountered

| Issue | Resolution |
|-------|------------|
| Lokalne MySQL niedostepne przy weryfikacji | Uzyto `--use-remote` (DB_HOST_REMOTE) zgodnie z konwencja CLAUDE.md |

## Verification Results

```
$ php -l src/Modules/Settings/AllegroOrderImportService.php
No syntax errors detected
$ php -l src/Modules/Settings/ShopproOrdersSyncService.php
No syntax errors detected
$ php -l bin/backfill_shipped_status_98.php
No syntax errors detected

$ php bin/backfill_shipped_status_98.php --dry-run --use-remote
[scan] candidates: 4
  [dry-run] order #275 -> wyslane
  [dry-run] order #340 -> wyslane
  [dry-run] order #396 -> wyslane
  [dry-run] order #422 -> wyslane

$ php bin/backfill_shipped_status_98.php --use-remote
[scan] candidates: 4
  [ok] order #275 -> wyslane
  [ok] order #340 -> wyslane
  [ok] order #396 -> wyslane
  [ok] order #422 -> wyslane
Backfill 98: total=4 updated=4 skipped=0

$ php bin/backfill_shipped_status_98.php --dry-run --use-remote
[scan] candidates: 0    # idempotency confirmed
```

## Next Phase Readiness

**Ready:**
- Reguly automatyzacji "Pobranie zamowienia" sa bezpieczne dla zamowien w obrocie
- Mechanizm `OrdersRepository::updateOrderStatus` potwierdzony dla skryptow CLI

**Concerns:**
- Manualny test przez uzytkownika (wymuszony re-import) nie jest jeszcze zarejestrowany w czasie tego Unify

**Blockers:** None

---
*Phase: 98-order-imported-first-only, Plan: 01*
*Completed: 2026-04-13*
