Files
newwalls.pl/.paul/PROJECT.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

7.7 KiB
Raw Blame History

PROJECT.md

Name

newwalls.pl — PrestaShop 1.7 (theme: ayon)

Mission

Sklep z tapetami na wymiar. Klient prowadzi migrację wyglądu strony produktu na nowy layout. Do czasu zakończenia testów nowy layout jest warunkowany IP administratora.

Core Constraints

  • Stary i nowy wygląd strony produktu współegzystują w themes/ayon/templates/catalog/product.tpl:
    • Stary layout: {if $smarty.server.REMOTE_ADDR != '89.69.31.86'} ... {/if}
    • Nowy layout: {if $smarty.server.REMOTE_ADDR == '89.69.31.86'} ... {/if}
  • Nie wolno modyfikować starego layoutu (produkcja działa dla zwykłych użytkowników).
  • Partial themes/ayon/templates/catalog/_partials/product-variants.tpl jest współdzielony — zmiany w nim muszą być zgodne z oboma layoutami.
  • Stack: PrestaShop 1.7, Smarty, jQuery, SCSS (themes/ayon/assets/css/custom.scsscustom.css).

Value Proposition

Nowy layout strony produktu ma dać czystszy, bardziej prezentowalny UI konfiguratora tapety przy zachowaniu dotychczasowej funkcjonalności (wybór wariantu kolorystycznego, wymiary, dodanie do koszyka itd.).

Known Broken After Redesign

Naprawione (Phase 01)

  • .product-variants (wariant kolorystyczny) — wygląd grid 3×1 wg Figma 27:9867 + klik zmienia wariant in-place (AJAX action=refresh + history.pushState).

Naprawione (Phase 02)

  • Konfigurator „piece" (Plan 02-01) — crop + odbicie lustrzane, drag + mirror, re-init po AJAX refresh. Reuse #piece z shared partial.
  • Add-to-cart submission (Plan 02-02) — capture-phase native handler w custom.js + inline mirror, blockcart refresh, idempotency guard. Button+qty poza formą #add-to-cart-or-refresh — manualny serialize + POST.
  • Customization save + success modal (Plan 02-03) — full squaremeter payload (26 fields, verbose PL dim), chain POST do /module/ps_shoppingcart/ajax → Bootstrap #blockcart-modal. __p02p02InFlight re-entrancy guard. Inline script finally renders (Plan 02-03 {/block} move).
  • Live cena labelka (Plan 02-04) — .p02p04-total-price obok "Dodaj do koszyka", reactively updates z piece dimensions + variant AJAX refresh. Górna .current-price zostaje statyczna info-label.
  • Struktura materiału w POST payload (Plan 02-05) — enumeracja external PS attribute groups ([name^="group["] poza formą) w POST payload. Wybrana „Tekstura materiału" (<select id="group_5">) trafia do koszyka z prawidłowym id_product_attribute.

⚠️ Do naprawy (Phase 03+ / deferred)

  • Plan 02-06 (deferred nice-to-have) — systemowy cache-buster ?v=<mtime> dla <script src=custom.js>; pozwoli wycofac inline mirror z Plan 02-02/02-03/02-04/02-05.
  • Plan 02-07 — Puste bloki <div class="product-box--data"></div>: product-protect, product-installation, product-order-sample — wypełnić treścią.
  • Brakujące elementy dla pełnego PS updatedProduct flow (.product-cover-thumbnails, .js-product-images2-modal, .product-details, .product-customization, .product-additional-info) — edge case'y przy zmianie wariantu z różnymi miniaturami/opisami.
  • Resize handles bezpośrednio na #piece (deferred bonus z Plan 02-01).

Established Patterns (Phase 01)

  • Scoped CSS under body#product .product-variants-data--new — izoluje zmiany nowego layoutu od globalnych reguł i starego widoku.
  • Własny AJAX refresh w custom.jsaction=refresh (nie productrefresh), POST na window.location.href.split('?')[0].split('#')[0], dataType: 'json', header Accept: application/json.
  • In-place DOM update: history.pushState(resp.product_url) + $('.product-prices-data .product-prices').replaceWith(resp.product_prices) + $('.product_image_wrapper').html(resp.product_cover_thumbnails) + prestashop.emit('updatedProduct', resp). Fallback na window.location.reload() przy błędzie.
  • Pipeline SCSS → CSS: edytuj tylko themes/ayon/assets/css/custom.scss, custom.css auto-generowany przez user'a watcher (feedback memory).

