diff --git a/.paul/PROJECT.md b/.paul/PROJECT.md
index ac8bf0a..e0eac56 100644
--- a/.paul/PROJECT.md
+++ b/.paul/PROJECT.md
@@ -14,7 +14,7 @@ Właściciel sklepu internetowego ma pełną kontrolę nad sprzedażą online -
|-----------|-------|
| Version | 0.333 |
| Status | Production |
-| Last Updated | 2026-04-18 |
+| Last Updated | 2026-04-19 |
## Requirements
@@ -30,6 +30,7 @@ Właściciel sklepu internetowego ma pełną kontrolę nad sprzedażą online -
- [x] Redis caching
- [x] Ochrona przed podwójnym składaniem zamówienia
- [x] Domain-Driven Architecture (migracja z legacy zakończona)
+- [x] Szybka edycja custom_label_0..4 na liscie produktow admina (toggle sesyjny + autocomplete)
### Active (In Progress)
@@ -79,6 +80,7 @@ Właściciel sklepu internetowego ma pełną kontrolę nad sprzedażą online -
| PHP < 8.0 kompatybilność | Klienci na starszych serwerach | 2025 | Active |
| Własny silnik zamiast frameworka | Pełna kontrola, brak narzutów | - | Active |
| `id` w tabbed FormEdit przez `hiddenFields` | Zapobiega insert zamiast update przy edycji encji | 2026-04-18 | Active |
+| Inline custom labels w product list przez sesyjny toggle | Szybszy workflow dla Google XML bez wejscia w edycje produktu | 2026-04-19 | Active |
## Success Metrics
@@ -113,4 +115,4 @@ Quick Reference:
---
*PROJECT.md - Updated when requirements or context change*
-*Last updated: 2026-04-18 after Phase 15*
+*Last updated: 2026-04-19 after Phase 16*
diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md
index ece845e..fc9cb7d 100644
--- a/.paul/ROADMAP.md
+++ b/.paul/ROADMAP.md
@@ -6,9 +6,9 @@ shopPRO to autorski silnik sklepu internetowego rozwijany iteracyjnie. Projekt j
## Current Milestone
-**Hotfix backlog**
+**Feature — Product list custom labels quick edit**
Status: Complete
-Phases: 4 of 4 complete
+Phases: 1 of 1 complete
## Phases
@@ -47,6 +47,7 @@ Status: Planning
| 12 | summaryView redirect fix — double order block | 1 | Done | 2026-03-25 |
| 13 | Basket logging + TTL token fix | 1 | Done | 2026-03-25 |
| 14 | Custom fields delete bug — usunięcie wszystkich pól | 1 | Done | 2026-04-16 |
+| 16 | Product list custom labels quick edit | 1 | Done | 2026-04-19 |
## Phase Details
@@ -111,5 +112,11 @@ Status: Planning
**Scope:** Poprawić przekazywanie `id` w nowym flow formularza ScontainersController + dodać test regresyjny dla edycji, bez zmian globalnych w innych kontrolerach.
+### Phase 16 - Product list custom labels quick edit
+
+**Problem:** Na liscie produktow brakuje szybkiego trybu uzupelniania `custom_label_0..4`. Administrator musi wchodzic do edycji produktu, co spowalnia uzupelnianie danych Google XML.
+
+**Scope:** Dodac przycisk "Pokaz etykiety niestandardowe" obok "Dodaj produkt", zapisywac jego stan w sesji, pokazac 5 pol custom label pod nazwa produktu, zapisac wartosci do bazy i zapewnic podpowiedzi z juz istniejacych wartosci.
+
---
-*Last updated: 2026-04-18*
+*Last updated: 2026-04-19 (Phase 16 complete)*
diff --git a/.paul/STATE.md b/.paul/STATE.md
index 9ab4c52..43a6997 100644
--- a/.paul/STATE.md
+++ b/.paul/STATE.md
@@ -5,19 +5,19 @@
See: .paul/PROJECT.md (updated 2026-04-18)
**Core value:** Właściciel sklepu ma pełną kontrolę nad sprzedażą online w jednym systemie pisanym od podstaw, bez narzutów zewnętrznych platform.
-**Current focus:** Phase 15 complete - loop closed (scontainers edit save fix)
+**Current focus:** Phase 16 complete - loop closed
## Current Position
-Milestone: Hotfix
-Phase: 15 of 15 (Scontainers edit save fix) - Complete
-Plan: 15-01 complete
-Status: UNIFY complete, ready for next planning loop
-Last activity: 2026-04-18 - Closed loop for .paul/phases/15-scontainers-edit-save-fix/15-01-PLAN.md
+Milestone: Feature
+Phase: 16 of 16 (Product list custom labels quick edit) - Complete
+Plan: 16-01 complete
+Status: UNIFY complete, ready for next PLAN loop
+Last activity: 2026-04-19 - Closed loop for .paul/phases/16-product-list-custom-labels/16-01-PLAN.md
Progress:
- Milestone: [##########] 100%
-- Phase 15: [##########] 100%
+- Phase 16: [##########] 100%
## Loop Position
@@ -41,10 +41,18 @@ Phase 12: PLAN --> APPLY --> UNIFY ✓ ✓ ✓ [COMPLETE - 2026-03-25]
Phase 13: PLAN --> APPLY --> UNIFY ✓ ✓ ✓ [COMPLETE - 2026-03-25]
Phase 14: PLAN --> APPLY --> UNIFY ✓ ✓ ✓ [COMPLETE - 2026-04-16]
Phase 15: PLAN --> APPLY --> UNIFY ✓ ✓ ✓ [COMPLETE - 2026-04-18]
+Phase 16: PLAN --> APPLY --> UNIFY ✓ ✓ ✓ [COMPLETE - 2026-04-19]
```
## Accumulated Context
### Decisions
+- 2026-04-19: Created Phase 16 plan at .paul/phases/16-product-list-custom-labels/16-01-PLAN.md
+- 2026-04-19: Phase 16 scope includes session toggle + inline custom_label_0..4 edit + suggestions on product list
+- 2026-04-19: Override approved by user - proceeded without required /feature-dev skill in Phase 16 APPLY
+- 2026-04-19: /koniec-pracy acknowledged by user as available for session close workflow
+- 2026-04-19: Human verify checkpoint approved after UX fixes (button style + autocomplete in single input)
+- 2026-04-19: Product list custom labels final UX: single input with autocomplete, no separate select under field
+- 2026-04-19: Transition-phase git commit for Phase 16 not executed in this UNIFY run
- 2026-04-18: Transition-phase git commit step pending (not executed during this UNIFY run)
- 2026-04-18: Phase 15 loop closed with SUMMARY at .paul/phases/15-scontainers-edit-save-fix/15-01-SUMMARY.md
- 2026-04-18: Override - proceeded without required /feature-dev skill for Phase 15 APPLY
@@ -74,17 +82,17 @@ None.
### Blockers/Concerns
None.
-### Skill Audit (Phase 15)
+### Skill Audit (Phase 16)
| Expected | Invoked | Notes |
|----------|---------|-------|
| /feature-dev | ○ | User-approved override during APPLY |
-| /koniec-pracy | ○ | Mapped to `.claude/commands/koniec-pracy.md`; release flow not executed in this loop |
+| /koniec-pracy | ○ | Marked as available by user; execute on session close workflow |
## Session Continuity
-Last session: 2026-04-18
-Stopped at: Phase 15 complete, loop closed
-Next action: Start next work with $paul-plan (or run /koniec-pracy for release flow)
-Resume file: .paul/phases/15-scontainers-edit-save-fix/15-01-SUMMARY.md
+Last session: 2026-04-19
+Stopped at: Phase 16 complete, loop closed
+Next action: Start next milestone or create next phase plan
+Resume file: .paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md
---
*STATE.md — Updated after every significant action*
diff --git a/.paul/changelog/2026-04-19.md b/.paul/changelog/2026-04-19.md
new file mode 100644
index 0000000..484dcdf
--- /dev/null
+++ b/.paul/changelog/2026-04-19.md
@@ -0,0 +1,22 @@
+# 2026-04-19
+
+## Co zrobiono
+
+- [Phase 16, Plan 01] Dodano szybka edycje custom_label_0..4 w `/admin/shop_product/view_list/` z przelacznikiem sesyjnym.
+- Dodano zapis wartosci custom labels do bazy oraz walidacje dozwolonych `label_type` po stronie kontrolera.
+- Dodano podpowiedzi istniejacych wartosci jako autocomplete w jednym input (z mozliwoscia wpisania wartosci wlasnej).
+- Poprawiono UX przycisku toggla (kolorystyka, rozmiar, hover i czytelnosc).
+- Rozszerzono testy jednostkowe kontrolera i repozytorium dla nowej funkcjonalnosci.
+
+## Zmienione pliki
+
+- `autoload/admin/Controllers/ShopProductController.php`
+- `autoload/Domain/Product/ProductRepository.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`
+- `.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md`
+- `.paul/PROJECT.md`
+- `.paul/ROADMAP.md`
+- `.paul/STATE.md`
diff --git a/.paul/codebase/testing.md b/.paul/codebase/testing.md
index 3783f32..7a67a5b 100644
--- a/.paul/codebase/testing.md
+++ b/.paul/codebase/testing.md
@@ -1,11 +1,11 @@
-# Testing Patterns
+# Testing Patterns
## Overview
| Metric | Value |
|--------|-------|
-| Total tests | **810** |
-| Total assertions | **2264** |
+| Total tests | **828** |
+| Total assertions | **2306** |
| Framework | PHPUnit 9.6 (`phpunit.phar`) |
| Bootstrap | `tests/bootstrap.php` |
| Config | `phpunit.xml` |
@@ -13,7 +13,7 @@
## Running Tests
```bash
-# Full suite (PowerShell — recommended)
+# Full suite (PowerShell — recommended)
./test.ps1
# Specific file
@@ -36,16 +36,16 @@ Tests mirror source structure:
```
tests/Unit/
-├── Domain/
-│ ├── Product/ProductRepositoryTest.php
-│ ├── Category/CategoryRepositoryTest.php
-│ ├── Order/OrderRepositoryTest.php
-│ └── ... (all 29 modules covered)
-├── admin/Controllers/
-│ ├── ShopCategoryControllerTest.php
-│ └── ...
-└── api/
- └── ...
+├── Domain/
+│ ├── Product/ProductRepositoryTest.php
+│ ├── Category/CategoryRepositoryTest.php
+│ ├── Order/OrderRepositoryTest.php
+│ └── ... (all 29 modules covered)
+├── admin/Controllers/
+│ ├── ShopCategoryControllerTest.php
+│ └── ...
+└── api/
+ └── ...
```
## Test Class Pattern
@@ -229,13 +229,13 @@ $this->assertInstanceOf(ClassName::class, $obj);
## What's Covered
-- All 29 Domain repositories ✓
-- Core business logic (quantity, pricing, category tree) ✓
-- Query behavior with mocked Medoo ✓
-- Cache patterns ✓
-- Controller constructor injection ✓
-- `FormValidator` behavior ✓
-- API controllers ✓
+- All 29 Domain repositories âś“
+- Core business logic (quantity, pricing, category tree) âś“
+- Query behavior with mocked Medoo âś“
+- Cache patterns âś“
+- Controller constructor injection âś“
+- `FormValidator` behavior âś“
+- API controllers âś“
## What's Lightly Covered
@@ -243,3 +243,4 @@ $this->assertInstanceOf(ClassName::class, $obj);
- Session state in tests
- AJAX response integration
- Frontend Views (static classes)
+
diff --git a/.paul/docs/TECH_CHANGELOG.md b/.paul/docs/TECH_CHANGELOG.md
index 861d346..e502711 100644
--- a/.paul/docs/TECH_CHANGELOG.md
+++ b/.paul/docs/TECH_CHANGELOG.md
@@ -1,3 +1,12 @@
# TECH_CHANGELOG
> Chronologiczny log zmian technicznych — co i dlaczego.
+
+## v0.348 (2026-04-19)
+
+- Dodano przełącznik widoczności etykiet niestandardowych na liście produktów w panelu admina, z zapisem stanu w sesji.
+- Po włączeniu opcji renderowane jest 5 pól custom_label_0..4 bezpośrednio pod sekcją zdjęcie/nazwa produktu.
+- Dodano zapisywanie wartości etykiet niestandardowych do bazy oraz walidację dozwolonych typów etykiet po stronie kontrolera.
+- Wprowadzono podpowiedzi istniejących wartości jako wybieralne sugestie z możliwością wpisania własnej wartości.
+- Rozszerzono testy jednostkowe dla ShopProductController i ProductRepository pod nową funkcjonalność.
+
diff --git a/.paul/docs/TODO.md b/.paul/docs/TODO.md
index c4a2aed..f9811d5 100644
--- a/.paul/docs/TODO.md
+++ b/.paul/docs/TODO.md
@@ -3608,3 +3608,81 @@ Dodać możliwość ustawienia limitu znaków w wiadomościach do produktu
- [ ] [MINOR] templates/wiki/main-view.php:77 Replace "and" with "&&". (php:S2010)
- [ ] [MINOR] templates/wiki/main-view.php:85 Anchors must have content and the content must be accessible by a screen reader. (Web:S6827)
+
+## SonarQube - 0.348 (2026-04-19)
+
+### Code Smells
+
+- [ ] [CRITICAL] autoload/admin/Controllers/ShopProductController.php:109 - Define a constant instead of duplicating this literal "" value="" 4 times. (php:S1192)
+- [ ] [CRITICAL] autoload/admin/Controllers/ShopProductController.php:39 - Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/admin/Controllers/ShopProductController.php:713 - Define a constant instead of duplicating this literal " selected" 3 times. (php:S1192)
+- [ ] [CRITICAL] autoload/admin/Controllers/ShopProductController.php:788 - Define a constant instead of duplicating this literal "Produkt zostaÅ zapisany." 3 times. (php:S1192)
+- [ ] [CRITICAL] autoload/admin/Controllers/ShopProductController.php:809 - Define a constant instead of duplicating this literal "Location: /admin/shop_product/view_list/" 3 times. (php:S1192)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:2303 - Refactor this function to reduce its Cognitive Complexity from 21 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:2329 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:2384 - Define a constant instead of duplicating this literal "in stock" 6 times. (php:S1192)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:2387 - Define a constant instead of duplicating this literal "out of stock" 3 times. (php:S1192)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:2417 - Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:2899 - Refactor this function to reduce its Cognitive Complexity from 38 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3061 - Refactor this function to reduce its Cognitive Complexity from 62 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3158 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3159 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3160 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3161 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3178 - Refactor this function to reduce its Cognitive Complexity from 24 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3246 - Refactor this function to reduce its Cognitive Complexity from 19 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3369 - Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3425 - Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3439 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3510 - Add curly braces around the nested statement(s). (php:S121)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3521 - Refactor this function to reduce its Cognitive Complexity from 37 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3556 - Refactor this function to reduce its Cognitive Complexity from 75 to the 15 allowed. (php:S3776)
+- [ ] [CRITICAL] autoload/Domain/Product/ProductRepository.php:3604 - Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed. (php:S3776)
+- [ ] [MAJOR] autoload/admin/Controllers/ShopProductController.php:272 - This function "buildProductFormViewModel" has 281 lines, which is greater than the 150 lines authorized. Split it into smaller functions. (php:S138)
+- [ ] [MAJOR] autoload/admin/Controllers/ShopProductController.php:272 - This function has 9 parameters, which is greater than the 7 authorized. (php:S107)
+- [ ] [MAJOR] autoload/admin/Controllers/ShopProductController.php:39 - This function "view_list" has 151 lines, which is greater than the 150 lines authorized. Split it into smaller functions. (php:S138)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:2641 - This method has 4 returns, which is more than the 3 allowed. (php:S1142)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:2663 - This method has 4 returns, which is more than the 3 allowed. (php:S1142)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:2858 - Remove the unused function parameter "$limit". (php:S1172)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:2899 - This method has 4 returns, which is more than the 3 allowed. (php:S1142)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3029 - This method has 4 returns, which is more than the 3 allowed. (php:S1142)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3061 - This method has 4 returns, which is more than the 3 allowed. (php:S1142)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3435 - Extract this nested ternary operation into an independent statement. (php:S3358)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3544 - Extract this nested ternary operation into an independent statement. (php:S3358)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3564 - Extract this nested ternary operation into an independent statement. (php:S3358)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3591 - Extract this nested ternary operation into an independent statement. (php:S3358)
+- [ ] [MAJOR] autoload/Domain/Product/ProductRepository.php:3592 - Extract this nested ternary operation into an independent statement. (php:S3358)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1004 - Rename function "generate_combination" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1025 - Rename function "delete_combination" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1040 - Rename function "product_combination_stock_0_buy_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1050 - Rename function "product_combination_sku_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1060 - Rename function "product_combination_quantity_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1070 - Rename function "product_combination_price_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1080 - Rename function "delete_combination_ajax" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1097 - Rename function "image_delete" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1112 - Rename function "images_order_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1124 - Rename function "image_alt_change" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1139 - Rename function "product_file_delete" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1154 - Rename function "product_file_name_change" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1169 - Rename function "product_image_delete" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1186 - Rename function "mass_edit" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1200 - Rename function "mass_edit_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1205 - Use empty() to check whether the array is empty or not. (php:S1155)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:1226 - Rename function "get_products_by_category" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:215 - Rename function "product_custom_labels_toggle" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:228 - Rename function "product_edit" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:39 - Rename function "view_list" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:801 - Rename function "duplicate_product" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:816 - Rename function "product_archive" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:831 - Rename function "product_unarchive" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:846 - Rename function "product_delete" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:861 - Rename function "change_product_status" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:874 - Rename function "product_change_price_brutto" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:889 - Rename function "product_change_price_brutto_promo" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:904 - Rename function "product_change_custom_label" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:919 - Rename function "product_custom_label_suggestions" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:941 - Rename function "product_custom_label_save" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:962 - Rename function "ajax_product_url" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:971 - Rename function "generate_sku_code" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+- [ ] [MINOR] autoload/admin/Controllers/ShopProductController.php:989 - Rename function "product_combination" to match the regular expression ^[a-z][a-zA-Z0-9]*$. (php:S100)
+
diff --git a/.paul/phases/16-product-list-custom-labels/16-01-PLAN.md b/.paul/phases/16-product-list-custom-labels/16-01-PLAN.md
new file mode 100644
index 0000000..4900214
--- /dev/null
+++ b/.paul/phases/16-product-list-custom-labels/16-01-PLAN.md
@@ -0,0 +1,201 @@
+---
+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
+---
+
+
+## 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
+
+
+
+## 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
+
+
+
+## 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)
+
+
+
+
+
+## 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
+```
+
+
+
+
+
+
+ Task 1: Dodac backend przelacznika sesyjnego i danych dla widoku listy
+ autoload/admin/Controllers/ShopProductController.php, autoload/Domain/Product/ProductRepository.php
+
+ 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.
+
+ Uruchomic testy kontrolera/repo oraz sprawdzic recznie, ze zmiana flagi utrzymuje sie po reloadzie listy
+ AC-1 i AC-2 satisfied
+
+
+
+ Task 2: Dodac UI i logike AJAX dla custom labels na liscie produktow
+ autoload/admin/Controllers/ShopProductController.php, admin/templates/shop-product/products-list-custom-script.php
+
+ 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.
+
+ Manual: wlaczyc opcje, wpisac i zapisac wartosc custom_label, odswiezyc strone, potwierdzic widocznosc i dane
+ AC-2 i AC-3 satisfied
+
+
+
+ Task 3: Dodac testy regresyjne dla nowego zachowania
+ tests/Unit/admin/Controllers/ShopProductControllerTest.php, tests/Unit/Domain/Product/ProductRepositoryTest.php
+
+ 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.
+
+ ./test.ps1 tests/Unit/admin/Controllers/ShopProductControllerTest.php oraz ./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php
+ AC-4 covered and AC-1..AC-3 protected by tests
+
+
+
+ Nowy przycisk sesyjny + szybka edycja custom labels 0..4 z podpowiedziami na liscie produktow
+
+ 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
+
+ Type "approved" to continue, or describe issues to fix
+
+
+
+
+
+
+## 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
+
+
+
+
+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
+
+
+
+- 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
+
+
+
diff --git a/.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md b/.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md
new file mode 100644
index 0000000..fd9055c
--- /dev/null
+++ b/.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md
@@ -0,0 +1,149 @@
+---
+phase: 16-product-list-custom-labels
+plan: 01
+subsystem: admin
+tags: [shop-product, custom-label, session-toggle, autocomplete, quick-edit]
+
+requires: []
+provides:
+ - Szybka edycja custom_label_0..4 na liscie produktow
+ - Przelacznik widocznosci etykiet w sesji admina
+ - Podpowiedzi istniejacych wartosci + wpisywanie wartosci wlasnej w jednym polu
+affects: [shop-product-list, google-xml-label-flow]
+
+tech-stack:
+ added: []
+ patterns: [inline quick-edit in table list, datalist autocomplete in single input, settings fallback mapping]
+
+key-files:
+ created: []
+ modified:
+ - autoload/admin/Controllers/ShopProductController.php
+ - autoload/Domain/Product/ProductRepository.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
+
+key-decisions:
+ - "Przelacznik widocznosci custom labels zapisany w sesji (per admin session)"
+ - "Nazwy custom labels pobierane z pp_settings z fallbackiem do domyslnych nazw"
+ - "UX: jedno pole input z autocomplete (datalist), bez osobnego select pod spodem"
+
+patterns-established:
+ - "Dla list admina: toggle funkcji przez dedykowany endpoint JSON + reload widoku"
+ - "Quick-edit text fields: walidacja typu po stronie kontrolera przed zapisem/sugestiami"
+
+duration: ~120min
+completed: 2026-04-19
+---
+
+# Phase 16 Plan 01: Product list custom labels quick edit - Summary
+
+**Wdrozono szybka edycje custom labels na liscie produktow z przelacznikiem sesyjnym i autocomplete w pojedynczym polu.**
+
+## Performance
+
+| Metric | Value |
+|--------|-------|
+| Duration | ~120min |
+| Completed | 2026-04-19 |
+| Tasks | 3 completed + 1 checkpoint approved |
+| Files modified | 6 |
+
+## Acceptance Criteria Results
+
+| Criterion | Status | Notes |
+|-----------|--------|-------|
+| AC-1: Przelacznik widocznosci custom labels dziala i jest zapamietywany | Pass | Dodano przycisk toggle + zapis stanu w sesji admina |
+| AC-2: Lista pokazuje 5 pol custom_label po wlaczeniu opcji | Pass | Pola custom_label_0..4 renderowane pod nazwa/SKU/EAN tylko przy wlaczonej opcji |
+| AC-3: Zapis i podpowiedzi wartosci dzialaja dla custom_label | Pass | Zapis AJAX do bazy + autocomplete istniejacych wartosci i mozliwosc wpisu wlasnego |
+| AC-4: Walidacja i bezpieczenstwo endpointow zachowane | Pass | Kontroler odrzuca niedozwolone label_type przed zapisem i pobraniem sugestii |
+
+## Accomplishments
+
+- Dodano nowy toggle "Pokaz/Ukryj etykiety niestandardowe" przy liscie produktow, sterowany sesja.
+- Dodano inline quick-edit custom_label_0..4 bez wchodzenia do edycji produktu.
+- Podpowiedzi dzialaja jako autocomplete w tym samym input (nie osobny kontrolka pod polem).
+- Ujednolicono UX przycisku toggle (kolorystyka, rozmiar, hover, czytelnosc).
+- Rozszerzono testy kontrolera i repozytorium o nowe przypadki.
+
+## Files Created/Modified
+
+| File | Change | Purpose |
+|------|--------|---------|
+| `autoload/admin/Controllers/ShopProductController.php` | Modified | Toggle sesyjny, render custom labels w tabeli, walidacja label_type |
+| `autoload/Domain/Product/ProductRepository.php` | Modified | Pobieranie nazw custom_label z ustawien (fallback) |
+| `admin/templates/shop-product/products-list.php` | Modified | Przekazanie flagi custom_labels_enabled do skryptu |
+| `admin/templates/shop-product/products-list-custom-script.php` | Modified | UI toggle, zapis/sugestie custom label, autocomplete, poprawki wygladu |
+| `tests/Unit/admin/Controllers/ShopProductControllerTest.php` | Modified | Testy nowych metod i walidacji kontrolera |
+| `tests/Unit/Domain/Product/ProductRepositoryTest.php` | Modified | Testy customLabelNames + walidacji sugestii/zapisu |
+
+## Decisions Made
+
+| Decision | Rationale | Impact |
+|----------|-----------|--------|
+| Session key dla toggla (`shop_product_show_custom_labels`) | Funkcja ma byc osobnym trybem widoku admina | Stabilny stan po odswiezeniu strony |
+| Nazwy etykiet z `pp_settings` + fallback | Wymaganie "nazwy z bazy" i bezpieczne zachowanie gdy brak konfiguracji | Elastyczne nazewnictwo bez hardcodu |
+| Autocomplete w jednym polu zamiast input + oddzielny select | UX feedback od usera podczas checkpointu | Czytelniejszy i szybszy flow edycji |
+
+## Deviations from Plan
+
+### Summary
+
+| Type | Count | Impact |
+|------|-------|--------|
+| Auto-fixed | 1 | Niski, techniczny (BOM w pliku kontrolera) |
+| Scope additions | 2 | Niski, UX polish po feedbacku checkpoint |
+| Deferred | 0 | Brak |
+
+**Total impact:** Niezbedne poprawki techniczne i UX bez scope creep funkcjonalnego.
+
+### Auto-fixed Issues
+
+**1. Encoding/BOM in controller file**
+- **Found during:** Task 1 implementation verification
+- **Issue:** Parser PHP zglaszal blad namespace przez BOM na poczatku pliku
+- **Fix:** Zapisano plik `ShopProductController.php` jako UTF-8 bez BOM
+- **Files:** `autoload/admin/Controllers/ShopProductController.php`
+- **Verification:** `php -l autoload/admin/Controllers/ShopProductController.php`
+
+### Deferred Items
+
+None.
+
+## Issues Encountered
+
+| Issue | Resolution |
+|-------|------------|
+| Drobne regresje UX przycisku toggle | Iteracyjna poprawka stylu i hover po feedbacku usera |
+| Forma podpowiedzi (select pod inputem) nieakceptowalna UX | Zmieniono na jedno pole z autocomplete (datalist) |
+
+## Verification Results
+
+- `php -l autoload/admin/Controllers/ShopProductController.php` -> OK
+- `php -l autoload/Domain/Product/ProductRepository.php` -> OK
+- `php -l admin/templates/shop-product/products-list-custom-script.php` -> OK
+- `php phpunit.phar tests/Unit/admin/Controllers/ShopProductControllerTest.php` -> OK (15 tests, 71 assertions)
+- `php phpunit.phar tests/Unit/Domain/Product/ProductRepositoryTest.php` -> OK (64 tests, 131 assertions)
+- Checkpoint human-verify: approved by user after final UX adjustments
+
+Skill audit:
+- `/feature-dev` - not invoked (user-approved override)
+- `/koniec-pracy` - acknowledged by user as available for end-of-session flow
+
+## Next Phase Readiness
+
+**Ready:**
+- Admin ma szybki i praktyczny workflow uzupelniania custom labels bez przechodzenia do edycji produktu.
+- Kod posiada testy regresyjne dla nowej logiki backendowej.
+
+**Concerns:**
+- Brak.
+
+**Blockers:**
+- None.
+
+---
+*Phase: 16-product-list-custom-labels, Plan: 01*
+*Completed: 2026-04-19*
diff --git a/admin/templates/shop-product/products-list-custom-script.php b/admin/templates/shop-product/products-list-custom-script.php
index 7830c84..b379ee9 100644
--- a/admin/templates/shop-product/products-list-custom-script.php
+++ b/admin/templates/shop-product/products-list-custom-script.php
@@ -1,3 +1,20 @@
+custom_labels_enabled ); ?>
+
+
+
if ( $this -> shoppro_enabled ):?>