5.2 KiB
5.2 KiB
phase, plan, status, unified_at
| phase | plan | status | unified_at |
|---|---|---|---|
| 01-products-cl1-column | 01 | completed | 2026-04-22 |
Summary 01-01 — Products CL1 Column
Co zostało zrobione
Task 1 — Migracja DB
- Utworzono
migrations/028_products_custom_label_1.sql(idempotentna, wzorzec 016) - Dodaje
products.custom_label_1 VARCHAR(255) NULL DEFAULT NULL AFTER min_roas
Task 2 — Factory (autoload/factory/class.Products.php)
is_product_core_field(): dodanocustom_label_1(obok zachowanychcustom_label_3/custom_label_4)get_products(): zmieniono sygnaturę o parametr$custom_label_1, SELECT/GROUP BY/order_map przepięte zcustom_label_3nacustom_label_1, dodano LIKE search i WHERE filter dla CL1get_roas_bounds(): nowy parametr$custom_label_1, analogiczny filtr WHEREget_records_total_products(): nowy parametr$custom_label_1, analogiczny filtr WHERE- Dodano metodę
get_distinct_custom_label_1( $client_id )(kopia metody CL4)
Task 3 — Controller (autoload/controls/class.Products.php)
list():- Nowa zmienna
$filter_cl1z\S::get('filter_cl1') - Przekazana do
get_roas_bounds,get_products,get_records_total_products - W pętli: pobiera
$custom_label_1przezget_product_data, wylicza$custom_label_1_color(analogiczna paleta: bestseller/deleted/zombie/pla_single/pla/paused) - Komórka CL3 (
htmlspecialchars) zastąpiona inputem<input class="custom_label_1">z kolorem
- Nowa zmienna
- Dodano endpoint
get_distinct_cl1()→ zwraca unikalne wartości CL1 dla klienta - Dodano endpoint
save_custom_label_1()→ zapis + komentarz w historii produktu
Task 4 — Template (templates/products/main_view.php)
- Nagłówek tabeli:
<th>CL3</th>→<th>CL1</th> - Nowy filtr nagłówkowy
#products_cl1przed CL4 - columnDefs:
name: 'custom_label_3'→name: 'custom_label_1' ajax.data: dodanod.filter_cl1 = $('#products_cl1').val()- Debounce 400ms dla filtra CL1 +
localStorage.setItem('products_cl1', ...) - Reset filtrów (change #client_id): dodano usuwanie
products_cl1z localStorage i czyszczenie pola - Odczyt na starcie:
savedCl1 = localStorage.getItem('products_cl1')+load_cl1_suggestions() - Pełny blok autocomplete CL1:
load_cl1_suggestions,render_cl1_datalist,bind_cl1_datalist,draw.dthook, listener change #client_id,refresh_cl1_cache_after_save - Handler
change .custom_label_1→ AJAX POST do/products/save_custom_label_1/+ toast
Zmienione pliki
migrations/028_products_custom_label_1.sql(nowy)autoload/factory/class.Products.phpautoload/controls/class.Products.phptemplates/products/main_view.php
Weryfikacja statyczna
php -l autoload/factory/class.Products.php— OKphp -l autoload/controls/class.Products.php— OK- Zero pozostałości
custom_label_3/CL3wtemplates/products/main_view.php - Zero pozostałości
custom_label_3w rendererze listy kontrolera custom_label_3zachowany wSupplementalFeed.php(linie 166/171/190/199/202/212) — AC-4custom_label_3zachowany wis_product_core_fieldw factory (potrzebny dla get/set z merchant sync)custom_label_1w field_mapGoogleAdsApi.php:438— już istniało, bez zmian
Weryfikacja runtime (do wykonania)
php install.php— zaaplikuj migrację 028- Otwórz
/products, wybierz klienta — nagłówek pokazuje CL1 zamiast CL3 - Edytuj wartość CL1 → toast „Custom Label 1 zapisany", po F5 wartość utrzymana
- Wpisz w filtrze nagłówkowym
#products_cl1— tabela zawęża wyniki po 400ms - Datalist (autocomplete) pokazuje poprzednie wartości CL1 dla klienta
- Generowanie feedu:
feeds/supplemental_{client_id}.tsvzawiera kolumnęcustom_label_3(bez zmian) - Regresja CL4: wszystkie funkcje CL4 działają jak wcześniej (edycja, filtr, autocomplete, color coding)
AC status
- AC-1 (migracja) — kod gotowy, wymaga
php install.phpdo aktywacji - AC-2 (CL1 zamiast CL3 w widoku) — zrealizowane
- AC-3 (CL1 pełne zachowanie CL4) — zrealizowane
- AC-4 (custom_label_3 w feed) — zachowane bez zmian, zweryfikowano grepem
Deviations (odchylenia od planu)
- DEV-1: columnDefs szerokość CL1 zmieniona z 50px (plan: 1:1 z CL3) na 120px (zgodność z CL4 jako kolumna z inputem). Zasugerowane przez użytkownika po pierwszym renderze — wąski input CL3 był nieczytelny dla edytowalnego pola.
- DEV-2: Pytanie diagnostyczne user nt. nadpisywania CL4 przez sync Google Ads — potwierdzono czytając
Cron.php(linie 1366, 1401, 928) orazApi.php(407): import GAds pisze tylkoclient_id/offer_id/nameprzy INSERT iproduct_url/merchant_url_not_foundprzy UPDATE.custom_label_*są nietykane. Jedyny automat piszący do CL4 —SupplementalFeed::refresh_bestseller_labels_for_client— respektuje ręczne etykiety (continuedla wartości ≠ '' i ≠ 'bestseller').
Odroczone / Known issues
- Istniejące produkty mają pustą wartość
custom_label_1— spodziewane (nowa kolumna) - GoogleAdsApi
field_mapjuż obsługujecustom_label_1→customLabel1, więc ewentualny push do Merchant Center zadziała bez dodatkowych zmian - Nie dodano automatyki label-owania dla CL1 (poza scope; bestseller rules nadal wiążą się wyłącznie z CL4)