---
phase: 16-product-list-custom-labels
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - autoload/admin/Controllers/ShopProductController.php
  - autoload/Domain/Product/ProductRepository.php
  - admin/templates/shop-product/products-list-custom-script.php
  - tests/Unit/admin/Controllers/ShopProductControllerTest.php
  - tests/Unit/Domain/Product/ProductRepositoryTest.php
autonomous: false
delegation: off
---

<objective>
## Goal
Dodac w liscie produktow (`/admin/shop_product/view_list/`) przelacznik "Pokaz etykiety niestandardowe", ktory zapisuje stan w sesji i po wlaczeniu pokazuje szybka edycje 5 pol `custom_label_0..4` z podpowiedziami.

## Purpose
Administrator ma szybciej uzupelniac etykiety Google XML bez wchodzenia do edycji kazdego produktu, z zachowaniem spojnosc danych i wygodnych podpowiedzi istniejacych wartosci.

## Output
- Nowy przycisk obok "Dodaj produkt", sterujacy widocznoscia custom labels i zapisujacy stan w sesji
- Render 5 pol `custom_label_0..4` pod nazwa/SKU produktu w tabeli, tylko przy wlaczonej opcji
- Zapis kazdego pola do `pp_shop_products` oraz system podpowiedzi z istniejacych wartosci w bazie
- Odczyt nazw etykiet z bazy (z fallbackiem) zamiast hardcodu w widoku listy
</objective>

<context>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md

## Source Files
@autoload/admin/Controllers/ShopProductController.php
@autoload/Domain/Product/ProductRepository.php
@admin/templates/components/table-list.php
@admin/templates/shop-product/products-list.php
@admin/templates/shop-product/products-list-custom-script.php
@tests/Unit/admin/Controllers/ShopProductControllerTest.php
@tests/Unit/Domain/Product/ProductRepositoryTest.php
</context>

<skills>
## Required Skills (from SPECIAL-FLOWS.md)

| Skill | Priority | When to Invoke | Loaded? |
|-------|----------|----------------|---------|
| /feature-dev | required | Before implementation in APPLY | ○ |
| /koniec-pracy | required | After implementation/release wrap-up | ○ |

**BLOCKING:** Required skills MUST be loaded before APPLY proceeds.
Run each skill command or confirm already loaded.

## Skill Invocation Checklist
- [ ] /feature-dev loaded (run command or confirm)
- [ ] /koniec-pracy loaded (run command or confirm)

</skills>

<acceptance_criteria>

## AC-1: Przelacznik widocznosci custom labels dziala i jest zapamietywany
```gherkin
Given administrator jest na /admin/shop_product/view_list/
When kliknie przycisk "Pokaz etykiety niestandardowe"
Then stan opcji zostanie zapisany w sesji
And po odswiezeniu/listowaniu tabela zachowa ustawiony stan (wlaczony lub wylaczony)
```

## AC-2: Lista produktow pokazuje 5 pol custom_label po wlaczeniu opcji
```gherkin
Given opcja "Pokaz etykiety niestandardowe" jest wlaczona
When lista produktow sie renderuje
Then pod sekcja zdjecie/nazwa/SKU-EAN dla kazdego produktu widoczne sa pola custom_label_0..custom_label_4
And etykiety tych pol sa pobrane dynamicznie z bazy danych (z fallbackiem tylko gdy brak konfiguracji)
```

## AC-3: Zapis i podpowiedzi wartosci dzialaja dla kazdego custom_label
```gherkin
Given administrator wpisuje wartosc w jednym z pol custom_label_0..custom_label_4
When wybierze podpowiedz lub zatwierdzi wpis
Then wartosc zostanie zapisana w pp_shop_products dla danego produktu i pola
And podpowiedzi sa budowane z juz istniejacych wartosci tego samego custom_label w bazie
```

