---
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
---
## 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'
## 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
## 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)
## 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)
```
Task 1: Metoda createManual w ShipmentPackageRepository + endpoint w ShipmentController
src/Modules/Shipments/ShipmentPackageRepository.php, src/Modules/Shipments/ShipmentController.php, routes/web.php
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
POST na /orders/{id}/shipment/manual z tracking_number tworzy rekord w shipment_packages i redirectuje z flash success.
AC-1 satisfied: ręczne dodanie numeru przesyłki działa end-to-end
Task 2: Formularz inline + wyświetlanie ręcznych przesyłek w widoku zamówienia
resources/views/orders/show.php, resources/scss/pages/_orders.scss
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
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".
AC-2, AC-3 satisfied: walidacja formularza i wyświetlanie ręcznych przesyłek
Task 3: Aktualizacja dokumentacji
DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md
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
Dokumentacja zaktualizowana zgodnie z nowymi endpointami.
Dokumentacja odzwierciedla nową funkcjonalność
## 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
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
- Wszystkie taski zakończone
- Wszystkie weryfikacje przechodzą
- Brak nowych błędów PHP ani JS
- Dokumentacja zaktualizowana