--- phase: 02-product-actions-fixes plan: 05 type: execute wave: 1 depends_on: ["02-03"] files_modified: - themes/ayon/assets/js/custom.js - themes/ayon/templates/catalog/product.tpl autonomous: false delegation: off --- ## Goal Wybrana struktura materiału (`` do formy — Bootstrap grid constraint (identyczna przyczyna jak w Plan 02-02 dla button+qty). - Double-inclusion `group[N]` jesli jest zarazem w formie i outside (defensive `closest('#add-to-cart-or-refresh').length` check). - Nadpisywania innych non-group pol spoza formy — filter strict `[name^="group["]`. - Modyfikacji Plan 02-03 sq fields injection (activation independent). Node syntax: `node -c themes/ayon/assets/js/custom.js`. AC-1 (payload zawiera group[5]) oraz AC-3 (group[4] nadal obecny) satisfied po Task 3 live verify. Task 2: FTP deploy obu plików themes/ayon/assets/js/custom.js, themes/ayon/templates/catalog/product.tpl ```bash curl -s -T "themes/ayon/assets/js/custom.js" "ftp://projectpro:i6B.b5P%7Bd6@newwalls.pl/public_html/themes/ayon/assets/js/custom.js" -w "js:%{http_code}\n" curl -s -T "themes/ayon/templates/catalog/product.tpl" "ftp://projectpro:i6B.b5P%7Bd6@newwalls.pl/public_html/themes/ayon/templates/catalog/product.tpl" -w "tpl:%{http_code}\n" ``` Expected: `js:226` + `tpl:226`. Post-deploy fetch + grep `externalGroups` na remote custom.js + product page HTML (confirm). Via Playwright `fetch('/themes/ayon/assets/js/custom.js', {cache:'no-store'})` zawiera `externalGroups` string. Deploy confirmed, Task 3 gate available. Task 3: Live verification via Playwright — wszystkie 4 AC POST payload builder rozszerzony o external `[name^="group"]` inputs spoza formy. Efekt: wybrana struktura materiału (`group[5]`) trafia do koszyka. **Setup Playwright network capture:** 1. `browser_navigate https://newwalls.pl/pl/prestige/294-4181-rain-of-flowers.html?_new=1` 2. Wait 5s (interval initial render Plan 02-04 + bindings). 3. Change `#group_5` select value do non-default (eg. "10" lub "11"): ```js const sel = document.getElementById('group_5'); sel.value = '10'; // lub inna available option sel.dispatchEvent(new Event('change', { bubbles: true })); ``` 4. Wymusic piece config: `document.getElementById('checkbox-piece').click()` (jesli nie checked). 5. Dispatchowac piece-width/height input eventy (50×50 baseline). **AC-1: POST payload capture:** 6. `browser_network_requests` przed kliknieciem — baseline. 7. Klik `.add-to-cart` button. 8. Wait 2s na POST completion. 9. `browser_network_requests` — znajdz POST do `/pl/koszyk` (lub current URL), pobrac requestBody, grep `group[5]=10`. **Expected:** payload contains `group%5B5%5D=10` (URL encoded). **AC-2: Cart display:** 10. Po POST, sprawdz `.blockcart` lub navigate do `/pl/koszyk`, czytac produkty — wybrana struktura powinna byc visible w attribute combination. **AC-3: Default case:** 11. Reload, zostaw defaults (`group[5]=9`, `group[4]=5`). 12. Add to cart, sprawdz payload zawiera `group%5B4%5D=5` AND `group%5B5%5D=9`. **AC-4: OLD layout regression:** 13. Temporary flip IP gate `'89.69.31.86'` → `'255.255.255.255'` w product.tpl via Edit + FTP. 14. Navigate, add to cart → PS core flow, zero JS errors, cart updates. 15. RESTORE IP gate. Jesli ktores AC nie spelnione — opisz specific failure (payload field missing, cart wrong structure, etc.). Type "approved" LUB describe AC failure. ## DO NOT CHANGE - Plan 02-03 add-to-cart handler core logic (piece validation, sync is_crop, sqFields build, modal fetch) — rozszerzamy tylko payload line. - Markup template product.tpl — nie przesuwamy `