Established Patterns (Phase 02)

  • Capture-phase native addEventListener + useCapture=true — blokuje PS core delegated handlers (bubble phase) w customowym flow, gdy trzeba całkowicie nadpisać PS behavior (Plan 02-02).
  • Idempotency guard per Plan (__p02pNNBound) — kazdy plan ma own flag, nie shared; chroni inline mirror przed blokada gdy custom.js cached stale. Separate guards pozwalaja na plan-level cache-aware deployment (Plan 02-02/03/04).
  • Re-entrancy flag (__pNNInFlight) — chroni przed podwójnym POST gdy handler i inline mirror oba firują. Reset w complete: callback jQuery.ajax (Plan 02-03).
  • Inline mirror IIFE w {block name='content'}<script> wewnatrz Smarty block, cache-safety dopóki systemowego cache-bustera (Plan 02-05) nie ma. {/block} musi zamykac się PO script (Plan 02-03 critical fix).
  • Playwright MCP ground truth capture — temporary flip IP gate → capture 26-field OLD payload przed portowaniem do NEW (Plan 02-03). Bez tego verbose PL dim format i qty_alt/qty_alth by zostaly pominiete.
  • Manual FTP deploy via curl -T ftp://... — ftp-kr VSCode watcher nie łapie zmian Claude Code Edit tool (feedback memory). Deploy 226 confirmation per file.
  • Poll-retry dla late globals (prestashop, itp.) — inline script runtime, window.prestashop moze jeszcze nie istniec. (function fn(){ if (avail) register(); else setTimeout(fn, 200); })() niezawodnie obsługuje race (Plan 02-04).
  • Synchronous IIFE init zamiast jQuery(document).ready — ready nie firuje konsekwentnie w inline Smarty block context. Synchronous call + recalc-safe early-return pokrywa DOM-not-ready case (Plan 02-04).
  • setInterval reconciliation gdy external code overwritea nasz DOM po initial render (np. squaremeter init). 10×500ms okno = 5s pokrycie (Plan 02-04).
  • External PS attribute groups enumeration[name^="group["] inputs spoza #add-to-cart-or-refresh muszą być ręcznie enumerowane i dołączane do payload ($form.serialize() ich nie łapie). Defensive closest('#form').length skip (unika duplicate gdy kiedyś przesunięte do formy) + filter radio/checkbox przez :checked (Plan 02-05).

Key Decisions (aggregated)

Data Faza/Plan Decyzja Wpływ
2026-04-23 01-01 Własny AJAX action=refresh + history.pushState zamiast PS core productrefresh In-place wariant switch bez reload; base pattern dla wszystkich subsequent AJAX updates w NEW layoucie
2026-04-23 02-01 Override totalpriceinfospecific/prod na no-op Spowodowało regresję squaremeter customization flow (Plan 02-02/03 fix); no-op zostaje ale fields syncowane manualnie w POST
2026-04-23 02-02 Capture-phase native handler (useCapture=true) Pattern dla blokowania PS core bubble handlers przy customowym flow
2026-04-23 02-02 Inline mirror IIFE w product.tpl Cache-safety dopóki Plan 02-05 nie dostarczy systemowego cache-bustera
2026-04-24 02-03 Playwright capture z flipped IP → ground truth payload Bez tego verbose PL dim format + fields (qty_alt/qty_alth/calculated_total itp.) zostałyby pominięte; dał 5/5 AC pass
2026-04-24 02-03 Move {/block} inside script wrapper Krytyczne: Smarty {extends} renderuje TYLKO blocki; inline script z Plan 02-02 był dead code przez cały czas
2026-04-24 02-04 Scope pivot: label zamiast .current-price User request mid-task; górna cena zostaje info-label, konkretna suma blisko buttona
2026-04-24 02-04 Poll-retry prestashop.on + separate __p02p04Bound Late-loading globals + stale-cache safety
2026-04-24 02-05 Enumerate [name^="group["] spoza formy → payload Future-proof: kolejne PS attribute groups pokryte automatycznie bez code change

Last updated: 2026-04-24 after Phase 02 (5 plans)