Files
adsPRO/.paul/phases/07-xml-feed-cron-refresh/07-01-PLAN.md
2026-04-30 21:33:58 +02:00

11 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
phase plan type wave depends_on files_modified autonomous delegation
07-xml-feed-cron-refresh 01 execute 1
autoload/controls/class.Cron.php
autoload/controls/class.Clients.php
autoload/controls/class.Users.php
templates/clients/main_view.php
autoload/services/class.XmlFeedImporter.php
true off
## Goal Wydzielic import danych produktow z XML feed klienta do osobnego crona `/cron/cron_xml_feed_import`, dodac reczne odswiezanie XML feed w `/clients` oraz zdiagnozowac i naprawic brak `custom_label_1` dla produktu `offer_id=2084` klienta `pomysloweprezenty.pl`.

Purpose

Import XML feed jest niezalezny od pobierania statystyk produktow z Google Ads. Trzymanie go w cron_universal utrudnia diagnostyke, harmonogram i reczne odswiezanie z poziomu klienta. Osobny cron daje kontrolowany punkt uruchomienia i jasny raport, a analiza offer_id=2084 ma potwierdzic, czy problem wynika z endpointu, mapowania klienta, parsera XML, duplikatow w products, czy braku pola w feedzie.

Output

  • Nowa akcja \controls\Cron::cron_xml_feed_import() dostepna jako /cron/cron_xml_feed_import.
  • Usuniecie automatycznego importu XML z cron_universal.
  • Nowa opcja w menu odswiezania klienta na /clients: XML Feed.
  • Clients::force_sync uruchamia import XML natychmiast dla wskazanego klienta i zwraca raport JSON.
  • Diagnostyka i ewentualny fix pobierania custom_label_1 dla pomysloweprezenty.pl, offer_id=2084.
- **Endpoint** - Jaki endpoint ma miec osobny cron XML? -> Odpowiedz: `/cron/cron_xml_feed_import`, metoda `\controls\Cron::cron_xml_feed_import()`. - **Zakres diagnozy** - Czy produkt `offer_id=2084` klienta `pomysloweprezenty.pl` robimy w tym samym planie? -> Odpowiedz: Tak, w tym samym planie. - **Cron universal** - Czy zostawic import XML jako czesc `cron_universal`? -> Odpowiedz: Nie. XML feed ma byc niezalezny od pobierania produktow. - **UI clients** - Gdzie ma byc mozliwosc odswiezenia? -> Odpowiedz: W `/clients`, w obecnym miejscu odswiezania danych klienta.

Project Context

@.paul/STATE.md @.paul/phases/06-xml-feed-import/06-01-SUMMARY.md @CLAUDE.md

Source Files

@autoload/controls/class.Cron.php @autoload/controls/class.Clients.php @autoload/controls/class.Users.php @templates/clients/main_view.php @autoload/services/class.XmlFeedImporter.php @autoload/factory/class.Clients.php

<acceptance_criteria>

AC-1: Osobny cron XML feed

Given klient ma ustawiony `clients.xml_feed_url`
When wywolam `/cron/cron_xml_feed_import` bez `client_id`
Then cron wybiera aktywnego klienta z `xml_feed_url` i uruchamia `XmlFeedImporter::import_for_client()`
And zwraca JSON z `client_id`, `feed_url`, `fetched`, `updated`, `inserted`, `skipped`, `errors`, `peak_memory_mb`, `duration_ms`
And ustawia `clients.xml_feed_last_sync_at` przez importer po udanym przebiegu

AC-2: Reczne odswiezanie XML feed w /clients

Given jestem na `https://adspro.projectpro.pl/clients`
When rozwijam menu odswiezania przy kliencie z `xml_feed_url`
Then widze opcje `XML Feed`
When klikam `XML Feed`
Then aplikacja uruchamia import natychmiast dla tego klienta
And pokazuje komunikat z liczba pobranych/zaktualizowanych/dodanych/pominietych pozycji albo czytelny blad

AC-3: XML feed niezalezny od cron_universal

Given uruchamia sie `/cron/cron_universal`
When cron synchronizuje kampanie i produkty Google Ads
Then nie wywoluje `XmlFeedImporter::import_for_client()`
And response `cron_universal` nie zawiera juz importu XML jako czesci sync produktow
And import XML mozna uruchomic tylko przez `/cron/cron_xml_feed_import` albo reczna akcje `/clients`

AC-4: Diagnoza i fix custom_label_1 dla offer_id 2084

