feat(47-shipment-created-automation): immediate shipment automation trigger

Phase 47 complete:

- add event shipment.created triggered immediately after shipment creation

- add action update_shipment_status with real-change guard and chain-safe emit

- update automation UI/options, docs, and PAUL state artifacts
This commit is contained in:
2026-03-28 13:24:20 +01:00
parent d3f4bdaecd
commit ad9087d5e4
17 changed files with 784 additions and 310 deletions

View File

@@ -0,0 +1,210 @@
---
phase: 47-shipment-created-automation
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- src/Modules/Automation/AutomationController.php
- src/Modules/Automation/AutomationService.php
- src/Modules/Cron/CronHandlerFactory.php
- src/Modules/Shipments/ShipmentController.php
- src/Modules/Shipments/ShipmentPackageRepository.php
- resources/views/automation/form.php
- public/assets/js/modules/automation-form.js
- resources/views/automation/index.php
- DOCS/ARCHITECTURE.md
- DOCS/TECH_CHANGELOG.md
- DOCS/todo.md
autonomous: false
---
<objective>
## Goal
Dodac nowe zdarzenie automatyzacji `shipment.created`, ktore uruchamia sie od razu po utworzeniu przesylki w zamowieniu, oraz dodac nowa akcje automatyzacji `update_shipment_status` (UI: "Zmiana statusu przesylki").
## Purpose
Operator ma moc budowania automatyzacji natychmiast po wygenerowaniu przesylki (bez czekania na cron tracking) i moze reakcja reguly zmieniac status przesylki zgodnie z procesem operacyjnym firmy.
## Output
Kompletne rozszerzenie automatyzacji o:
- event `shipment.created` (natychmiastowy trigger),
- action `update_shipment_status`,
- konfiguracje w formularzu automatyzacji,
- aktualna dokumentacje techniczna.
</objective>
<context>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md
@DOCS/ARCHITECTURE.md
@DOCS/DB_SCHEMA.md
@DOCS/todo.md
## Prior Work (only if genuinely needed)
@.paul/phases/42-automation-shipment-status-event/42-01-PLAN.md
@.paul/phases/42-automation-shipment-status-event/42-01-SUMMARY.md
@.paul/phases/26-manual-tracking-number/26-01-SUMMARY.md
@.paul/phases/27-shipment-tracking-backend/27-01-SUMMARY.md
## Source Files
@src/Modules/Shipments/ShipmentController.php
@src/Modules/Shipments/ShipmentPackageRepository.php
@src/Modules/Automation/AutomationController.php
@src/Modules/Automation/AutomationService.php
@src/Modules/Cron/CronHandlerFactory.php
@resources/views/automation/form.php
@public/assets/js/modules/automation-form.js
@resources/views/automation/index.php
</context>
<skills>
## Required Skills (from SPECIAL-FLOWS.md)
| Skill | Priority | When to Invoke | Loaded? |
|-------|----------|----------------|---------|
| `sonar-scanner` | required | Po APPLY, przed UNIFY | o |
| /feature-dev | optional | Przed wdrazaniem nowej funkcjonalnosci | o |
| /code-review | optional | Po APPLY, przed UNIFY | o |
**BLOCKING:** Required skills MUST be loaded before APPLY proceeds.
## Skill Invocation Checklist
- [ ] `sonar-scanner` uruchomiony po APPLY
- [ ] /feature-dev (opcjonalnie)
- [ ] /code-review (opcjonalnie)
</skills>
<acceptance_criteria>
## AC-1: Event "Utworzenie przesylki" uruchamia sie natychmiast po sukcesie utworzenia
```gherkin
Given istnieje aktywna regula automatyzacji z eventem `shipment.created`
When uzytkownik utworzy przesylke dla zamowienia (provider API lub recznie)
Then system wywola AutomationService trigger w tym samym flow requestu
And nie wymaga to oczekiwania na cron `shipment_tracking_sync`
```
## AC-2: Nowa akcja "Zmiana statusu przesylki" jest konfigurowalna i walidowana
```gherkin
Given uzytkownik tworzy/edytuje regule automatyzacji
When dodaje akcje "Zmiana statusu przesylki"
Then moze wskazac docelowy status przesylki z dozwolonej listy
And zapis nie przechodzi dla nieprawidlowej konfiguracji akcji
```
## AC-3: Akcja poprawnie aktualizuje status przesylki i nie powoduje petli
```gherkin
Given regula uruchamia akcje `update_shipment_status`
When akcja jest wykonana dla zamowienia z paczka
Then status paczki zostaje zaktualizowany tylko przy realnej zmianie
And system nie wchodzi w nieskonczone petle triggerow automatyzacji
```
## AC-4: UI i dokumentacja sa spójne z nowymi elementami automatyzacji
```gherkin
Given wdrozenie nowego eventu i akcji
When uzytkownik otworzy formularz automatyzacji
Then widzi event "Utworzenie przesylki" i akcje "Zmiana statusu przesylki"
And ARCHITECTURE/TECH_CHANGELOG/todo opisuja zakres i ograniczenia implementacji
```
</acceptance_criteria>
<tasks>
<task type="auto">
<name>Task 1: Dodaj event `shipment.created` i natychmiastowy trigger po utworzeniu przesylki</name>
<files>src/Modules/Automation/AutomationController.php, src/Modules/Shipments/ShipmentController.php, src/Modules/Automation/AutomationService.php</files>
<action>
Rozszerz ALLOWED_EVENTS i etykiety UI o `shipment.created` ("Utworzenie przesylki").
W `ShipmentController::create()` i `ShipmentController::createManual()` po potwierdzonym utworzeniu paczki wywolaj `AutomationService->trigger('shipment.created', orderId, context)`.
Context powinien zawierac co najmniej: package_id, provider, tracking_number (jezeli dostepny), package_status.
Unikaj triggera w sciezkach bledu tworzenia przesylki.
</action>
<verify>rg -n "shipment\.created|trigger\('shipment\.created'|Utworzenie przesylki" src/Modules/Automation src/Modules/Shipments resources/views/automation</verify>
<done>AC-1 satisfied: event jest dostepny i odpalany od razu po utworzeniu przesylki.</done>
</task>
<task type="auto">
<name>Task 2: Dodaj akcje `update_shipment_status` i wykonanie backend</name>
<files>src/Modules/Automation/AutomationController.php, src/Modules/Automation/AutomationService.php, src/Modules/Shipments/ShipmentPackageRepository.php, src/Modules/Cron/CronHandlerFactory.php</files>
<action>
Dodaj nowy typ akcji do walidacji i parsera konfiguracji: `update_shipment_status`.
Konfiguracja akcji: docelowy status dostawy (`delivery_status`) z tej samej mapy statusow biznesowych co warunki shipment_status.
W `AutomationService` dodaj handler akcji, ktory wyszukuje docelowa paczke (z context package_id lub fallback: najnowsza aktywna paczka zamowienia) i wykonuje aktualizacje statusu tylko przy realnej zmianie.
Dodaj zabezpieczenie anty-petla: nie emituj kolejnego eventu przy braku zmiany; przy zmianie oznacz context zrodla automatyzacji i respektuj chain dedup.
Zaktualizuj factory DI, by serwis automatyzacji mial dostep do repo paczek.
</action>
<verify>rg -n "update_shipment_status|handleUpdateShipmentStatus|delivery_status|ALLOWED_ACTION_TYPES" src/Modules/Automation src/Modules/Shipments src/Modules/Cron</verify>
<done>AC-2 satisfied i AC-3 satisfied: akcja jest walidowana, wykonuje realna zmiane i nie petli sie.</done>
</task>
<task type="auto">
<name>Task 3: Rozszerz formularz automatyzacji oraz dokumentacje techniczna</name>
<files>resources/views/automation/form.php, public/assets/js/modules/automation-form.js, resources/views/automation/index.php, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md, DOCS/todo.md</files>
<action>
Dodaj opcje akcji "Zmiana statusu przesylki" do formularza oraz dynamiczny config (wybor statusu).
Zapewnij zgodnosc renderu create/edit i JS add-row.
Zaktualizuj dokumentacje: nowy event natychmiastowy i nowa akcja, z opisem kontekstu oraz ograniczen.
Dodaj/uzupelnij wpis w `DOCS/todo.md` dla nowego zakresu (zamkniecie po wdrozeniu).
</action>
<verify>rg -n "shipment\.created|Zmiana statusu przesylki|update_shipment_status" resources/views/automation public/assets/js/modules/automation-form.js DOCS/ARCHITECTURE.md DOCS/TECH_CHANGELOG.md DOCS/todo.md</verify>
<done>AC-4 satisfied: UI i dokumentacja sa spójne z wdrozonym zakresem.</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<what-built>Nowy natychmiastowy event `shipment.created` oraz nowa akcja automatyzacji `update_shipment_status`.</what-built>
<how-to-verify>
1. Otworz: Ustawienia > Zadania automatyczne > Dodaj zadanie.
2. Sprawdz event "Utworzenie przesylki" i akcje "Zmiana statusu przesylki".
3. Utworz regule: event `shipment.created`, warunek integracji, akcja zmiany statusu przesylki.
4. Utworz przesylke z poziomu zamowienia i potwierdz, ze regula wykonala sie od razu (bez cron).
5. Potwierdz, ze ponowne odpalenie bez realnej zmiany statusu nie generuje petli.
</how-to-verify>
<resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
</task>
</tasks>
<boundaries>
## DO NOT CHANGE
- `database/migrations/*` (brak zmian schematu w tej fazie)
- Logika eventu `receipt.created` i istniejace akcje poza wymaganym rozszerzeniem
- Moduly niezwiazane z automatyzacja i przesylkami
## SCOPE LIMITS
- Tylko nowe zdarzenie i nowa akcja w module automatyzacji.
- Bez przebudowy calego silnika cron/tracking.
- Bez zmian UX poza formularzem i listowaniem automatyzacji.
</boundaries>
<verification>
Before declaring plan complete:
- [ ] `C:\xampp\php\php.exe -l src/Modules/Automation/AutomationController.php`
- [ ] `C:\xampp\php\php.exe -l src/Modules/Automation/AutomationService.php`
- [ ] `C:\xampp\php\php.exe -l src/Modules/Shipments/ShipmentController.php`
- [ ] `C:\xampp\php\php.exe -l src/Modules/Shipments/ShipmentPackageRepository.php`
- [ ] `C:\xampp\php\php.exe -l src/Modules/Cron/CronHandlerFactory.php`
- [ ] `C:\xampp\php\php.exe -l resources/views/automation/form.php`
- [ ] `C:\xampp\php\php.exe -l resources/views/automation/index.php`
- [ ] Manual checkpoint wykonany (event dziala od razu + akcja statusu)
- [ ] Dokumentacja zaktualizowana (`DOCS/ARCHITECTURE.md`, `DOCS/TECH_CHANGELOG.md`, `DOCS/todo.md`)
- [ ] All acceptance criteria met
</verification>
<success_criteria>
- Event `shipment.created` uruchamia automatyzacje natychmiast po utworzeniu przesylki.
- Akcja `update_shipment_status` jest dostepna, walidowana i dziala przewidywalnie.
- Brak petli automatyzacji przy ponownych wywolaniach bez zmiany statusu.
- Dokumentacja techniczna odzwierciedla nowy kontrakt event/action.
</success_criteria>
<output>
After completion, create `.paul/phases/47-shipment-created-automation/47-01-SUMMARY.md`
</output>

