Files
adsPRO/.paul/phases/05-products-scope-history-delete/05-01-SUMMARY.md
2026-04-30 01:04:06 +02:00

7.9 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, started, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration started completed
05-products-scope-history-delete 01 ui
products
datatables
breakdown
delete
history
php
jquery
transactions
phase provides
04-products-aggregate-breakdown rozwijane podwiersze breakdown per kampania+grupa z payloadem row_meta.breakdown_rows
Lokalne usuwanie wpisow statystyczno-historycznych per trojka product_id+campaign_id+ad_group_id z UI breakdown
Endpoint AJAX `/products/delete_product_scope_history/`
Factory method `\factory\Products::delete_product_scope_history()` (transakcja PDO)
Kolumna "Akcje" w tabeli rozbicia + dialog `$.confirm` z potwierdzeniem
Odswiezony, schludniejszy styl ikony rozwijania breakdown (CSS rotate, hover, stan open)
autoload/factory/class.Products.php (delete API)
autoload/controls/class.Products.php (payload breakdown_for_view + nowa akcja)
templates/products/main_view.php (kolumna Akcje + handler + style)
added patterns
Hard delete scope-level: AGGREGATE + HISTORY + HISTORY_30 atomowo w transakcji PDO
Breakdown payload eksponuje pelna trojke ID (product, campaign, ad_group) dla operacji per-wiersz
Toggle expand stylowany CSS-em (rotate 90deg) zamiast swapu klas FA w JS
created modified
autoload/factory/class.Products.php
autoload/controls/class.Products.php
templates/products/main_view.php
Hard delete lokalny w transakcji - bez Google Ads API, bez ruszania tabeli `products`
Eksponowanie product_id/campaign_id/ad_group_id w breakdown_for_view (poza zaplanowana edycja factory)
Style toggle: chevron rotowany przez CSS, JS nie podmienia klas FA
Operacje per-wiersz w child rows DataTables wymagaja eksponowania ID we payloadzie row_meta - nie polegaj na danych z parent row
Transakcja PDO przed serwisem Medoo: `$mdb->pdo->beginTransaction()` + `commit/rollBack` + `$pdo->inTransaction()` guard
~30min 2026-04-29T18:35:00Z 2026-04-29T19:05:00Z

Phase 5 Plan 01: Products Scope History Delete (Summary)

Dodano w UI /products na rozwijanym podwierszu breakdown przycisk usuwania, ktory atomowo kasuje wpisy z products_aggregate, products_history i products_history_30 dla konkretnej trojki product+campaign+ad_group, bez ruszania tabeli products i bez wywolan Google Ads API.

Performance

Metric Value
Duration ~30 min
Started 2026-04-29T18:35:00Z
Completed 2026-04-29T19:05:00Z
Tasks 4/4 (3 auto + 1 human-verify) + 1 unplanned bonus (toggle styling)
Files modified 3

Acceptance Criteria Results

Criterion Status Notes
AC-1: Endpoint usuwa lokalne wpisy dla trojki product+campaign+ad_group Pass Factory uzywa $mdb->delete() z dokladnym WHERE per kazda z 3 tabel; transakcja PDO; inne trojki nietkniete (zweryfikowane przez usera)
AC-2: Walidacja parametrow i bledow Pass Controller: product_id <= 0 -> {status:error,message:...} przed wywolaniem factory; factory tez waliduje (defense in depth)
AC-3: UI kolumny Akcje + potwierdzenie Pass Nowa kolumna "Akcje" widoczna na koncu breakdown; ikona kosza fa-solid fa-trash w btn btn-sm btn-danger; dialog $.confirm z nazwa kampanii/grupy + przyciski "Usun"/"Anuluj"
AC-4: UI po sukcesie aktualizuje sie bez utraty stanu Pass $tr.remove() + products_table.ajax.reload(null,false); toast PL na success; $.alert z res.message na blad - human-verify approved

Accomplishments

  • Dodano scope-level usuwanie historii produktu z UI breakdown bez ryzyka skasowania samego produktu ani wplywu na inne trojki kampania/grupa.
  • Atomowa operacja DELETE-z-trzech-tabel w pojedynczej transakcji PDO z guardem inTransaction() i rollBack na throw.
  • Naprawiono nieoczywisty bug: breakdown_for_view nie eksponowal ID, przez co handler dostawal undefined i nic sie nie dzialo - dolozono trzy pola.
  • Bonus: ikona rozwijania breakdown przemodelowana na okragly button (hover, fioletowy stan open, CSS rotate chevron) - usunieto JS swap klas FA.

