feat: database-backed cron job queue replacing JSON file system
Replace file-based JSON cron queue with DB-backed job queue (pp_cron_jobs, pp_cron_schedules). New Domain\CronJob module: CronJobType (constants), CronJobRepository (CRUD, atomic fetch, retry/backoff), CronJobProcessor (orchestration with handler registration). Priority ordering guarantees apilo_send_order (40) runs before sync tasks (50). Includes cron.php auth protection, race condition fix in fetchNext, API response validation, and DI wiring across all entry points. 41 new tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,27 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze.
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.324 (2026-02-27) - System kolejki zadań cron
|
||||
|
||||
- **NEW**: `Domain\CronJob\CronJobType` — stałe typów zadań, priorytetów, statusów, exponential backoff
|
||||
- **NEW**: `Domain\CronJob\CronJobRepository` — CRUD na `pp_cron_jobs` + `pp_cron_schedules` (enqueue, fetchNext, markCompleted, markFailed, hasPendingJob, cleanup, recoverStuck, getDueSchedules, touchSchedule)
|
||||
- **NEW**: `Domain\CronJob\CronJobProcessor` — orkiestracja: rejestracja handlerów, tworzenie scheduled jobs, przetwarzanie kolejki z priorytetami i retry/backoff
|
||||
- **NEW**: Tabele `pp_cron_jobs` i `pp_cron_schedules` — kolejka zadań z priorytetami, exponential backoff, harmonogram cykliczny
|
||||
- **REFACTOR**: `cron.php` — zastąpienie monolitycznego ~550 linii orkiestratorem z CronJobProcessor i zarejestrowanymi handlerami
|
||||
- **REFACTOR**: `OrderAdminService::queueApiloSync()` — kolejkowanie przez `CronJobRepository::enqueue()` zamiast pliku JSON
|
||||
- **REFACTOR**: `OrderAdminService::syncApiloPayment()`, `syncApiloStatus()` — zmiana z private na public (używane przez handlery cron)
|
||||
- **REMOVED**: `OrderAdminService::processApiloSyncQueue()`, `loadApiloSyncQueue()`, `saveApiloSyncQueue()`, `apiloSyncQueuePath()`, stała `APILO_SYNC_QUEUE_FILE`
|
||||
- **NEW**: Jednorazowa migracja JSON queue → DB w cron.php (automatyczna przy pierwszym uruchomieniu)
|
||||
- **SECURITY**: `cron.php` — ochrona endpointu: wymaga `$config['cron_key']` w URL (`?key=...`) lub trybu CLI
|
||||
- **FIX**: `CronJobRepository::fetchNext()` — re-SELECT po UPDATE eliminuje race condition przy równoległych workerach
|
||||
- **FIX**: `cron.php` — null check dla `$mdb->query()` przed `->fetch()` / `->fetchAll()` (3 miejsca)
|
||||
- **FIX**: `cron.php` — walidacja odpowiedzi curl w APILO_PRODUCT_SYNC i APILO_PRICELIST_SYNC (zapobiega zapisaniu null do bazy)
|
||||
- **FIX**: DI wiring — `CronJobRepository` przekazywany do `OrderAdminService` we wszystkich 4 punktach: `admin\App`, `api\ApiRouter`, `front\App`, `cron.php`
|
||||
- **TESTS**: 41 nowych testów CronJob (CronJobTypeTest, CronJobRepositoryTest, CronJobProcessorTest)
|
||||
- **MIGRATION**: `migrations/0.324.sql`
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.323 (2026-02-24) - Import zdjęć, trwałe usuwanie, fix API upload
|
||||
|
||||
- **FIX**: `IntegrationsRepository::shopproImportProduct()` — kompletny refactor importu zdjęć: walidacja HTTP response, curl timeouty, bezpieczna budowa URL, szczegółowy log do `logs/shoppro-import-debug.log` i `error_log`, czytelny komunikat z wynikiem
|
||||
|
||||
@@ -654,3 +654,49 @@ Tlumaczenia producentow (per jezyk). FK kaskadowe ON DELETE CASCADE.
|
||||
**Aktualizacja 2026-02-15 (ver. 0.273):** modul `/admin/shop_producer` korzysta z `Domain\Producer\ProducerRepository` przez `admin\Controllers\ShopProducerController`. Usunieto legacy `admin\controls\ShopProducer` i `admin\factory\ShopProducer`. `shop\Producer` dziala jako fasada do repozytorium.
|
||||
|
||||
**Aktualizacja 2026-02-17 (ver. 0.291):** frontend `/shop_producer/*` korzysta z `Domain\Producer\ProducerRepository` przez `front\Controllers\ShopProducerController`; usunięto legacy `front\controls\ShopProducer` i `shop\Producer`.
|
||||
|
||||
## pp_cron_jobs
|
||||
Kolejka zadań cron z priorytetami i retry/backoff.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK auto increment |
|
||||
| job_type | Typ zadania (VARCHAR 50) — np. apilo_send_order, price_history |
|
||||
| status | ENUM: pending, processing, completed, failed, cancelled |
|
||||
| priority | TINYINT — niższy = ważniejszy (10=krytyczny, 50=wysoki, 100=normalny, 200=niski) |
|
||||
| payload | JSON z danymi zadania (TEXT NULL) |
|
||||
| result | JSON z wynikiem (TEXT NULL) |
|
||||
| attempts | Liczba prób (SMALLINT) |
|
||||
| max_attempts | Maksymalna liczba prób (SMALLINT, domyślnie 10) |
|
||||
| last_error | Ostatni błąd (VARCHAR 500) |
|
||||
| scheduled_at | Kiedy zadanie ma być uruchomione (DATETIME) |
|
||||
| started_at | Kiedy rozpoczęto przetwarzanie (DATETIME NULL) |
|
||||
| completed_at | Kiedy zakończono (DATETIME NULL) |
|
||||
| created_at | Data utworzenia (DATETIME) |
|
||||
| updated_at | Data ostatniej modyfikacji (DATETIME, ON UPDATE) |
|
||||
|
||||
**Indeksy:** idx_status_priority_scheduled (status, priority, scheduled_at), idx_job_type, idx_status
|
||||
|
||||
**Używane w:** `Domain\CronJob\CronJobRepository`, `Domain\CronJob\CronJobProcessor`
|
||||
|
||||
## pp_cron_schedules
|
||||
Harmonogram cyklicznych zadań cron.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK auto increment |
|
||||
| job_type | Typ zadania (VARCHAR 50, UNIQUE) |
|
||||
| interval_seconds | Interwał uruchomienia w sekundach |
|
||||
| priority | Priorytet tworzonych zadań (TINYINT) |
|
||||
| max_attempts | Maks. prób dla tworzonych zadań (SMALLINT) |
|
||||
| payload | Opcjonalny payload JSON (TEXT NULL) |
|
||||
| enabled | Czy harmonogram aktywny (TINYINT 1) |
|
||||
| last_run_at | Ostatnie uruchomienie (DATETIME NULL) |
|
||||
| next_run_at | Następne planowane uruchomienie (DATETIME NULL) |
|
||||
| created_at | Data utworzenia (DATETIME) |
|
||||
|
||||
**Indeksy:** idx_enabled_next_run (enabled, next_run_at)
|
||||
|
||||
**Używane w:** `Domain\CronJob\CronJobRepository`, `Domain\CronJob\CronJobProcessor`
|
||||
|
||||
**Dodano w wersji 0.324.**
|
||||
|
||||
@@ -16,6 +16,7 @@ Kazdy modul zawiera Repository (i opcjonalnie dodatkowe klasy). Konstruktor DI z
|
||||
| Category | CategoryRepository | drzewa kategorii, produkty w kategorii, Redis cache |
|
||||
| Client | ClientRepository | CRUD, auth, adresy, zamowienia |
|
||||
| Coupon | CouponRepository | kupony rabatowe, walidacja, uzycie |
|
||||
| CronJob | CronJobType, CronJobRepository, CronJobProcessor | kolejka zadan cron (DB), priorytety, retry/backoff, harmonogram |
|
||||
| Dashboard | DashboardRepository | statystyki admin, Redis cache |
|
||||
| Dictionaries | DictionariesRepository | slowniki admin |
|
||||
| Integrations | IntegrationsRepository | Apilo sync, ustawienia |
|
||||
|
||||
@@ -23,7 +23,7 @@ composer test # standard
|
||||
## Aktualny stan
|
||||
|
||||
```text
|
||||
OK (765 tests, 2153 assertions)
|
||||
OK (805 tests, 2253 assertions)
|
||||
```
|
||||
|
||||
Zweryfikowano: 2026-02-24 (ver. 0.318)
|
||||
@@ -52,6 +52,9 @@ tests/
|
||||
| | |-- Cache/CacheRepositoryTest.php
|
||||
| | |-- Category/CategoryRepositoryTest.php
|
||||
| | |-- Coupon/CouponRepositoryTest.php
|
||||
| | |-- CronJob/CronJobTypeTest.php
|
||||
| | |-- CronJob/CronJobRepositoryTest.php
|
||||
| | |-- CronJob/CronJobProcessorTest.php
|
||||
| | |-- Dictionaries/DictionariesRepositoryTest.php
|
||||
| | |-- Integrations/IntegrationsRepositoryTest.php
|
||||
| | |-- Languages/LanguagesRepositoryTest.php
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
1. Dodać przycisk kopiowania przy atrybutach produktu w zamówieniu
|
||||
1. Dodać przycisk kopiowania przy atrybutach produktu w zamówieniu
|
||||
2. Poprawić htaccess, żeby w nim nie było w ogóle adresów strona wszystko z bazy.
|
||||
3. Dodać uwierzytelnienie dwuskładnikowe za pomocą aplikacji.
|
||||
Reference in New Issue
Block a user