Files
newwalls.pl/.paul/phases/02-product-actions-fixes/02-05-PLAN.md
Jacek Pyziak ac03f807c1 feat(02-product-actions-fixes): Phase 02 complete — customization, price label, structure fix
Plan 02-03: Customization save + success modal (5/5 AC)
- 26-field squaremeter POST payload (verbose PL dim, qty_alt/qty_alth)
- Chain POST /module/ps_shoppingcart/ajax -> Bootstrap #blockcart-modal
- Critical fix: moved {/block} so inline script actually renders
- __p02p02InFlight re-entrancy guard

Plan 02-04: Live cena per-sqm label obok "Dodaj do koszyka" (5/5 AC)
- .p02p04-total-price label, gorna .current-price static
- Separate __p02p04Bound + setInterval reconciliation
- Poll-retry prestashop.on registration

Plan 02-05: Struktura materialu w POST payload (4/4 AC)
- Enumerate [name^="group["] spoza formy, doklej do payload
- Fix: group_5 select w .product-bar-box nie trafial do koszyka

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:55:05 +02:00

11 KiB
Raw Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
phase plan type wave depends_on files_modified autonomous delegation
02-product-actions-fixes 05 execute 1
02-03
themes/ayon/assets/js/custom.js
themes/ayon/templates/catalog/product.tpl
false off
## Goal Wybrana struktura materiału (`` — atrybut „Tekstura materiału") **zapisuje się do koszyka** w nowym layoucie. Obecnie select jest poza formą `#add-to-cart-or-refresh` (w `.product-bar-box`), wiec `$form.serialize()` go nie łapie → POST payload nie zawiera `group[5]` → PS zapisuje wrong attribute combination. Purpose Phase 02 complete ale 02-03 UNIFY pominął że niektóre PS attribute group inputs są poza formą (identyczny pattern jak button+qty z Plan 02-02). Kolor (group[4]) działa bo radios są w formie. Struktura (group[5]) nie — select jest w product-bar, poza formą. Bug production-blocking dla milestone (klient kupuje złą strukturę). Output Zmiana w POST payload builder: enumeruj WSZYSTKIE [name^="group"] poza #add-to-cart-or-refresh i dołącz do payload. Zmiany w custom.js + inline mirror w product.tpl (identyczne, identity semantics). Zero zmian markupie templatu (nie przesuwamy selecta do formy — Bootstrap grid constraint jak przy qty/button). Summary: .paul/phases/02-product-actions-fixes/02-05-SUMMARY.md. ## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md Prior Work (direct dependency) @.paul/phases/02-product-actions-fixes/02-03-SUMMARY.md Plan 02-03 ustalił pattern: $form.serialize() + dodatkowe pola (qty, sq fields) encodeURIComponent'owane w payload. Ten plan rozszerza payload o group[N] inputy spoza formy. Source Files @themes/ayon/assets/js/custom.js Line ~1083: payload construction w add-to-cart handler: var payload = $form.serialize() + '&qty=' + ... + '&' + sqFields + ... Tutaj wstrzyknąć enumerację external group inputs. @themes/ayon/templates/catalog/product.tpl Line ~853: inline mirror ma identyczny payload builder (jQuery). ## Required Skills Skill Priority When to Invoke Loaded? Playwright MCP (mcp__plugin_playwright_playwright__*) required Task 3 live verification + payload capture ✓ BLOCKING: Playwright MCP wymagany w Task 3 — inspect POST payload + cart contents. <acceptance_criteria> AC-1: group[5] (struktura) w POST payload Given user na stronie produktu w NEW layoucie (IP 89.69.31.86) And select `#group_5` ma value "10" (inna struktura niż default value "9") And piece configured (50×50, checkbox-piece checked) When user klika "Dodaj do koszyka" Then POST /pl/koszyk zawiera `group[5]=10` w body And (wszystkie inne `group[N]` spoza formy tez są w body — future-proof dla kolejnych attribute groups) AC-2: Cart wyświetla wybraną strukturę Given user zmieni select `#group_5` na strukturę "X" (nie default) And doda produkt do koszyka When blockcart modal się otworzy (Plan 02-03) Then modal (lub preview .blockcart content) pokazuje nazwę struktury "X" Or (jeśli modal nie pokazuje atrybutów) cart page `/pl/koszyk` pokazuje strukturę "X" AC-3: Kolor (group[4]) nadal działa Given user nie zmieni nic, zaakceptuje default color + default structure When POST firuje Then payload zawiera zarowno `group[4]=5` (default color) jak i `group[5]=9` (default structure) And cart pokazuje correct combination AC-4: Zero regression OLD layout Given strona produktu poza IP 89.69.31.86 (OLD layout) When user klika "Dodaj do koszyka" Then PS core handler działa jak dotychczas (zero zmian w flow OLD) And nie ma JS errors w console </acceptance_criteria> Task 1: Inject external group[N] inputs do POST payload themes/ayon/assets/js/custom.js, themes/ayon/templates/catalog/product.tpl W custom.js (add-to-cart handler, obecna linia gdzie payload jest budowany): Znajdź linię: ```js var payload = $form.serialize() + '&qty=' + encodeURIComponent(qty) + '&' + sqFields + '&add=1&action=update'; ``` Dodaj PRZED tą linią (lub nad budowaniem payload): ```js // Plan 02-05: group[N] inputy spoza formy (np. #group_5 "Tekstura materiału" // w .product-bar-box). $form.serialize() ich nie łapie. Enumeruj i dołącz. var externalGroups = ''; $('[name^="group["]').each(function() { var $el = $(this); // Skip te ktore juz sa w formie (bo $form.serialize() je ma) if ($el.closest('#add-to-cart-or-refresh').length) return; // Dla radio/checkbox: uwzglednij tylko checked if (($el.attr('type') === 'radio' || $el.attr('type') === 'checkbox') && !$el.prop('checked')) return; var n = $el.attr('name'); var v = $el.val(); if (v === undefined || v === null || v === '') return; externalGroups += '&' + encodeURIComponent(n) + '=' + encodeURIComponent(v); }); ``` Potem zmień payload line na: ```js var payload = $form.serialize() + '&qty=' + encodeURIComponent(qty) + externalGroups + '&' + sqFields + '&add=1&action=update'; ``` Dopisz IDENTYCZNY blok w product.tpl inline mirror (używając `jQuery` zamiast `$`). **Unikaj:** - Przesuwania `<select id="group_5">` 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 <select id="group_5"> do formy (Bootstrap grid risk, identyczny powod jak przy button+qty w Plan 02-02). Shared _partials/*.tpl — tylko custom.js + inline mirror w product.tpl. modules/squaremeter/* — zero edit. OLD layout {if REMOTE_ADDR != '89.69.31.86'} block — niedotknięty (AC-4). Plan 02-04 price label logic — niezwiązany z tym fixem. SCOPE LIMITS Ten plan NIE rebuilduje attribute selector UI — tylko POST payload coverage. Ten plan NIE obsluguje edge case'ow (np. disabled options, group[N] w modal/hidden tab) poza tym ze filtruje radio/checkbox przez :checked. Ten plan NIE adresuje potencjalnego refresh variant flow gdy user zmienia group[5] (Plan 01-01 handler on group[4] change może lub może nie pokrywać group[5] — audit defer). Brak nowych dependencies. Przed UNIFY: - [ ] AC-1: Playwright captures POST body zawierający `group%5B5%5D=`. - [ ] AC-2: Cart pokazuje wybraną strukturę. - [ ] AC-3: Default case — `group[4]=5` AND `group[5]=9` oba w payload. - [ ] AC-4: OLD layout test pass, zero JS errors. - [ ] Git diff clean: zero zmian poza custom.js + product.tpl. - [ ] Kod identyczny w obu miejscach. - [ ] FTP deploy 226/226. <success_criteria> Wszystkie 4 AC pass w live Playwright test. Zero regresji: kolor variant, customization, modal, price label (Plan 01-01/02-02/02-03/02-04) nietknięte. SUMMARY.md dokumentuje pattern "enumerate external group inputs for PS attribute groups poza formą". </success_criteria> Po zakończeniu: `.paul/phases/02-product-actions-fixes/02-05-SUMMARY.md`