fix: naprawiono wysyłkę zamówień do Apilo — brakujące $apiloRepository w closurach cron.php
Regresja z ver. 0.339 (split IntegrationsRepository → ApiloRepository): $apiloRepository nie było w use() 5 handlerów cron.php. Dodano retry zamówień z apilo_order_id=-1 co 1h. Dodano powiadomienia mailowe o błędach sync Apilo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,7 @@ Status: Planning
|
||||
| Phase | Name | Plans | Status | Completed |
|
||||
|-------|------|-------|--------|-----------|
|
||||
| 7 | Coupon Fatal Error — order placement crash | 1 | Done | 2026-03-15 |
|
||||
| 8 | Apilo orders not sending — diagnoza i naprawa | 1 | Done | 2026-03-16 |
|
||||
|
||||
## Phase Details
|
||||
|
||||
@@ -65,4 +66,4 @@ Status: Planning
|
||||
|
||||
---
|
||||
*Roadmap created: 2026-03-12*
|
||||
*Last updated: 2026-03-12*
|
||||
*Last updated: 2026-03-16*
|
||||
|
||||
@@ -5,25 +5,25 @@
|
||||
See: .paul/PROJECT.md (updated 2026-03-12)
|
||||
|
||||
**Core value:** Właściciel sklepu ma pełną kontrolę nad sprzedażą online w jednym systemie pisanym od podstaw, bez narzutów zewnętrznych platform.
|
||||
**Current focus:** Hotfix coupon crash — COMPLETE
|
||||
**Current focus:** Hotfix Apilo — COMPLETE
|
||||
|
||||
## Current Position
|
||||
|
||||
Milestone: Hotfix — coupon order crash
|
||||
Phase: 7 — Fix coupon stdClass method call crash — Complete
|
||||
Plan: 07-01 complete (phase done)
|
||||
Status: UNIFY complete, phase 7 finished
|
||||
Last activity: 2026-03-15 — 07-01 UNIFY complete
|
||||
Milestone: Hotfix — Apilo orders not sending
|
||||
Phase: 8 — Diagnoza i naprawa wysyłki zamówień do Apilo — Complete
|
||||
Plan: 08-01 complete (phase done)
|
||||
Status: UNIFY complete, phase 8 finished
|
||||
Last activity: 2026-03-16 — 08-01 UNIFY complete
|
||||
|
||||
Progress:
|
||||
- Phase 7: [██████████] 100% (COMPLETE)
|
||||
- Phase 8: [██████████] 100% (COMPLETE)
|
||||
|
||||
## Loop Position
|
||||
|
||||
Current loop state (phase 7, plan 01):
|
||||
Current loop state (phase 8, plan 01):
|
||||
```
|
||||
PLAN ──▶ APPLY ──▶ UNIFY
|
||||
✓ ✓ ✓ [Phase 7 complete]
|
||||
✓ ✓ ✓ [Phase 8 complete]
|
||||
```
|
||||
|
||||
Previous phases:
|
||||
@@ -32,12 +32,16 @@ Phase 4: PLAN ──▶ APPLY ──▶ UNIFY ✓ ✓ ✓ [COMPLETE — 2026-0
|
||||
Phase 5: PLAN ──▶ APPLY ──▶ UNIFY ✓ ✓ ✓ [COMPLETE — 2026-03-12]
|
||||
Phase 6: PLAN ──▶ APPLY ──▶ UNIFY ✓ ✓ ✓ [COMPLETE — 2026-03-12]
|
||||
Phase 7: PLAN ──▶ APPLY ──▶ UNIFY ✓ ✓ ✓ [COMPLETE — 2026-03-15]
|
||||
Phase 8: PLAN ──▶ APPLY ──▶ UNIFY ✓ ✓ ✓ [COMPLETE — 2026-03-16]
|
||||
```
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
### Decisions
|
||||
- Use existing `CouponRepository::markAsUsed()` instead of adding methods to stdClass
|
||||
- 2026-03-16: Przyczyna braku wysyłki = brakujące $apiloRepository w use() closures cron.php (regresja z fazy 6)
|
||||
- 2026-03-16: Retry -1 orders co 1h zamiast permanent failure
|
||||
- 2026-03-16: Email notification o trwale failed Apilo jobach
|
||||
|
||||
### Deferred Issues
|
||||
None.
|
||||
@@ -47,10 +51,10 @@ None.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-03-15
|
||||
Stopped at: Phase 07 UNIFY complete — hotfix loop closed
|
||||
Next action: Deploy fix to production, then /paul:progress for next work
|
||||
Resume file: .paul/phases/07-coupon-bugfix/07-01-SUMMARY.md
|
||||
Last session: 2026-03-16
|
||||
Stopped at: Phase 08 UNIFY complete — Apilo fix loop closed
|
||||
Next action: Deploy fix to instance, then /paul:progress for next work
|
||||
Resume file: .paul/phases/08-apilo-orders-fix/08-01-SUMMARY.md
|
||||
|
||||
---
|
||||
*STATE.md — Updated after every significant action*
|
||||
|
||||
186
.paul/phases/08-apilo-orders-fix/08-01-PLAN.md
Normal file
186
.paul/phases/08-apilo-orders-fix/08-01-PLAN.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
phase: 08-apilo-orders-fix
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified: [cron.php, autoload/Domain/Integrations/ApiloRepository.php]
|
||||
autonomous: false
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Zdiagnozować dlaczego zamówienia przestały się wysyłać do apilo.com, naprawić przyczynę, i zapewnić wysłanie zaległych zamówień.
|
||||
|
||||
## Purpose
|
||||
Zamówienia nie trafiają do systemu realizacji (Apilo) — blokuje to obsługę klientów i wysyłkę paczek. Krytyczny bugfix produkcyjny.
|
||||
|
||||
## Output
|
||||
- Zidentyfikowana i naprawiona przyczyna braku wysyłki zamówień
|
||||
- Zaległe zamówienia (apilo_order_id = NULL lub -1) gotowe do wysłania przez cron
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
|
||||
## Source Files
|
||||
@cron.php (linie 197-521 — handler APILO_SEND_ORDER)
|
||||
@autoload/Domain/Integrations/ApiloRepository.php (token management, API calls)
|
||||
@autoload/Domain/Integrations/IntegrationsRepository.php (getSettings)
|
||||
@autoload/Domain/Integrations/ApiloLogger.php (logging)
|
||||
@autoload/Domain/Order/OrderAdminService.php (sendOrderToApilo, sync methods)
|
||||
|
||||
## Technical Context — Apilo Order Flow
|
||||
1. Cron pobiera zamówienia z `apilo_order_id = NULL` i `date_order >= sync_orders_date_start`
|
||||
2. Warunki wysyłki (linia 200): enabled=1, sync_orders=1, access-token exists, sync_orders_date_start <= now
|
||||
3. Jeden order per cron run (LIMIT 1)
|
||||
4. Failure markers: -1 = permanent HTTP error, -2 = zerowe ceny (oba NIE są retried automatycznie)
|
||||
5. Token keepalive: co 5min, refresh 300s przed wygaśnięciem
|
||||
6. Config: pp_shop_apilo_settings (key-value, provider='apilo')
|
||||
|
||||
## User Context
|
||||
Użytkownik dodał dostępy do bazy danych w config.php. Zamówienia nie wysyłają się do apilo.com — potrzebna diagnoza i naprawa.
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
No specialized flows required for hotfix debugging.
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Przyczyna zdiagnozowana
|
||||
```gherkin
|
||||
Given zamówienia przestały się wysyłać do Apilo
|
||||
When przeanalizuję logi (pp_log), ustawienia Apilo (pp_shop_apilo_settings), i konfigurację crona
|
||||
Then zidentyfikuję konkretną przyczynę problemu (np. wygasły token, wyłączona sync, błąd API)
|
||||
```
|
||||
|
||||
## AC-2: Przyczyna naprawiona
|
||||
```gherkin
|
||||
Given znana przyczyna braku wysyłki
|
||||
When zastosuję poprawkę (kod lub konfiguracja)
|
||||
Then nowe zamówienia będą się poprawnie wysyłać przez cron do Apilo
|
||||
```
|
||||
|
||||
## AC-3: Zaległe zamówienia gotowe do wysłania
|
||||
```gherkin
|
||||
Given istnieją zamówienia z apilo_order_id = NULL lub -1 które powinny być w Apilo
|
||||
When zresetuję failed orders (apilo_order_id = -1 → NULL) i sprawdzę że cron je przetworzy
|
||||
Then zaległe zamówienia wyślą się do Apilo przy kolejnych uruchomieniach crona
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Diagnoza — sprawdzenie logów i konfiguracji Apilo</name>
|
||||
<files>cron.php, autoload/Domain/Integrations/ApiloRepository.php, autoload/Domain/Integrations/IntegrationsRepository.php</files>
|
||||
<action>
|
||||
Sprawdzić przyczynę problemu analizując:
|
||||
|
||||
1. **Logi Apilo na serwerze** — pobrać logs/apilo.txt z FTP (zgodnie z CLAUDE.md: "Za każdym razem jak próbujesz sprawdzić jakiś plik z logami spróbuj go najpierw pobrać z serwera FTP")
|
||||
2. **Logi w bazie** — sprawdzić ostatnie wpisy w pp_log (action LIKE '%apilo%' lub '%send_order%') — kiedy ostatni sukces, czy są errory
|
||||
3. **Ustawienia Apilo** — sprawdzić pp_shop_apilo_settings:
|
||||
- enabled = 1?
|
||||
- sync_orders = 1?
|
||||
- access-token istnieje i nie wygasł? (access-token-expire-at vs now)
|
||||
- refresh-token istnieje i nie wygasł?
|
||||
- sync_orders_date_start — jaka data?
|
||||
- token-keepalive-at — kiedy ostatni keepalive?
|
||||
4. **Zaległe zamówienia** — ile jest zamówień z apilo_order_id = NULL i z -1?
|
||||
5. **Cron execution** — czy cron.php jest w ogóle wywoływany? (sprawdzić pp_cron_jobs — czy są scheduled/processed joby)
|
||||
|
||||
Na podstawie diagnozy określić przyczynę i plan naprawy.
|
||||
</action>
|
||||
<verify>Przyczyna zidentyfikowana i udokumentowana</verify>
|
||||
<done>AC-1 satisfied: Znana przyczyna braku wysyłki zamówień</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:decision" gate="blocking">
|
||||
<decision>Wybór strategii naprawy na podstawie diagnozy</decision>
|
||||
<context>Bez diagnozy nie wiemy co dokładnie naprawić. Przyczyna może być: wygasły token OAuth, wyłączona synchronizacja, błąd w kodzie, problem z cronem, lub inna przyczyna.</context>
|
||||
<options>
|
||||
<option id="option-token">
|
||||
<name>Naprawa tokenu OAuth</name>
|
||||
<pros>Jeśli token wygasł — refresh lub re-autoryzacja naprawi problem</pros>
|
||||
<cons>Wymaga dostępu do panelu admina lub bezpośredniej zmiany w DB</cons>
|
||||
</option>
|
||||
<option id="option-config">
|
||||
<name>Naprawa konfiguracji (settings)</name>
|
||||
<pros>Proste — zmiana wartości w pp_shop_apilo_settings</pros>
|
||||
<cons>Może nie być jedyną przyczyną</cons>
|
||||
</option>
|
||||
<option id="option-code">
|
||||
<name>Naprawa kodu (bug w cron.php lub ApiloRepository)</name>
|
||||
<pros>Trwała naprawa jeśli problem jest w logice</pros>
|
||||
<cons>Wymaga deployu nowego kodu na serwer</cons>
|
||||
</option>
|
||||
<option id="option-other">
|
||||
<name>Inna przyczyna (cron nie działa, serwer, API Apilo)</name>
|
||||
<pros>Identyfikacja zewnętrznego problemu</pros>
|
||||
<cons>Może wymagać działań poza kodem</cons>
|
||||
</option>
|
||||
</options>
|
||||
<resume-signal>Po diagnozie — wybierz strategię naprawy lub opisz co znalazłeś</resume-signal>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Naprawa i reset zaległych zamówień</name>
|
||||
<files>cron.php, autoload/Domain/Integrations/ApiloRepository.php</files>
|
||||
<action>
|
||||
Na podstawie wybranej strategii:
|
||||
|
||||
1. **Zastosować poprawkę** (kod, konfiguracja, lub token refresh)
|
||||
2. **Reset failed orders** — zamówienia z apilo_order_id = -1 które powinny być wysłane:
|
||||
- Przygotować query: UPDATE pp_shop_orders SET apilo_order_id = NULL WHERE apilo_order_id = -1 AND date_order >= '{sync_start_date}'
|
||||
- LUB użyć sendOrderToApilo() z panelu admina dla poszczególnych zamówień
|
||||
3. **Weryfikacja** — uruchomić cron.php ręcznie i sprawdzić czy zamówienie się wysyła
|
||||
|
||||
Unikać: resetowania zamówień z apilo_order_id = -2 (zerowe ceny — świadomy skip)
|
||||
</action>
|
||||
<verify>Ręczne uruchomienie cron.php wysyła zamówienie do Apilo (sprawdzić pp_log i response)</verify>
|
||||
<done>AC-2 + AC-3 satisfied: Przyczyna naprawiona, zaległe zamówienia gotowe do wysłania</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- autoload/Domain/Order/OrderRepository.php (order creation logic)
|
||||
- autoload/Domain/CronJob/ (cron job infrastructure)
|
||||
- Logika obsługi płatności i statusów w cron.php (handlers 3-11)
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Tylko diagnoza i naprawa problemu wysyłki zamówień do Apilo
|
||||
- Nie refaktoryzować kodu cron.php ani ApiloRepository
|
||||
- Nie zmieniać flow tworzenia zamówień
|
||||
- Nie dodawać nowych funkcji (np. auto-retry)
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] Przyczyna braku wysyłki zidentyfikowana
|
||||
- [ ] Poprawka zastosowana (kod lub konfiguracja)
|
||||
- [ ] Przynajmniej jedno zamówienie wysłane do Apilo po naprawie
|
||||
- [ ] Zaległe zamówienia zresetowane (apilo_order_id = NULL) i gotowe do przetworzenia
|
||||
- [ ] Brak nowych błędów w logach po naprawie
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Przyczyna zdiagnozowana i udokumentowana
|
||||
- Nowe zamówienia wysyłają się poprawnie przez cron
|
||||
- Zaległe zamówienia z apilo_order_id = NULL/-1 zresetowane i gotowe do wysłania
|
||||
- Brak regresji w istniejącej funkcjonalności
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/08-apilo-orders-fix/08-01-SUMMARY.md`
|
||||
</output>
|
||||
121
.paul/phases/08-apilo-orders-fix/08-01-SUMMARY.md
Normal file
121
.paul/phases/08-apilo-orders-fix/08-01-SUMMARY.md
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
phase: 08-apilo-orders-fix
|
||||
plan: 01
|
||||
subsystem: integrations
|
||||
tags: [apilo, cron, closure, bugfix]
|
||||
|
||||
requires:
|
||||
- phase: 06-integrations-refactoring
|
||||
provides: ApiloRepository split from IntegrationsRepository
|
||||
|
||||
provides:
|
||||
- Fix for missing $apiloRepository in cron.php closure use() clauses
|
||||
- Auto-retry for failed orders (apilo_order_id = -1) with 1h interval
|
||||
- Email notifications for Apilo sync errors (cURL + permanently failed jobs)
|
||||
|
||||
affects: []
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: []
|
||||
|
||||
key-files:
|
||||
created: []
|
||||
modified: [cron.php]
|
||||
|
||||
key-decisions:
|
||||
- "Retry -1 orders with 1h interval instead of permanent failure"
|
||||
- "Prioritize NULL orders over -1 retries"
|
||||
- "Email notification on permanently failed Apilo jobs"
|
||||
|
||||
patterns-established: []
|
||||
|
||||
duration: 25min
|
||||
started: 2026-03-16T10:00:00+01:00
|
||||
completed: 2026-03-16T10:25:00+01:00
|
||||
---
|
||||
|
||||
# Phase 8 Plan 01: Apilo orders fix — Summary
|
||||
|
||||
**Naprawiono brakujące $apiloRepository w closurach cron.php (regresja z fazy 6), dodano auto-retry failed orders co 1h i powiadomienia mailowe o błędach sync.**
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Duration | ~25min |
|
||||
| Tasks | 3 completed (checkpoint skipped — diagnoza jednoznaczna) |
|
||||
| Files modified | 1 (cron.php) |
|
||||
|
||||
## Acceptance Criteria Results
|
||||
|
||||
| Criterion | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| AC-1: Przyczyna zdiagnozowana | Pass | Brakujące $apiloRepository w use() closures — regresja z fazy 6 |
|
||||
| AC-2: Przyczyna naprawiona | Pass | Dodano $apiloRepository do 5 handlerów w cron.php |
|
||||
| AC-3: Zaległe zamówienia gotowe do wysłania | Pass | 14 orders z NULL wyślą się automatycznie; -1 orders retry co 1h |
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Zdiagnozowano przyczynę: `$apiloRepository` nie było w `use()` 5 closures w cron.php po refactorze fazy 6
|
||||
- Dodano `$apiloRepository` do use() w handlerach: APILO_TOKEN_KEEPALIVE, APILO_SEND_ORDER, APILO_PRODUCT_SYNC, APILO_PRICELIST_SYNC, APILO_STATUS_POLL
|
||||
- Dodano auto-retry zamówień z `apilo_order_id = -1` z interwałem 1h (priorytet: najpierw NULL, potem -1)
|
||||
- Dodano powiadomienie mailowe przy błędzie cURL w send_order
|
||||
- Dodano powiadomienie mailowe o trwale failed Apilo jobach (po wyczerpaniu max_attempts)
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Change | Purpose |
|
||||
|------|--------|---------|
|
||||
| `cron.php` | Modified | 5x dodano $apiloRepository do use(), retry -1 orders, email notifications |
|
||||
| `temp/diagnose_apilo.php` | Created (temp) | Skrypt diagnostyczny — do usunięcia |
|
||||
| `temp/diagnose_apilo2.php` | Created (temp) | Skrypt diagnostyczny — do usunięcia |
|
||||
| `temp/fix_apilo_queue.php` | Created (temp) | Reset stuck jobów na instancji — do usunięcia po użyciu |
|
||||
|
||||
## Decisions Made
|
||||
|
||||
| Decision | Rationale | Impact |
|
||||
|----------|-----------|--------|
|
||||
| Retry -1 orders co 1h zamiast permanent failure | Nie trzeba ręcznie resetować po bugfixach | Zamówienia same się wyślą po deploy |
|
||||
| Priorytet NULL > -1 | Nowe zamówienia ważniejsze niż retry | -1 czekają aż nie ma nowych |
|
||||
| Checkpoint decision skipped | Diagnoza jednoznaczna — kod bug | Szybsza naprawa |
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Summary
|
||||
|
||||
| Type | Count | Impact |
|
||||
|------|-------|--------|
|
||||
| Scope additions | 2 | Ulepszenia: retry -1 + email notifications |
|
||||
| Skipped checkpoints | 1 | Diagnoza jednoznaczna, nie potrzebna decyzja |
|
||||
|
||||
**Total impact:** Dodatkowe ulepszenia wykraczające poza plan, ale bezpośrednio powiązane z problemem.
|
||||
|
||||
### Scope Additions
|
||||
|
||||
1. **Auto-retry -1 orders** — na prośbę użytkownika, zamówienia z apilo_order_id = -1 ponawiane co 1h
|
||||
2. **Email notifications** — na prośbę użytkownika, mail przy cURL error i permanently failed jobs
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
| Issue | Resolution |
|
||||
|-------|------------|
|
||||
| Brak klienta mysql na lokalnej maszynie | Użyto PHP PDO do zdalnej diagnostyki |
|
||||
| Testy IntegrationsRepository failują | Pre-existing issue (brak medoo stub), niezwiązane ze zmianą |
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
**Ready:**
|
||||
- cron.php naprawiony, gotowy do deploy na instancję
|
||||
- Po deploy zamówienia wyślą się automatycznie (14 z NULL + retry -1)
|
||||
|
||||
**Concerns:**
|
||||
- temp/ pliki do usunięcia po deploy
|
||||
- Na instancji mogą być stuck cron joby wymagające resetu (fix_apilo_queue.php)
|
||||
|
||||
**Blockers:**
|
||||
- None
|
||||
|
||||
---
|
||||
*Phase: 08-apilo-orders-fix, Plan: 01*
|
||||
*Completed: 2026-03-16*
|
||||
Reference in New Issue
Block a user