Task Commits

Brak commitu fazowego na tym etapie (working tree zawiera tez .vscode/ftp-kr.sync.cache.json, .serena/project.yml i .paul/STATE.md z innych watkow).

Files Created/Modified

File Change Purpose
autoload/factory/class.Products.php Modified (+51) Nowa metoda delete_product_scope_history($pid,$cid,$agid) z transakcja PDO i 3-tabelowym DELETE
autoload/controls/class.Products.php Modified (+23 +3) Nowa akcja AJAX delete_product_scope_history(); payload breakdown_for_view rozszerzony o product_id, campaign_id, ad_group_id
templates/products/main_view.php Modified (+86, ~30 styling) Kolumna "Akcje" w products_build_breakdown_html, handler kliku z $.confirm, przebudowane style .products-breakdown-toggle (CSS rotate zamiast JS), CSS td:last-child szerokosci 56px

Decisions Made

Decision Rationale Impact
Eksponowac product/campaign/ad_group ID w breakdown_for_view Bez tego JS dostawal undefined ID i handler ucinal sie na walidacji <= 0 Ustanawia wzorzec: jak chcesz akcje per-wiersz w child row, dodaj ID do payloadu row_meta
Stylowac chevron rotacja CSS, nie podmiana klas FA w JS Mniej kodu JS, plynniejsza animacja, jeden zrodlowy stan (.products-breakdown-open) Pojedynczy CSS transition zarzadza wizualem; usunieto 2 linie JS
Transakcja PDO + guard inTransaction() zamiast nested-transaction errora Inny kod moze otworzyc transakcje wczesniej (np. w cron/migracji) Bezpieczne uzycie metody w roznych kontekstach wywolania

Deviations from Plan

Summary

Type Count Impact
Auto-fixed 1 Niezbedne - bez tej korekty UI nie dziala (bug: undefined ID)
Scope additions 1 Maly bonus stylowania ikony toggle na prosbe usera, w obrebie tego samego pliku
Deferred 0 Brak

Total impact: Plan zrealizowany zgodnie z zakresem; jedna konieczna korekta payloadu (Task 2) i jedno male rozszerzenie kosmetyczne na zyczenie usera.

Auto-fixed Issues

1. UI Breakdown - brak ID produktu/kampanii/grupy w payloadzie

  • Found during: Task 4 (human-verify)
  • Issue: js-products-breakdown-delete po kliknieciu nie robil nic - parseInt(undefined,10) || 0 dalo 0, a handler ma if (product_id <= 0) return. Powod: breakdown_for_view w controls/class.Products.php:1097 mapowal tylko statystyki + nazwy, bez ID.
  • Fix: Dodano product_id, campaign_id, ad_group_id jako pierwsze pola mappingu (z fallbackami).
  • Files: autoload/controls/class.Products.php
  • Verification: Czesc human-verify - klik kosza po patchu wywoluje dialog z poprawnymi nazwami kampanii/grupy.
  • Commit: TBD (pojedynczy commit fazowy zostanie wykonany w nastepnym etapie)

Deferred Items

Brak.

Issues Encountered

Issue Resolution
Klik w kosz nie wywolywal dialogu (puste dane w entry.product_id itd.) Zlokalizowano: payload breakdown filtrowany w controllerze. Dolozono 3 pola ID i pominieto cache state DataTables (force reload)

Next Phase Readiness

Ready:

  • Wzorzec dla operacji per-wiersz w breakdown ustanowiony (ID w row_meta).
  • Wzorzec transakcyjnego DELETE w factory ustanowiony.
  • Style toggle bardziej spojne wizualnie - mozna wykorzystac wzorzec rotate-on-state w innych collapsible UI.

Concerns:

  • Cron sync moze ponownie zaciagnac dane jezeli produkt nadal aktywny w MC dla danej kampanii/grupy - to jest oczekiwane zachowanie, ale uzytkownik powinien byc tego swiadom.
  • Working tree zawiera zmiany niepowiazane z planem (.vscode/ftp-kr.sync.cache.json, .serena/project.yml) - przy commit fazowym selektywne stage'owanie.

Blockers:

  • Brak.

Phase: 05-products-scope-history-delete, Plan: 01 Completed: 2026-04-29