This commit is contained in:
2026-04-08 19:08:40 +02:00
parent 40644eb362
commit 0f7742f10d
25 changed files with 750 additions and 77 deletions

View File

@@ -0,0 +1,163 @@
---
phase: 87-shipment-delete
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- src/Modules/Shipments/ShipmentPackageRepository.php
- src/Modules/Shipments/ShipmentController.php
- routes/web.php
- resources/views/orders/show.php
autonomous: true
delegation: off
---
<objective>
## Goal
Dodanie możliwości usuwania przesyłek (shipment_packages) z zakładki Przesyłki w szczegółach zamówienia, z pytaniem potwierdzającym przed usunięciem.
## Purpose
Użytkownik potrzebuje możliwości usunięcia błędnie utworzonej lub niepotrzebnej przesyłki bez konieczności ingerencji w bazę danych.
## Output
- Przycisk "Usuń" przy każdej przesyłce w tabeli na /orders/{id}#shipments
- Potwierdzenie przez OrderProAlerts.confirm przed wysłaniem żądania
- Endpoint POST /orders/{id}/shipment/{packageId}/delete z walidacją CSRF
- Usunięcie rekordu z shipment_packages + pliku etykiety (jeśli istnieje)
- Wpis w activity log zamówienia
</objective>
<context>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md
## Source Files
@src/Modules/Shipments/ShipmentPackageRepository.php
@src/Modules/Shipments/ShipmentController.php
@routes/web.php
@resources/views/orders/show.php
</context>
<skills>
No specialized flows required.
</skills>
<acceptance_criteria>
## AC-1: Przycisk usuwania widoczny przy przesyłce
```gherkin
Given zamówienie ma co najmniej jedną przesyłkę w shipment_packages
When użytkownik otwiera szczegóły zamówienia i zakładkę Przesyłki
Then przy każdej przesyłce w tabeli "Wygenerowane przesylki" widoczny jest przycisk "Usuń"
```
## AC-2: Potwierdzenie przed usunięciem
```gherkin
Given użytkownik widzi przycisk "Usuń" przy przesyłce
When kliknie przycisk "Usuń"
Then wyświetla się okno potwierdzenia OrderProAlerts.confirm z pytaniem "Czy na pewno chcesz usunąć tę przesyłkę?"
And przesyłka NIE jest usuwana dopóki użytkownik nie potwierdzi
```
## AC-3: Usunięcie przesyłki po potwierdzeniu
```gherkin
Given użytkownik potwierdził usunięcie przesyłki
When żądanie POST trafia do /orders/{id}/shipment/{packageId}/delete
Then rekord shipment_packages jest usuwany z bazy danych
And plik etykiety (label_path) jest usuwany z dysku (jeśli istnieje)
And w activity log zamówienia pojawia się wpis "shipment_deleted"
And użytkownik jest przekierowany z powrotem na /orders/{id} z komunikatem sukcesu
```
</acceptance_criteria>
<tasks>
<task type="auto">
<name>Task 1: Backend — repository delete + controller endpoint + route</name>
<files>src/Modules/Shipments/ShipmentPackageRepository.php, src/Modules/Shipments/ShipmentController.php, routes/web.php</files>
<action>
1. ShipmentPackageRepository — dodaj metodę `delete(int $id): void`:
- DELETE FROM shipment_packages WHERE id = :id
- Prepared statement, spójne z resztą repo
2. ShipmentController — dodaj metodę `delete(Request $request): Response`:
- Pobierz orderId i packageId z requestu
- Waliduj CSRF token (wzorzec z metody create)
- Pobierz pakiet przez packageRepository->findById
- Sprawdź czy pakiet istnieje i należy do tego zamówienia (order_id match)
- Jeśli label_path istnieje na dysku — usuń plik (unlink)
- Wywołaj packageRepository->delete($packageId)
- Zapisz activity log: ordersRepository->recordActivity($orderId, 'shipment_deleted', opis z tracking_number/provider/id, null, 'user', $actorName)
- Flash::set('order.success', 'Przesylka zostala usunieta.')
- Redirect do /orders/{orderId}
3. routes/web.php — dodaj route tuż po linii z /shipment/manual:
- $router->post('/orders/{id}/shipment/{packageId}/delete', [$shipmentController, 'delete'], [$authMiddleware]);
</action>
<verify>Grep for 'delete' in ShipmentController.php and ShipmentPackageRepository.php; check route in web.php</verify>
<done>AC-3 satisfied: przesyłka usuwana z DB, etykieta z dysku, activity log zapisany, redirect z flash message</done>
</task>
<task type="auto">
<name>Task 2: Frontend — przycisk Usuń z potwierdzeniem w widoku zamówienia</name>
<files>resources/views/orders/show.php</files>
<action>
W tabeli "Wygenerowane przesylki" (sekcja packagesList), dodaj kolumnę "Akcje" w thead.
W tbody, w nowej kolumnie dla każdej przesyłki dodaj formularz POST:
- action="/orders/{orderId}/shipment/{packageId}/delete"
- hidden _token (CSRF)
- przycisk "Usuń" klasy btn btn--sm btn--danger
- Na submit formularza: event.preventDefault(), wywołaj window.OrderProAlerts.confirm z pytaniem "Czy na pewno chcesz usunąć tę przesyłkę?" i w onConfirm: form.submit()
Skrypt JS inline (lub w bloku script na dole) obsługujący confirm:
- Delegacja na .btn-delete-package click
- preventDefault, pobranie closest form
- OrderProAlerts.confirm({title: 'Usuwanie przesyłki', message: 'Czy na pewno chcesz usunąć tę przesyłkę?', onConfirm: () => form.submit()})
</action>
<verify>Otworzyć /orders/{id} z przesyłkami — widoczny przycisk Usuń, kliknięcie pokazuje confirm dialog</verify>
<done>AC-1 i AC-2 satisfied: przycisk widoczny, potwierdzenie wymagane przed usunięciem</done>
</task>
</tasks>
<boundaries>
## DO NOT CHANGE
- shipment_packages table schema (no migrations)
- Logika tworzenia przesyłek (create, createManual)
- Sekcja "Wysylki z Allegro" (to dane zewnętrzne, nie lokalne pakiety)
- Automation triggers (nie emituj eventu przy usuwaniu)
## SCOPE LIMITS
- Usuwanie dotyczy tylko rekordów z tabeli shipment_packages (lokalne przesyłki)
- Nie usuwamy przesyłek z API przewoźnika (tylko lokalny rekord)
- Brak soft-delete — twarde usunięcie z bazy
</boundaries>
<verification>
Before declaring plan complete:
- [ ] Metoda delete() w ShipmentPackageRepository działa (prepared statement)
- [ ] Endpoint POST /orders/{id}/shipment/{packageId}/delete zwraca redirect
- [ ] CSRF walidacja działa (bez tokena = błąd)
- [ ] Plik etykiety usuwany z dysku gdy istnieje
- [ ] Activity log zapisany po usunięciu
- [ ] Przycisk "Usuń" widoczny w tabeli przesyłek
- [ ] OrderProAlerts.confirm wyświetla się przed usunięciem
- [ ] Wszystkie acceptance criteria spełnione
</verification>
<success_criteria>
- Wszystkie zadania ukończone
- Wszystkie weryfikacje przeszły
- Brak błędów PHP/JS
- Przesyłka usuwana po potwierdzeniu, z cleanup etykiety i wpisem w logu
</success_criteria>
<output>
After completion, create `.paul/phases/87-shipment-delete/87-01-SUMMARY.md`
</output>

