--- phase: 14-custom-fields-delete-bug plan: 01 type: execute wave: 1 depends_on: [] files_modified: - admin/templates/shop-product/product-edit-custom-script.php - autoload/Domain/Product/ProductRepository.php autonomous: true delegation: off --- ## Goal Naprawić bug: usunięcie WSZYSTKICH dodatkowych pól produktu w panelu admina nie działa — pola pozostają po zapisie. ## Purpose Właściciel sklepu musi mieć możliwość usunięcia wszystkich custom fields z produktu. Obecny bug blokuje tę operację. ## Output - Poprawiony JS w szablonie — hidden field gwarantujący obecność klucza `custom_field_name` w POST - Defensive check w repozytorium (opcjonalnie) - Test jednostkowy potwierdzający poprawkę ## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md ## Source Files @admin/templates/shop-product/product-edit-custom-script.php @autoload/Domain/Product/ProductRepository.php ## AC-1: Usunięcie wszystkich custom fields zapisuje pusty stan ```gherkin Given produkt ma 2 dodatkowe pola (np. "Grawerunek", "Kolor") When admin usuwa oba pola i klika "Zatwierdź" Then po zapisie produkt nie ma żadnych dodatkowych pól And tabela pp_shop_products_custom_fields nie zawiera rekordów dla tego produktu ``` ## AC-2: Częściowe usunięcie nadal działa ```gherkin Given produkt ma 3 dodatkowe pola When admin usuwa 1 pole i klika "Zatwierdź" Then po zapisie produkt ma 2 dodatkowe pola And usunięte pole nie istnieje w bazie ``` ## AC-3: Dodawanie pól nadal działa ```gherkin Given produkt nie ma dodatkowych pól When admin dodaje 2 nowe pola i klika "Zatwierdź" Then po zapisie produkt ma 2 dodatkowe pola ``` Task 1: Dodać hidden field gwarantujący klucz custom_field_name w POST admin/templates/shop-product/product-edit-custom-script.php W szablonie product-edit-custom-script.php dodać ukryte pole w sekcji custom fields: ```html ``` To pole musi być ZAWSZE obecne w formularzu (nie wewnątrz dynamicznych wierszy pól), tak aby serwer wiedział, że sekcja custom fields była obecna w formularzu. ALTERNATYWNIE (lepsze rozwiązanie): zamiast hidden field, zmienić warunek w ProductRepository z `array_key_exists('custom_field_name', $d)` na sprawdzanie obecności markera `custom_field_name_present`. Podejście: dodać hidden field `custom_field_name_present` w szablonie + zmienić warunek w ProductRepository na: ```php if ( array_key_exists( 'custom_field_name_present', $d ) ) { ``` Dzięki temu: - Gdy formularz jest renderowany → marker ZAWSZE w POST → saveCustomFields() ZAWSZE wywoływany - Gdy API partial update bez custom fields → marker BRAK → skip (backward compat) 1. Otworzyć edycję produktu z custom fields w przeglądarce 2. Usunąć wszystkie pola → Zatwierdź → sprawdzić że pola zniknęły 3. Otworzyć ponownie → potwierdzić brak pól AC-1 satisfied: usunięcie wszystkich pól działa poprawnie Task 2: Test jednostkowy — saveCustomFields z pustą listą tests/Unit/Domain/Product/ProductRepositoryTest.php Dodać test weryfikujący że saveCustomFields() z pustymi tablicami wywołuje delete na pp_shop_products_custom_fields dla danego produktu. Test powinien mockować Medoo i sprawdzić: - Że `delete('pp_shop_products_custom_fields', ['id_product' => $productId])` jest wywoływany - Że żaden insert/update nie jest wywoływany saveCustomFields() jest private — użyć Reflection do wywołania lub testować przez publiczną metodę saveProduct() z odpowiednim payloadem zawierającym `custom_field_name_present` i puste tablice. ./test.ps1 --filter testSaveCustomFieldsDeletesAllWhenEmpty AC-1 potwierdzone testem jednostkowym ## DO NOT CHANGE - Logika saveCustomFields() dla niepustych list pól (insert/update) — działa poprawnie - API partial update — brak markera = skip custom fields (backward compat) - Inne sekcje formularza edycji produktu ## SCOPE LIMITS - Tylko naprawa buga usuwania pól — żadne refactoring ani nowe feature - Nie zmieniać struktury tabeli pp_shop_products_custom_fields Before declaring plan complete: - [ ] Usunięcie wszystkich custom fields → po zapisie brak pól (AC-1) - [ ] Usunięcie części custom fields → pozostałe zachowane (AC-2) - [ ] Dodanie nowych custom fields → poprawnie zapisane (AC-3) - [ ] Testy przechodzą: ./test.ps1 - [ ] Brak regresji w istniejących testach - Wszystkie 3 AC spełnione - Test jednostkowy przechodzi - Zero regresji w istniejącym test suite (820+ testów) After completion, create `.paul/phases/14-custom-fields-delete-bug/14-01-SUMMARY.md`