Given klient `pomysloweprezenty.pl` ma skonfigurowany XML feed
When uruchomie import XML dla tego klienta
Then importer poprawnie odczytuje `g:custom_label_1` dla pozycji `g:id=2084`, jesli pole istnieje w feedzie
And rekord albo rekordy `products` tego klienta z `offer_id='2084'` maja uzupelnione `custom_label_1`
And jesli feed nie zawiera tej wartosci, raport diagnostyczny jasno wskazuje `custom_label_1_missing_in_feed`

</acceptance_criteria>

Task 1: Wydziel osobny cron XML feed autoload/controls/class.Cron.php, autoload/controls/class.Users.php Dodaj publiczna metode `cron_xml_feed_import()` w `autoload/controls/class.Cron.php`.
Wymagane zachowanie:
- Ustaw `self::$current_cron_action = __FUNCTION__` i wywolaj `self::touch_cron_invocation(__FUNCTION__)`.
- Obsluz `client_id` z requestu: jesli podany, importuj dokladnie tego aktywnego klienta z niepustym `xml_feed_url`.
- Bez `client_id` wybierz jednego aktywnego klienta z niepustym `xml_feed_url`, najlepiej po `xml_feed_last_sync_at ASC` z `NULL` jako pierwsze. To ogranicza czas jednego uruchomienia i pasuje do istniejacych cronow per klient.
- Uruchom `\services\XmlFeedImporter::import_for_client((int) $client['id'])` i zwroc `self::output_cron_response()` z raportem.
- Nie wymagaj Google Ads API ani Merchant API do importu XML.
- Dodaj endpoint do dashboardu cron w `autoload/controls/class.Users.php` jako `/cron/cron_xml_feed_import` z opisem harmonogramu.

Usun wywolania `XmlFeedImporter::import_for_client()` z `cron_universal`, z obu sciezek: wymuszonego `client_id` i automatycznego pipeline, jezeli wystepuja.

Avoid: laczenie statusu XML z `cron_sync_status` pipeline `products`, bo XML feed ma byc niezaleznym procesem.
`php -l autoload/controls/class.Cron.php` i `php -l autoload/controls/class.Users.php`; grep `XmlFeedImporter::import_for_client` pokazuje wywolanie w `cron_xml_feed_import` i ewentualnie w `Clients::force_sync`, ale nie w `cron_universal`. AC-1 i AC-3 satisfied Task 2: Dodaj reczne odswiezanie XML Feed w /clients autoload/controls/class.Clients.php, templates/clients/main_view.php Rozszerz istniejace menu odswiezania w `templates/clients/main_view.php`: - Dla klienta z niepustym `xml_feed_url` pokaz przycisk `XML Feed` w dropdownie `sync-dropdown-menu`. - Uzyj istniejacego `syncFromMenu(id, pipeline, btn)` z nowym `pipeline = 'xml_feed'`. - Dodaj etykiete `xml_feed: 'XML feedu'` w obiekcie `labels`. - Dla odpowiedzi natychmiastowej pokaz komunikat z liczbami z raportu: fetched/updated/inserted/skipped; przy bledach pokaz czytelny komunikat.
W `autoload/controls/class.Clients.php` znajdz metode `force_sync` i dodaj obsluge `pipeline === 'xml_feed'`:
- Waliduj klienta, aktywnosc i obecne `xml_feed_url`.
- Uruchom `\services\XmlFeedImporter::import_for_client($id)` natychmiast.
- Zwroc JSON `{ success: true, immediate: true, pipeline: 'xml_feed', report: ... }` albo `{ success: false, message: ... }`.
- Nie kolejkuj tego przez `cron_sync_status`, bo wymaganie mowi o niezaleznym odswiezeniu w `/clients`.

