---
phase: 02-bug-fixes
plan: 02
subsystem: database, cron
tags: [allegro, status-sync, cursor, migration]

requires:
  - phase: 02-bug-fixes
    provides: Plan 02-01 (dead code fix in AllegroShipmentService)

provides:
  - Kolumna orders.last_status_checked_at z indeksem (source, source_updated_at)
  - Kursor kursorowy w findOrdersNeedingStatusSync()
  - Zapis timestampu po sukcesie importu (markOrderStatusChecked)

affects: cron-status-sync, allegro-order-import

tech-stack:
  added: []
  patterns: [cursor-based-sync, timestamp-marker]

key-files:
  created:
    - database/migrations/20260312_000047_add_last_status_checked_at_to_orders.sql
  modified:
    - src/Modules/Settings/AllegroStatusSyncService.php

key-decisions:
  - "Indeks kompozytowy (source, source_updated_at) zamiast single-column (last_status_checked_at) — code review wykazał że single-column jest bezużyteczny dla zapytania"
  - "markOrderStatusChecked() ciche Throwable — nie przerywać pętli sync z powodu błędu logu"

patterns-established:
  - "Cursor pattern: last_status_checked_at NULL OR source_updated_at > last_status_checked_at"

duration: ~30min
started: 2026-03-13T00:00:00Z
completed: 2026-03-13T00:00:00Z
---

# Phase 02 Plan 02: Kursor last_status_checked_at w AllegroStatusSyncService

**Dodano kursor czasowy do sync statusów Allegro — zamówienia nie są re-importowane gdy status nie zmienił się.**

## Performance

| Metric | Value |
|--------|-------|
| Duration | ~30min |
| Started | 2026-03-13 |
| Completed | 2026-03-13 |
| Tasks | 2/2 completed |
| Files modified | 2 |

## Acceptance Criteria Results

| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Zamówienia z aktualnym timestampem pomijane | Pass | `source_updated_at > last_status_checked_at` |
| AC-2: Zamówienia bez sprawdzenia uwzględniane | Pass | `last_status_checked_at IS NULL` |
| AC-3: Timestamp zapisywany po sukcesie | Pass | `markOrderStatusChecked()` w try, nie w catch |
| AC-4: Migracja bez destrukcji danych | Pass | `NULL DEFAULT NULL` — istniejące wiersze = NULL |

## Accomplishments

- Migracja SQL dodaje kolumnę `orders.last_status_checked_at DATETIME NULL`
- `findOrdersNeedingStatusSync()` filtruje tylko zamówienia gdzie status mógł się zmienić
- `markOrderStatusChecked()` aktualizuje timestamp po każdym sukcesie importu
- Code review poprawił indeks: kompozytowy `(source, source_updated_at)` zamiast bezużytecznego single-column

## Files Created/Modified

| File | Change | Purpose |
|------|--------|---------|
| `database/migrations/20260312_000047_add_last_status_checked_at_to_orders.sql` | Created | Migracja: nowa kolumna + indeks kompozytowy |
| `src/Modules/Settings/AllegroStatusSyncService.php` | Modified | Kursor + markOrderStatusChecked() |

## Decisions Made

| Decision | Rationale | Impact |
|----------|-----------|--------|
| Indeks kompozytowy `(source, source_updated_at)` | Code review: single-column na `last_status_checked_at` nieużywany przez zapytanie z `source = ?` | Lepsza wydajność zapytania kursorowego |
| `markOrderStatusChecked()` swallows Throwable | Błąd zapisu timestampu nie może przerywać pętli synchronizacji | Degradacja graceful — zamówienie zostanie ponowione |

## Deviations from Plan

### Auto-fixed Issues

**1. Indeks SQL — zmiana z single-column na kompozytowy**
- **Found during:** Code review po implementacji
- **Issue:** Plan zakładał `ADD INDEX orders_status_check_idx (last_status_checked_at)` — bezużyteczny dla zapytania z wiodącym filtrem `source = ?`
- **Fix:** Zamieniony na `ADD INDEX orders_source_updated_idx (source, source_updated_at)`
- **Files:** `database/migrations/20260312_000047_add_last_status_checked_at_to_orders.sql`
- **Verification:** Logika zapytania potwierdza, że MySQL użyje indeksu z wiodącą kolumną `source`

### Deferred Items

- Duplikacja kodu `AllegroOrderSyncStateRepository` / `ShopproOrderSyncStateRepository` (brak abstrakcji) — poza zakresem planu 02-03, do rozważenia w osobnym planie

## Issues Encountered

None.

## Skill Audit

| Skill | Status | Notes |
|-------|--------|-------|
| /code-review | ✓ | Wywołany — wykazał błąd indeksu, naprawiony |
| sonar-scanner | ✓ | Uruchomiony — brak nowych issues w zmienionych plikach |

## Next Phase Readiness

**Ready:**
- Kursor `last_status_checked_at` gotowy po uruchomieniu migracji na bazie
- Migracja idempotentna (nullable column, nie psuje istniejących danych)

**Concerns:**
- Migracja musi być uruchomiona ręcznie lub przez migrator przed pierwszym cron run
- AllegroStatusSyncService nadal ma problem wydajności — każde zamówienie = pełny re-import z API (oddzielny concern w CONCERNS.md)

**Blockers:** None

---
*Phase: 02-bug-fixes, Plan: 02*
*Completed: 2026-03-13*
