--- phase: 79-personalization-message-field plan: 01 type: execute wave: 1 depends_on: [] files_modified: - src/Modules/Settings/ShopproOrderMapper.php - DOCS/ARCHITECTURE.md - DOCS/TECH_CHANGELOG.md autonomous: true --- ## Goal Dodanie pola `message` z API shopPRO do personalizacji produktow w zamowieniach. Aktualnie `extractPersonalization()` sprawdza tylko `attributes` i `custom_fields`, a shopPRO zwraca rowniez pole `message` z wiadomoscia personalizacji klienta (np. "Milenie na pamiatke I Komunii Swietej"). ## Purpose Klienci wpisuja wiadomosci personalizacji przy zamowieniach w shopPRO. Te dane sa kluczowe dla realizacji zamowien (np. grawerunki, dedykacje). Bez ich importu pracownik musi reczne sprawdzac dane w shopPRO. ## Output - Zaktualizowany `extractPersonalization()` w ShopproOrderMapper — obsluguje pole `message` - Istniejace zamowienia z `message` w payload_json — backfill personalizacji - Zaktualizowana dokumentacja ## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md ## Source Files @src/Modules/Settings/ShopproOrderMapper.php (metoda extractPersonalization, linia ~590) No specialized flows required for this plan. ## AC-1: Pole message importowane do personalizacji ```gherkin Given zamowienie shopPRO z pozycja majaca pole "message" w odpowiedzi API When pozycja jest importowana/aktualizowana przez ShopproOrderMapper Then wartosc pola "message" jest zapisana w kolumnie personalization tabeli order_items ``` ## AC-2: Laczenie message z attributes i custom_fields ```gherkin Given pozycja shopPRO majaca zarowno "attributes" jak i "message" When extractPersonalization przetwarza dane Then oba pola sa polaczone w personalization oddzielone nowa linia And pole "message" jest poprzedzone etykieta "Wiadomosc:" ``` ## AC-3: Backfill istniejacych zamowien ```gherkin Given istniejace pozycje zamowien z polem "message" w payload_json ale pustym personalization When uruchomiona jest migracja/skrypt backfill Then kolumna personalization zostaje wypelniona danymi z payload_json.message ``` Task 1: Dodanie pola message do extractPersonalization src/Modules/Settings/ShopproOrderMapper.php W metodzie `extractPersonalization()` (linia ~590): 1. Dodac pole `message` do listy sprawdzanych pol OSOBNO po petli attributes/custom_fields 2. Wartosc message powinna byc poprzedzona etykieta "Wiadomosc: " (z dwukropkiem i spacja) 3. Zachowac istniejaca logike czyszczenia HTML (strip_tags, html_entity_decode, trim) 4. Jesli message jest jedynym polem — zwrocic "Wiadomosc: {tresc}" 5. Jesli sa tez attributes/custom_fields — dodac message na koncu po nowej linii Logika: ``` // Po istniejącej pętli attributes/custom_fields: $message = $this->readPath($row, ['message']); if ($message !== null && $message !== '' && $message !== false) { $text = str_replace(['
', '
', '
'], "\n", (string) $message); $text = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8'); $text = trim($text); if ($text !== '') { $parts[] = 'Wiadomość: ' . $text; } } ```
Sprawdzic w kodzie ze extractPersonalization obsluguje 3 pola: attributes, custom_fields, message. Zweryfikowac ze message jest poprzedzony etykieta "Wiadomosc:". AC-1 i AC-2 satisfied: pole message jest importowane do personalizacji z etykieta
Task 2: Migracja backfill personalizacji z payload_json database/migrations/20260407_000080_backfill_personalization_message.sql Utworzyc migracje SQL ktora: 1. Aktualizuje kolumne personalization dla pozycji majacych message w payload_json 2. Warunek: personalization IS NULL AND payload_json zawiera niepuste pole message 3. Uzyc JSON_UNQUOTE(JSON_EXTRACT(payload_json, '$.message')) do wyciagniecia wartosci 4. Ustawic personalization = CONCAT('Wiadomość: ', extracted_message) 5. Jesli personalization juz istnieje (nie NULL) — nie nadpisywac (dodac do WHERE) Uwaga: Jezeli pozycja ma tez attributes/custom_fields w payload_json, sam SQL nie zbuduje pelnej personalizacji. Dla prostoty: backfill dotyczy TYLKO pozycji z pustym personalization. Pozycje z istniejacym personalization (z attributes/custom_fields) i brakujacym message — pomijamy (przyszly re-import uzupelni je poprawnie dzieki Task 1). Uruchomic migracje na bazie i sprawdzic ze pozycje zamowienia #217 maja wypelniona personalizacje z polem Wiadomosc. AC-3 satisfied: istniejace zamowienia maja uzupelniona personalizacje Task 3: Aktualizacja dokumentacji DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md 1. W ARCHITECTURE.md — zaktualizowac opis ShopproOrderMapper::extractPersonalization o pole message 2. W TECH_CHANGELOG.md — dodac wpis o rozszerzeniu importu personalizacji o pole message Sprawdzic ze dokumenty sa aktualne Dokumentacja zaktualizowana
## DO NOT CHANGE - Logika importu zamowien (OrderImportRepository) — zmiana tylko w mapperze - Widok show.php — juz obsluguje personalizacje (nl2br), nie wymaga zmian - Struktura tabeli order_items — kolumna personalization juz istnieje ## SCOPE LIMITS - Nie zmieniamy sposobu wyswietlania personalizacji w widoku (juz dziala) - Nie dodajemy nowych kolumn do bazy - Backfill tylko dla pozycji z pustym personalization (nie nadpisujemy istniejacych) Before declaring plan complete: - [ ] extractPersonalization obsluguje pola: attributes, custom_fields, message - [ ] Pole message jest poprzedzone etykieta "Wiadomosc:" - [ ] Migracja backfill wykonana pomyslnie - [ ] Zamowienie #217 wyswietla personalizacje z wiadomosciami - [ ] Dokumentacja zaktualizowana - Nowe zamowienia shopPRO z polem message importuja personalizacje - Istniejace zamowienia z message w payload_json maja uzupelniona personalizacje - Brak regresji w imporcie zamowien After completion, create `.paul/phases/79-personalization-message-field/79-01-SUMMARY.md`