--- phase: 18-google-feed-permutation-url-fix plan: 01 type: execute wave: 1 depends_on: [] files_modified: - autoload/Domain/Product/ProductRepository.php - autoload/Shared/Helpers/Helpers.php - autoload/front/LayoutEngine.php - templates/shop-product/_partial/product-attribute.php - tests/Unit/Domain/Product/ProductRepositoryTest.php - tests/Unit/Shared/Helpers/HelpersTest.php autonomous: true delegation: off --- ## Goal Naprawić linki produktów z permutacją atrybutów w feedzie Google: zamienić separator `/` na `_` między parami `attr-val`, dopasować routing `pp_routes`, konwersję `_` → `|` w warstwie front oraz preselekcję wartości atrybutów na podstawie `permutation_hash` z URL. ## Purpose URL z formatu `/slug/20-170/21-175` nie matchował się w `pp_routes` (wzorzec `[0-9-]+` nie obejmuje `/`), więc Google Merchant Center prowadził klientów na stronę główną zamiast na produkt z wybraną kombinacją atrybutów. Strata ruchu komercyjnego z feedu. ## Output - 4 pliki silnika z nowym separatorem `_` - Unit testy: regex routingu (Helpers) + generator linku (ProductRepository::appendCombinationToXml) - SUMMARY z listą akcji post-deploy do wykonania ręcznie na produkcji ## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md @.paul/codebase/architecture.md ## Source Files @autoload/Domain/Product/ProductRepository.php @autoload/Shared/Helpers/Helpers.php @autoload/front/LayoutEngine.php @templates/shop-product/_partial/product-attribute.php - **Testy** — Czy dodać unit testy dla zmian? → Odpowiedź: Tak — pełne pokrycie (Helpers regex + ProductRepository::appendCombinationToXml) - **Post-deploy** — Czy wykonać regenerację routes/cache/feedu w ramach fazy? → Odpowiedź: Nic — tylko kod; akcje produkcyjne udokumentowane w SUMMARY - **Redirect 301** — Czy dodać redirecty ze starych URL-i? → Odpowiedź: Nie — Google sam zaktualizuje linki z feedu - **Skills** — /feature-dev required w SPECIAL-FLOWS? → Odpowiedź: Override — pomiń (hotfix z konkretną instrukcją, jak w fazach 15/16/17) ## AC-1: Generator linku w feedzie używa `_` ```gherkin Given produkt z permutacją atrybutów (permutation_hash = "20-170|21-175") When wywołany jest ProductRepository::appendCombinationToXml dla feedu Google Then wygenerowany URL zawiera segment `20-170_21-175` (jeden segment, separator `_`) And nie zawiera `/` między parami atrybutów And dotyczy obu gałęzi (z seo_link i fallback p-id-name) ``` ## AC-2: Routing `pp_routes` matchuje URL z `_` ```gherkin Given wzorzec routingu wygenerowany przez Helpers dla produktu z permutacją When URI to `slug-produktu/20-170_21-175` Then regex `[0-9_-]+` dopasowuje cały segment permutacji And `permutation_hash` w wynikowych GET to `20-170_21-175` And dotyczy obu wariantów (z seo_link i fallback p-id-name) ``` ## AC-3: Front konwertuje `_` z URL na `|` przed zapytaniem do bazy ```gherkin Given GET['permutation_hash'] = "20-170_21-175" When LayoutEngine renderuje blok PRODUKT Then ProductRepository::findCached otrzymuje argument "20-170|21-175" And gdy GET['permutation_hash'] nie istnieje, findCached otrzymuje null ``` ## AC-4: Partial atrybutu preselectuje wartość z URL ```gherkin Given URL produktu z permutation_hash zawierającym parę dla bieżącego atrybutu When renderuje się templates/shop-product/_partial/product-attribute.php Then aktywna (checked) jest wartość z URL, nie z is_default And gdy atrybut nie występuje w hashu, zachowane jest stare zachowanie (is_default) And blok