View File

@@ -0,0 +1,51 @@
---
phase: 47-shipment-created-automation
plan: 01
status: completed
completed: 2026-03-28
---
# Phase 47 Plan 01 Summary
## Result
- Dodano nowe zdarzenie automatyzacji `shipment.created` (UI: `Utworzenie przesylki`).
- Trigger `shipment.created` jest uruchamiany od razu po sukcesie tworzenia przesylki:
- `ShipmentController::create()` (provider API),
- `ShipmentController::createManual()` (reczny numer przesylki).
- Dodano nowy typ akcji automatyzacji `update_shipment_status` (UI: `Zmiana statusu przesylki`).
- `AutomationService` wykonuje aktualizacje `delivery_status` tylko przy realnej zmianie, zapisuje activity log i emituje `shipment.status_changed` z kontekstem zmiany.
## Acceptance Criteria
- AC-1: Pass
- AC-2: Pass
- AC-3: Pass
- AC-4: Pass
## Verification
- `C:\xampp\php\php.exe -l src/Modules/Automation/AutomationController.php` PASS
- `C:\xampp\php\php.exe -l src/Modules/Automation/AutomationService.php` PASS
- `C:\xampp\php\php.exe -l src/Modules/Shipments/ShipmentController.php` PASS
- `C:\xampp\php\php.exe -l src/Modules/Shipments/ShipmentPackageRepository.php` PASS
- `C:\xampp\php\php.exe -l src/Modules/Cron/CronHandlerFactory.php` PASS
- `C:\xampp\php\php.exe -l routes/web.php` PASS
- `C:\xampp\php\php.exe -l resources/views/automation/form.php` PASS
- `C:\xampp\php\php.exe -l resources/views/automation/index.php` PASS
- `rg -n "shipment\.created|update_shipment_status|shipment_status_key|automation_shipment_status_updated" src resources public routes` PASS
- `sonar-scanner` PASS (analysis successful): https://sonar.project-pro.pl/dashboard?id=orderPRO
## Manual Checkpoint
- UAT checkpoint wykonany i zatwierdzony przez uzytkownika (`approved`).
## Files
- `src/Modules/Automation/AutomationController.php`
- `src/Modules/Automation/AutomationService.php`
- `src/Modules/Cron/CronHandlerFactory.php`
- `src/Modules/Shipments/ShipmentController.php`
- `src/Modules/Shipments/ShipmentPackageRepository.php`
- `routes/web.php`
- `resources/views/automation/form.php`
- `resources/views/automation/index.php`
- `public/assets/js/modules/automation-form.js`
- `DOCS/ARCHITECTURE.md`
- `DOCS/TECH_CHANGELOG.md`
- `DOCS/todo.md`