View File

@@ -0,0 +1,100 @@
---
phase: 87-shipment-delete
plan: 01
subsystem: shipments
tags: [php, shipment-packages, crud, ui]
requires: []
provides:
- Usuwanie przesylek z poziomu szczegolow zamowienia
affects: []
tech-stack:
added: []
patterns: [OrderProAlerts.confirm for destructive actions]
key-files:
created: []
modified:
- src/Modules/Shipments/ShipmentPackageRepository.php
- src/Modules/Shipments/ShipmentController.php
- routes/web.php
- resources/views/orders/show.php
key-decisions:
- "Hard delete z bazy (bez soft-delete) — spójne z resztą systemu"
- "Usuwanie tylko lokalnego rekordu, bez kasowania z API przewoźnika"
patterns-established: []
duration: ~5min
started: 2026-04-08T00:00:00Z
completed: 2026-04-08T00:00:00Z
---
# Phase 87 Plan 01: Shipment Delete Summary
**Usuwanie przesyłek z zakładki Przesyłki w szczegółach zamówienia z potwierdzeniem OrderProAlerts.confirm**
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~5min |
| Tasks | 2 completed |
| Files modified | 4 |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Przycisk usuwania widoczny przy przesyłce | Pass | Kolumna Akcje z przyciskiem "Usun" btn--danger |
| AC-2: Potwierdzenie przed usunięciem | Pass | OrderProAlerts.confirm z fallback na native confirm |
| AC-3: Usunięcie przesyłki po potwierdzeniu | Pass | DELETE z DB, cleanup etykiety, activity log, flash + redirect |
## Accomplishments
- Endpoint POST `/orders/{id}/shipment/{packageId}/delete` z walidacją CSRF i owner check
- Cleanup pliku etykiety z dysku przy usunięciu
- Activity log `shipment_deleted` z tracking number i provider info
- Przycisk "Usun" z dialogiem potwierdzenia w tabeli przesyłek
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `src/Modules/Shipments/ShipmentPackageRepository.php` | Modified | Metoda `delete(int $id): void` |
| `src/Modules/Shipments/ShipmentController.php` | Modified | Metoda `delete()` — CSRF, owner check, label cleanup, activity log |
| `routes/web.php` | Modified | Route POST `/orders/{id}/shipment/{packageId}/delete` |
| `resources/views/orders/show.php` | Modified | Kolumna Akcje, przycisk Usun, JS confirm handler |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Hard delete (nie soft-delete) | Spójne z resztą systemu, brak potrzeby historii usuniętych | Prostsze, activity log zachowuje ślad |
| Brak kasowania z API przewoźnika | Usuwamy tylko lokalny rekord; przesyłka u przewoźnika istnieje niezależnie | Bezpieczne — nie wpływa na realną przesyłkę |
| Fallback na native confirm | Na wypadek gdyby OrderProAlerts nie był załadowany | Robustność |
## Deviations from Plan
None — plan executed exactly as written.
## Issues Encountered
None.
## Next Phase Readiness
**Ready:**
- Funkcjonalność usuwania przesyłek kompletna i gotowa do użycia
**Concerns:**
- None
**Blockers:**
- None
---
*Phase: 87-shipment-delete, Plan: 01*
*Completed: 2026-04-08*