Avoid: wymagania `google_ads_customer_id` dla przycisku XML feed. Do XML wystarczy aktywny klient i `xml_feed_url`.
`php -l autoload/controls/class.Clients.php`; reczne klikniecie `/clients` -> XML Feed zwraca alert z raportem i aktualizuje `clients.xml_feed_last_sync_at`. AC-2 satisfied Task 3: Zdiagnozuj i napraw custom_label_1 dla pomysloweprezenty.pl offer_id 2084 autoload/services/class.XmlFeedImporter.php, autoload/controls/class.Cron.php Dodaj minimalna diagnostyke ukierunkowana na przypadki braku pola po imporcie, bez stalego logowania kazdego produktu: - Dodaj opcjonalny parametr requestu dla crona, np. `debug_offer_id=2084` albo `offer_id=2084`, ktory przekazesz do importera tylko w raporcie diagnostycznym. - W `XmlFeedImporter` dodaj lekka obsluge diagnostyczna: kiedy parsowany `offer_id` odpowiada debugowanemu ID, zapisz w raporcie `debug_offer` z polami: `found_in_feed`, `custom_label_1_raw_present`, `custom_label_1_value`, `title_present`, `matched_existing_rows`, `updated_rows`. - Sprawdz parser `extract_item_fields()`: ma obslugiwac `g:custom_label_1` w namespace `http://base.google.com/ns/1.0`; jesli realny feed uzywa innej formy (np. bez namespace albo z prefiksem zachowanym jako nazwa), dodaj punktowa obsluge fallback bez ladowania calego XML do pamieci. - Sprawdz `flush_batch()`: dla istniejacych rekordow z `offer_id=2084` `custom_label_1` ma sie aktualizowac, gdy wartosc z feedu nie jest pusta. Jesli feed ma pusta wartosc, nie nadpisuj istniejacej wartosci pustka. - Jesli klient `pomysloweprezenty.pl` ma wiele rekordow `products` z tym samym `offer_id`, zachowaj aktualne zalozenie z fazy 06: aktualizuj wszystkie legacy duplikaty.
Po implementacji uruchom lub opisz weryfikacje:
`/cron/cron_xml_feed_import/client_id=<ID_KLIENTA>&debug_offer_id=2084`
i sprawdz w raporcie, czy `debug_offer` wskazuje przyczyne.

Avoid: hardcodowania domeny `pomysloweprezenty.pl` albo `2084` w logice produkcyjnej. To ma byc parametr diagnostyczny.
`php -l autoload/services/class.XmlFeedImporter.php`; import dla klienta `pomysloweprezenty.pl` z `debug_offer_id=2084` zwraca `debug_offer`; po imporcie SELECT po `client_id` i `offer_id='2084'` pokazuje uzupelnione `custom_label_1` albo raport jasno pokazuje brak wartosci w feedzie. AC-4 satisfied

DO NOT CHANGE

  • migrations/001-029 bez wyraznej potrzeby; ten plan nie wymaga zmiany schematu.
  • Semantyka z fazy 06: title/description sa danymi zrodlowymi, title_gmc/description_gmc sa edytowalne i ida do supplemental feed.
  • Importer nie moze nadpisywac custom_label_1 pustka z feedu.
  • Nie laczyc XML feed z Google Ads API ani Merchant API.

SCOPE LIMITS

  • Brak nowego dashboardu historii importow XML.
  • Brak kolejki cron_sync_status dla XML feed.
  • Brak deduplikacji products dla legacy duplikatow (client_id, offer_id).
  • Brak nowych pol z feedu poza diagnostyka custom_label_1.
  • Brak przebudowy calego UI /clients; tylko dodatkowa opcja w istniejacym dropdownie.
Before declaring plan complete: - [ ] `php -l autoload/controls/class.Cron.php` - [ ] `php -l autoload/controls/class.Clients.php` - [ ] `php -l autoload/services/class.XmlFeedImporter.php` - [ ] `rg -n "XmlFeedImporter::import_for_client" autoload/controls/class.Cron.php autoload/controls/class.Clients.php` potwierdza brak wywolania w `cron_universal` - [ ] `/cron/cron_xml_feed_import?client_id=` zwraca raport importu bez wymagania Google Ads API - [ ] `/clients` pokazuje opcje `XML Feed` dla klienta z `xml_feed_url` - [ ] Klikniecie `XML Feed` w `/clients` wykonuje import natychmiast i pokazuje raport - [ ] Debug `offer_id=2084` dla `pomysloweprezenty.pl` wskazuje przyczyne braku `custom_label_1` albo naprawia zapis - [ ] Wszystkie AC-1 do AC-4 spelnione

<success_criteria>

  • XML feed ma osobny endpoint cron i nie jest czescia cron_universal.
  • Klient moze recznie odswiezyc XML feed z /clients.
  • Import XML dziala bez konfiguracji Google Ads/Merchant API.
  • Problem custom_label_1 dla offer_id=2084 jest zdiagnozowany i naprawiony, jezeli wartosc istnieje w feedzie.
  • Brak regresji w dotychczasowym pobieraniu kampanii i produktow Google Ads. </success_criteria>
After completion, create `.paul/phases/07-xml-feed-cron-refresh/07-01-SUMMARY.md`