Nowy endpoint POST /orders/{id}/shipment/manual z formularzem inline
w zakladce Przesylki. Reuse tabeli shipment_packages (provider='manual',
status='created'). Activity log, walidacja CSRF, HTML required.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
194 lines
7.5 KiB
Markdown
194 lines
7.5 KiB
Markdown
---
|
|
phase: 26-manual-tracking-number
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- src/Modules/Shipments/ShipmentController.php
|
|
- src/Modules/Shipments/ShipmentPackageRepository.php
|
|
- resources/views/orders/show.php
|
|
- resources/scss/pages/_orders.scss
|
|
- routes/web.php
|
|
- DOCS/ARCHITECTURE.md
|
|
- DOCS/TECH_CHANGELOG.md
|
|
autonomous: true
|
|
---
|
|
|
|
<objective>
|
|
## Goal
|
|
Dodanie możliwości ręcznego wpisania numeru przesyłki (tracking number) do zamówienia — bez tworzenia przesyłki przez API przewoźnika.
|
|
|
|
## Purpose
|
|
Sprzedawca często nadaje paczki poza systemem (np. na poczcie, przez innego kuriera bez integracji API). Potrzebuje zapisać numer śledzenia przy zamówieniu, żeby mieć komplet informacji w jednym miejscu.
|
|
|
|
## Output
|
|
- Nowy endpoint POST `/orders/{id}/shipment/manual` w ShipmentController
|
|
- Formularz inline w zakładce Przesyłki na stronie zamówienia
|
|
- Rekord w `shipment_packages` z provider='manual', status='created'
|
|
</objective>
|
|
|
|
<context>
|
|
## Project Context
|
|
@.paul/PROJECT.md
|
|
@.paul/ROADMAP.md
|
|
@.paul/STATE.md
|
|
|
|
## Source Files
|
|
@src/Modules/Shipments/ShipmentController.php
|
|
@src/Modules/Shipments/ShipmentPackageRepository.php
|
|
@resources/views/orders/show.php
|
|
@routes/web.php
|
|
</context>
|
|
|
|
<skills>
|
|
## Required Skills (from SPECIAL-FLOWS.md)
|
|
|
|
| Skill | Priority | When to Invoke | Loaded? |
|
|
|-------|----------|----------------|---------|
|
|
| sonar-scanner | required | Po APPLY, przed UNIFY | ○ |
|
|
|
|
## Skill Invocation Checklist
|
|
- [ ] sonar-scanner loaded (run command or confirm)
|
|
</skills>
|
|
|
|
<acceptance_criteria>
|
|
|
|
## AC-1: Ręczne dodanie numeru przesyłki
|
|
```gherkin
|
|
Given zamówienie istnieje i użytkownik jest na stronie szczegółów zamówienia
|
|
When użytkownik wpisuje numer przesyłki i opcjonalnie nazwę przewoźnika w formularzu inline, i klika "Dodaj"
|
|
Then w tabeli shipment_packages powstaje rekord z provider='manual', status='created', tracking_number=wpisany numer
|
|
And numer pojawia się na liście przesyłek zamówienia
|
|
And wpis pojawia się w activity log zamówienia
|
|
```
|
|
|
|
## AC-2: Walidacja — pusty numer
|
|
```gherkin
|
|
Given użytkownik jest na stronie szczegółów zamówienia
|
|
When użytkownik klika "Dodaj" bez wpisania numeru przesyłki
|
|
Then formularz nie jest wysyłany (walidacja HTML required)
|
|
And żaden rekord nie jest tworzony
|
|
```
|
|
|
|
## AC-3: Wyświetlanie ręcznych przesyłek na liście
|
|
```gherkin
|
|
Given zamówienie ma ręcznie dodany numer przesyłki
|
|
When użytkownik otwiera stronę szczegółów zamówienia
|
|
Then na liście przesyłek widoczny jest rekord z etykietą "Ręczna" w kolumnie Przewoźnik
|
|
And tracking number jest wyświetlany
|
|
And kolumna Etykieta pokazuje "—" (brak etykiety dla ręcznych)
|
|
```
|
|
|
|
</acceptance_criteria>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Metoda createManual w ShipmentPackageRepository + endpoint w ShipmentController</name>
|
|
<files>src/Modules/Shipments/ShipmentPackageRepository.php, src/Modules/Shipments/ShipmentController.php, routes/web.php</files>
|
|
<action>
|
|
1. W ShipmentPackageRepository dodać metodę `createManual(int $orderId, string $trackingNumber, ?string $carrierName = null): int`:
|
|
- INSERT do shipment_packages z: order_id, provider='manual', tracking_number, carrier_id=carrierName (lub null), status='created', reference_number=null
|
|
- Zwraca ID nowego rekordu
|
|
|
|
2. W ShipmentController dodać metodę `createManual(Request $request): Response`:
|
|
- Walidacja CSRF
|
|
- Pobranie orderId z URL, tracking_number i carrier_name z POST
|
|
- Walidacja: tracking_number nie może być pusty (trim)
|
|
- Wywołanie $this->packageRepository->createManual(...)
|
|
- recordActivity na ordersRepository: typ 'shipment_manual', opis z numerem i przewoźnikiem
|
|
- Flash success + redirect do /orders/{id}
|
|
|
|
3. W routes/web.php dodać route:
|
|
- POST /orders/{id}/shipment/manual → [$shipmentController, 'createManual']
|
|
- Z $authMiddleware
|
|
</action>
|
|
<verify>
|
|
POST na /orders/{id}/shipment/manual z tracking_number tworzy rekord w shipment_packages i redirectuje z flash success.
|
|
</verify>
|
|
<done>AC-1 satisfied: ręczne dodanie numeru przesyłki działa end-to-end</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Formularz inline + wyświetlanie ręcznych przesyłek w widoku zamówienia</name>
|
|
<files>resources/views/orders/show.php, resources/scss/pages/_orders.scss</files>
|
|
<action>
|
|
1. W resources/views/orders/show.php, w sekcji zakładki Przesyłki (tab "shipments"), dodać kompaktowy formularz inline pod listą przesyłek:
|
|
- Jeden wiersz: input text "Nr przesyłki" (required), input text "Przewoźnik" (opcjonalny), przycisk "Dodaj"
|
|
- form method POST action="/orders/{id}/shipment/manual"
|
|
- Ukryte pole _token z CSRF
|
|
- Klasa CSS: `manual-tracking-form`
|
|
|
|
2. W tabeli przesyłek (packagesList foreach), dla rekordu z provider='manual':
|
|
- W kolumnie "Przewoźnik": wyświetlić carrier_id jeśli niepuste, inaczej "Ręczna"
|
|
- W kolumnie "Etykieta": wyświetlić "—"
|
|
- W kolumnie "Status": wyświetlić badge "Dodana ręcznie" (klasa `badge badge--neutral`)
|
|
|
|
3. W resources/scss/pages/_orders.scss dodać style dla `.manual-tracking-form`:
|
|
- display: flex, gap: 8px, align-items: center
|
|
- margin-top: 12px
|
|
- Inputy: standardowe style projektu
|
|
</action>
|
|
<verify>
|
|
Na stronie szczegółów zamówienia widoczny jest formularz dodawania ręcznego numeru. Po dodaniu, numer wyświetla się na liście z oznaczeniem "Ręczna".
|
|
</verify>
|
|
<done>AC-2, AC-3 satisfied: walidacja formularza i wyświetlanie ręcznych przesyłek</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 3: Aktualizacja dokumentacji</name>
|
|
<files>DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
|
|
<action>
|
|
1. W DOCS/ARCHITECTURE.md:
|
|
- W sekcji ShipmentController dodać metodę createManual
|
|
- W sekcji ShipmentPackageRepository dodać metodę createManual
|
|
|
|
2. W DOCS/TECH_CHANGELOG.md:
|
|
- Dodać wpis o nowej funkcjonalności ręcznego numeru przesyłki
|
|
</action>
|
|
<verify>Dokumentacja zaktualizowana zgodnie z nowymi endpointami.</verify>
|
|
<done>Dokumentacja odzwierciedla nową funkcjonalność</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<boundaries>
|
|
|
|
## DO NOT CHANGE
|
|
- database/migrations/* (nie trzeba nowej migracji — tabela shipment_packages już ma wszystkie potrzebne kolumny)
|
|
- src/Modules/Shipments/AllegroShipmentService.php
|
|
- src/Modules/Shipments/ApaczkaShipmentService.php
|
|
- src/Modules/Shipments/InpostShipmentService.php
|
|
- src/Modules/Shipments/ShipmentProviderInterface.php
|
|
|
|
## SCOPE LIMITS
|
|
- Nie dodawać usuwania/edycji ręcznych przesyłek (oddzielna faza jeśli potrzebne)
|
|
- Nie modyfikować flow tworzenia przesyłek przez API przewoźników
|
|
- Nie dodawać nowych zależności composer
|
|
|
|
</boundaries>
|
|
|
|
<verification>
|
|
Before declaring plan complete:
|
|
- [ ] POST /orders/{id}/shipment/manual tworzy rekord w shipment_packages
|
|
- [ ] Rekord ma provider='manual', status='created', poprawny tracking_number
|
|
- [ ] Activity log zawiera wpis o ręcznym dodaniu
|
|
- [ ] Formularz inline widoczny w zakładce Przesyłki
|
|
- [ ] Walidacja HTML required na polu tracking_number
|
|
- [ ] Ręczne przesyłki wyświetlają się poprawnie na liście (Przewoźnik, Status, Etykieta)
|
|
- [ ] CSRF protection działa
|
|
- [ ] Brak błędów PHP
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Wszystkie taski zakończone
|
|
- Wszystkie weryfikacje przechodzą
|
|
- Brak nowych błędów PHP ani JS
|
|
- Dokumentacja zaktualizowana
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.paul/phases/26-manual-tracking-number/26-01-SUMMARY.md`
|
|
</output>
|