update
This commit is contained in:
196
.paul/phases/107-automation-email-send-once/107-01-PLAN.md
Normal file
196
.paul/phases/107-automation-email-send-once/107-01-PLAN.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
phase: 107-automation-email-send-once
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- database/migrations/20260425_000102_create_automation_email_once_deliveries_table.sql
|
||||
- src/Modules/Automation/AutomationController.php
|
||||
- src/Modules/Automation/AutomationRepository.php
|
||||
- src/Modules/Automation/AutomationService.php
|
||||
- src/Modules/Automation/AutomationEmailOnceRepository.php
|
||||
- resources/views/automation/form.php
|
||||
- public/assets/js/modules/automation-form.js
|
||||
- src/Modules/Cron/CronHandlerFactory.php
|
||||
- tests/Unit/AutomationServiceTest.php
|
||||
- .paul/docs/DB_SCHEMA.md
|
||||
- .paul/docs/ARCHITECTURE.md
|
||||
- .paul/docs/TECH_CHANGELOG.md
|
||||
autonomous: true
|
||||
delegation: off
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Dodac w akcji automatyzacji `send_email` opcje "wyslij tylko raz na zamowienie", ktora gwarantuje, ze dla tej samej reguly i tego samego zamowienia ten sam mail nie zostanie wyslany ponownie przy kolejnych przebiegach crona.
|
||||
|
||||
## Purpose
|
||||
Event `order.status_aged` jest uruchamiany cyklicznie. Bez mechanizmu idempotencji klient moze dostawac ten sam mail przy kazdym przebiegu. Potrzebujemy bezpiecznego "once per order", ale tylko tam, gdzie operator swiadomie zaznaczy taka opcje.
|
||||
|
||||
## Output
|
||||
- Checkbox w konfiguracji akcji `Wyslij e-mail`: "Wyslij tylko raz dla tego zamowienia"
|
||||
- Trwale zapamietanie wysylki jednorazowej per `rule_id + action_id + order_id`
|
||||
- Logika wykonania, ktora pomija ponowna wysylke tylko dla akcji z wlaczonym checkboxem
|
||||
- Testy jednostkowe dla scenariusza jednorazowego i scenariusza domyslnego (wielokrotnego)
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
|
||||
## Prior Work
|
||||
@.paul/phases/60-order-status-aged-event/60-01-SUMMARY.md
|
||||
|
||||
## Source Files
|
||||
@src/Modules/Automation/AutomationController.php
|
||||
@src/Modules/Automation/AutomationRepository.php
|
||||
@src/Modules/Automation/AutomationService.php
|
||||
@src/Modules/Automation/OrderStatusAgedService.php
|
||||
@resources/views/automation/form.php
|
||||
@public/assets/js/modules/automation-form.js
|
||||
@src/Modules/Cron/CronHandlerFactory.php
|
||||
@database/migrations/20260318_000057_create_automation_tables.sql
|
||||
@database/migrations/20260328_000072_create_automation_execution_logs_table.sql
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
| Skill | Priority | When to Invoke | Loaded? |
|
||||
|-------|----------|----------------|---------|
|
||||
| sonar-scanner (CLI) | required | Po APPLY, przed UNIFY | o |
|
||||
|
||||
## Skill Invocation Checklist
|
||||
- [ ] sonar-scanner uruchomiony po wdrozeniu zmian
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Konfiguracja akcji e-mail ma opcje jednorazowej wysylki
|
||||
```gherkin
|
||||
Given operator tworzy lub edytuje zadanie automatyczne
|
||||
When wybierze akcje "Wyslij e-mail"
|
||||
Then widzi checkbox "Wyslij tylko raz dla tego zamowienia"
|
||||
And wartosc checkboxa zapisuje sie w action_config i wraca poprawnie po ponownej edycji reguly
|
||||
```
|
||||
|
||||
## AC-2: Jednorazowa wysylka dziala per zamowienie
|
||||
```gherkin
|
||||
Given regula z eventem "order.status_aged" i akcja send_email z wlaczona opcja "wyslij tylko raz"
|
||||
And zamowienie pozostaje w tym samym statusie przez kolejne uruchomienia crona
|
||||
When cron wyzwoli te sama regule wielokrotnie dla tego samego zamowienia
|
||||
Then e-mail zostanie wyslany tylko podczas pierwszego udanego wykonania tej akcji
|
||||
And kolejne wykonania pominaja tylko te akcje e-mail, nie przerywajac pozostalych akcji reguly
|
||||
```
|
||||
|
||||
## AC-3: Zachowanie domyslne pozostaje bez zmian
|
||||
```gherkin
|
||||
Given regula z akcja send_email bez zaznaczonej opcji "wyslij tylko raz"
|
||||
When event uruchomi regule wielokrotnie dla tego samego zamowienia
|
||||
Then e-mail moze byc wysylany wielokrotnie jak dotychczas
|
||||
```
|
||||
|
||||
## AC-4: Oznaczenie "wyslano raz" powstaje tylko po sukcesie wysylki
|
||||
```gherkin
|
||||
Given pierwsza proba wysylki zakonczyla sie bledem
|
||||
When kolejny przebieg crona ponowi wykonanie
|
||||
Then system ponownie sprobuje wyslac e-mail
|
||||
And blokada jednorazowosci nie jest zapisana po nieudanej probie
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Dodac model danych jednorazowej wysylki i repozytorium idempotencji</name>
|
||||
<files>database/migrations/20260425_000102_create_automation_email_once_deliveries_table.sql, src/Modules/Automation/AutomationEmailOnceRepository.php, src/Modules/Cron/CronHandlerFactory.php</files>
|
||||
<action>
|
||||
1. Dodac migracje tworzenia tabeli `automation_email_once_deliveries` z kolumnami:
|
||||
- `id` (PK),
|
||||
- `rule_id` (FK -> automation_rules.id),
|
||||
- `action_id` (FK -> automation_actions.id),
|
||||
- `order_id` (FK -> orders.id),
|
||||
- `created_at`.
|
||||
2. Dodac UNIQUE KEY na `(rule_id, action_id, order_id)` dla twardej deduplikacji.
|
||||
3. Utworzyc `AutomationEmailOnceRepository` z metodami:
|
||||
- `wasSent(int $ruleId, int $actionId, int $orderId): bool`
|
||||
- `markSent(int $ruleId, int $actionId, int $orderId): void`
|
||||
4. Podpiac repozytorium w `CronHandlerFactory` i konstruktorze `AutomationService`.
|
||||
</action>
|
||||
<verify>Uruchomienie migracji lokalnie konczy sie bez bledu, a tabela i indeks UNIQUE istnieja.</verify>
|
||||
<done>AC-2 i AC-4 maja trwaly mechanizm danych.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Rozszerzyc konfiguracje akcji send_email o flage "send_once_per_order"</name>
|
||||
<files>src/Modules/Automation/AutomationController.php, resources/views/automation/form.php, public/assets/js/modules/automation-form.js, src/Modules/Automation/AutomationRepository.php</files>
|
||||
<action>
|
||||
1. W `AutomationController::parseActionConfig()` dla `send_email` dodac bool `send_once_per_order` (0/1), domyslnie `0`.
|
||||
2. W widoku formularza (`resources/views/automation/form.php`) dodac checkbox dla akcji e-mail:
|
||||
`actions[idx][send_once_per_order]`.
|
||||
3. W generatorze dynamicznym JS (`automation-form.js`) dodac ten sam checkbox przy dodawaniu nowej akcji e-mail.
|
||||
4. Zachowac kompatybilnosc starych rekordow (brak pola = `false`).
|
||||
</action>
|
||||
<verify>Utworzenie i edycja reguly zapisuje/odczytuje checkbox poprawnie; brak regresji dla innych typow akcji.</verify>
|
||||
<done>AC-1 i AC-3 sa spelnione po stronie konfiguracji.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Wdrozyc wykonanie jednorazowe w AutomationService i testy</name>
|
||||
<files>src/Modules/Automation/AutomationService.php, tests/Unit/AutomationServiceTest.php, .paul/docs/DB_SCHEMA.md, .paul/docs/ARCHITECTURE.md, .paul/docs/TECH_CHANGELOG.md</files>
|
||||
<action>
|
||||
1. W `AutomationService::executeActions()` przekazac `ruleId` i `actionId` do obslugi send_email.
|
||||
2. W `handleSendEmail()`:
|
||||
- odczytac `send_once_per_order`,
|
||||
- gdy flaga aktywna: sprawdzic `wasSent(...)`; jesli true, pominac akcje e-mail,
|
||||
- po udanej wysylce (bez wyjatku): zapisac `markSent(...)`.
|
||||
3. Nie oznaczac jako wyslane przy bledzie wysylki (wyjatek -> brak `markSent`).
|
||||
4. Dodac testy:
|
||||
- `send_once_per_order=true` -> druga proba nie wywoluje `EmailSendingService::send`,
|
||||
- `send_once_per_order=false` -> kolejne proby wysylaja dalej.
|
||||
5. Zaktualizowac `.paul/docs/DB_SCHEMA.md`, `.paul/docs/ARCHITECTURE.md`, `.paul/docs/TECH_CHANGELOG.md`.
|
||||
</action>
|
||||
<verify>`php vendor/bin/phpunit tests/Unit/AutomationServiceTest.php` przechodzi; test reczny cron potwierdza pojedyncza wysylke dla zaznaczonej opcji.</verify>
|
||||
<done>AC-2, AC-3, AC-4 sa spelnione end-to-end.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- Logika eventow i warunkow automatyzacji niezwiązanych z `send_email`
|
||||
- Mechanizmy wysylki e-mail poza potrzebnym miejscem integracji w `AutomationService`
|
||||
- Runtime konfiguracji DB hostow (`DB_HOST` / `DB_HOST_REMOTE`)
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Brak nowych eventow automatyzacji
|
||||
- Brak zmian w harmonogramie crona `order_status_aged`
|
||||
- Brak zmian UI listy historii poza tym, co konieczne do konfiguracji checkboxa
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] Migracja tworzy tabele i UNIQUE KEY dla deduplikacji
|
||||
- [ ] Checkbox "wyslij tylko raz" dziala przy create/edit reguly
|
||||
- [ ] Dla `send_once_per_order=1` e-mail idzie tylko raz na zamowienie
|
||||
- [ ] Dla `send_once_per_order=0` zachowanie pozostaje bez zmian
|
||||
- [ ] `php vendor/bin/phpunit tests/Unit/AutomationServiceTest.php` przechodzi
|
||||
- [ ] Dokumentacja `.paul/docs/*` zaktualizowana
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Operator moze wlaczyc jednorazowa wysylke per zamowienie bez zmian kodu
|
||||
- Cron nie wysyla duplikatow dla tej samej jednorazowej akcji e-mail
|
||||
- Brak regresji istniejacych automatyzacji e-mail
|
||||
- Plan gotowy do uruchomienia przez `$paul-apply`
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/107-automation-email-send-once/107-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user