## AC-4: Walidacja i bezpieczenstwo endpointow sa zachowane
```gherkin
Given zapytanie AJAX podaje nieprawidlowy typ labela spoza custom_label_0..4
When backend przetwarza request
Then operacja zostaje odrzucona bez zapisu
And odpowiedz zwraca status bledu bez ingerencji w dane produktu
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: Dodac backend przelacznika sesyjnego i danych dla widoku listy</name>
  <files>autoload/admin/Controllers/ShopProductController.php, autoload/Domain/Product/ProductRepository.php</files>
  <action>
    Rozszerzyc `ShopProductController::view_list()` o flage sesyjna dla widocznosci custom labels
    oraz przekazanie do widoku nazw etykiet pobieranych z bazy.

    Dodac akcje kontrolera do przelaczania flagi (toggle) i zwracania prostego JSON.

    W `ProductRepository` dodac metode pobierajaca nazwy etykiet custom_label_0..4 z bazy
    (np. tabela ustawien), z bezpiecznym fallbackiem "Custom label N" gdy wartosc nie istnieje.
    Nie stosowac konkatenacji SQL dla danych wejsciowych.
  </action>
  <verify>Uruchomic testy kontrolera/repo oraz sprawdzic recznie, ze zmiana flagi utrzymuje sie po reloadzie listy</verify>
  <done>AC-1 i AC-2 satisfied</done>
</task>

<task type="auto">
  <name>Task 2: Dodac UI i logike AJAX dla custom labels na liscie produktow</name>
  <files>autoload/admin/Controllers/ShopProductController.php, admin/templates/shop-product/products-list-custom-script.php</files>
  <action>
    Wygenerowac HTML 5 pol custom_label pod kolumna nazwy produktu tylko gdy flaga sesyjna jest wlaczona.
    Uzyc klas zgodnych z istniejacym stylem (`custom-labels`, `custom_label_X_container`, listy sugestii).

    Dodac przycisk "Pokaz etykiety niestandardowe" obok "Dodaj produkt" (hook przez custom script listy)
    oraz obsluge klikniecia przez AJAX do nowej akcji toggle + odswiezenie aktualnego URL.

    Podlaczyc dla kazdego inputa:
    - pobieranie sugestii przez `/admin/shop_product/product_custom_label_suggestions/`
    - zapis przez `/admin/shop_product/product_custom_label_save/`
    z walidacja odpowiedzi i obsluga bledow UI.
  </action>
  <verify>Manual: wlaczyc opcje, wpisac i zapisac wartosc custom_label, odswiezyc strone, potwierdzic widocznosc i dane</verify>
  <done>AC-2 i AC-3 satisfied</done>
</task>

<task type="auto">
  <name>Task 3: Dodac testy regresyjne dla nowego zachowania</name>
  <files>tests/Unit/admin/Controllers/ShopProductControllerTest.php, tests/Unit/Domain/Product/ProductRepositoryTest.php</files>
  <action>
    Rozszerzyc testy kontrolera o przypadki:
    - toggle flagi sesyjnej
    - odrzucenie nieprawidlowych typow labeli
    - poprawne przekazanie danych do widoku listy przy wlaczonej opcji.

    Rozszerzyc testy repozytorium o:
    - pobieranie nazw custom labels z bazy z fallbackiem
    - sugestie i zapis tylko dla dozwolonych label_type.
  </action>
  <verify>./test.ps1 tests/Unit/admin/Controllers/ShopProductControllerTest.php oraz ./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php</verify>
  <done>AC-4 covered and AC-1..AC-3 protected by tests</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <what-built>Nowy przycisk sesyjny + szybka edycja custom labels 0..4 z podpowiedziami na liscie produktow</what-built>
  <how-to-verify>
    1. Otworz: /admin/shop_product/view_list/
    2. Kliknij: "Pokaz etykiety niestandardowe"
    3. Potwierdz: pola custom_label_0..4 pojawiaja sie pod nazwa produktu
    4. Wpisz wartosc, wybierz podpowiedz i odswiez strone
    5. Potwierdz: wartosc zostala zapisana i toggle pozostaje aktywny
  </how-to-verify>
  <resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- Globalnych komponentow listy niezwiązanych z produktami (`admin/templates/components/table-list.php`) poza minimalnym, koniecznym hookiem
- Endpointow API (`autoload/api/*`)
- Logiki produktow frontendowych (`autoload/front/*`, `templates/shop-product/*`)

## SCOPE LIMITS
- Zakres ograniczony do admin listy produktow i quick-edit custom labels
- Bez migracji DB w tym planie (odczyt nazw z istniejacych danych konfiguracyjnych)
- Bez refaktoru calego modułu integracji Google XML

</boundaries>

<verification>
Before declaring plan complete:
- [ ] ./test.ps1 tests/Unit/admin/Controllers/ShopProductControllerTest.php
- [ ] ./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php
- [ ] Manual check: toggle zapisuje sie w sesji i zachowuje po reloadzie
- [ ] Manual check: podpowiedzi i zapis custom labels dzialaja dla 0..4
- [ ] All acceptance criteria met
</verification>

<success_criteria>
- Przycisk "Pokaz etykiety niestandardowe" dziala i przechowuje stan w sesji
- Lista produktow pokazuje i zapisuje custom_label_0..4 bez wejscia w edycje produktu
- Nazwy etykiet sa pobierane z bazy z fallbackiem
- Testy regresyjne dla backendu i repozytorium przechodza
</success_criteria>

<output>
After completion, create `.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md`
</output>
