This commit is contained in:
2026-05-01 11:28:33 +02:00
parent 5a3948fee5
commit 7abb220bc5
10 changed files with 359 additions and 61 deletions

View File

@@ -1,9 +1,9 @@
## Current Position
Phase: 07-xml-feed-cron-refresh — Complete
Plan: 07-01 complete
Phase: 08-products-page-size — Complete
Plan: 08-01 complete
Status: UNIFY complete. Phase complete — ready for next phase.
Last activity: 2026-04-30T07:19:05.331Z
Last activity: 2026-05-01T09:27:11.436Z
## Loop Position
@@ -15,7 +15,7 @@ PLAN ──▶ APPLY ──▶ UNIFY
## Session Continuity
Last session: 2026-04-30
Stopped at: Plan 07-01 complete
Last session: 2026-05-01
Stopped at: Plan 08-01 complete
Next action: paul_workflow('plan') for next phase
Resume file: .paul/phases/07-xml-feed-cron-refresh/07-01-SUMMARY.md
Resume file: .paul/phases/08-products-page-size/08-01-SUMMARY.md

View File

@@ -1,59 +1,25 @@
# STATE
## Current Position
Milestone: (ad-hoc) Products - XML feed import
Phase: 7 of 7 (XML Feed Cron Refresh) - Planning
Plan: 07-01 created, awaiting approval
Status: APPLY complete — 3/3 PASS, ready for UNIFY
Last activity: 2026-04-30T09:20:00+02:00 - Created .paul/phases/07-xml-feed-cron-refresh/07-01-PLAN.md
Phase: 08-products-page-size — Apply complete
Plan: 08-01 executed
Status: APPLY complete — 2/2 PASS, ready for UNIFY
Last activity: 2026-05-01T10:59:46+02:00 — Completed APPLY for .paul/phases/08-products-page-size/08-01-PLAN.md
Progress:
- Milestone: [#########-] 90%
- Phase 7: [----------] 0%
- Milestone: [□□□□□□□□□□] unknown (ROADMAP.md missing)
- Phase 08: [████████░░] 80%
## Loop Position
Current loop state:
```
PLAN --> APPLY --> UNIFY
* o o [Plan created, awaiting approval]
PLAN ──▶ APPLY ──▶ UNIFY
[APPLY complete, awaiting UNIFY]
```
## Session Continuity
Last session: 2026-04-30
Stopped at: Plan 07-01 created
Next action: Review and approve plan, then run $paul-apply 07-01
Resume file: .paul/phases/07-xml-feed-cron-refresh/07-01-PLAN.md
## Historia zrealizowanych planow
- `01-01-PLAN.md` - CL3 -> CL1 w tabeli /products (completed 2026-04-22)
- `02-01-PLAN.md` - custom_label_1 w supplemental feed TSV (completed 2026-04-22)
- `03-01-PLAN.md` - Powrot do widoku "wszystkie kampanie" w /products (completed 2026-04-24)
- `04-01-PLAN.md` - Agregat produktu + rozwijane podwiersze kampania/grupa w /products (completed 2026-04-25)
- `05-01-PLAN.md` - Usuwanie wpisow historii produktu per kampania+grupa z UI breakdown (completed 2026-04-29)
- `06-01-PLAN.md` - XML feed import + rename name/title + xml_feed_url w clients (completed 2026-04-30)
## Decisions
| Date | Decision | Phase | Impact |
|------|----------|-------|--------|
| 2026-04-24 | Usuniecie placeholdera zamiast sentinel `0/all` | 3 | Minimalny blast radius, bez zmian w kontrolerze/factory |
| 2026-04-25 | Bez wybranej grupy: glowny agregat per produkt + rozwijane podwiersze per kampania/grupa | 4 | Czytelniejsza analiza produktu i szybki drill-down |
| 2026-04-25 | Podwiersze tylko readonly, edycja tylko w parent row | 4 | Spojnosc UX i brak konfliktu akcji edycyjnych |
| 2026-04-29 | Usuwanie scope-level: products_aggregate + products_history + products_history_30 (transakcja), bez ruszania `products` ani Google Ads API | 5 | Hard delete lokalny, ograniczony do trojki product+campaign+ad_group |
| 2026-04-29 | UI: nowa kolumna "Akcje" w breakdown z czerwona ikona kosza + dialog $.confirm + ajax.reload(null,false) | 5 | Brak utraty stanu paginacji/filtrow przy odswiezaniu agregatu |
| 2026-04-30 | XML feed: jeden URL w clients.xml_feed_url, mapping po g:id=offer_id, parser XMLReader (streaming), batched manual upsert (200/batch) w transakcjach | 6 | Odporno na feedy z kilkoma tysiacami pozycji, niezalezne pola _gmc dla danych edytowalnych |
| 2026-04-30 | Refaktor schematu products: name->title, title->title_gmc, dodanie description_gmc i price | 6 | Rozdzial danych zrodlowych od edytowalnych |
| 2026-04-30 | Korekta semantyki: title/description = ZRODLOWE (z feedu lub pierwszy fetch GA), title_gmc/description_gmc = EDYTOWALNE (wysylane jako supplemental feed do GMC) | 6 | XmlFeedImporter pisze do title/description, edycja UI/AI pisze do _gmc, SupplementalFeed czyta z _gmc |
| 2026-04-30 | INDEX zamiast UNIQUE na (client_id, offer_id) | 6 | Istniejace dane mialy duplikaty - manual upsert (SELECT IN + UPDATE/INSERT) zamiast ON DUPLICATE KEY UPDATE |
| 2026-04-30 | XML feed ma byc osobnym cronem `/cron/cron_xml_feed_import`, niezaleznym od `cron_universal`, z recznym odswiezeniem w `/clients` | 7 | Czytelny harmonogram, brak dublowania importu z produktami Google Ads, latwiejsza diagnostyka feedu |
## Notes
- PAUL framework dziala tutaj w trybie ad-hoc (bez ROADMAP.md i PROJECT.md).
- Plan 06-01 zostal zamkniety mimo legacy duplikatow w products - przyszle zadanie deduplikacji moze wymusic UNIQUE.
- Backfill historycznych edycji `description` -> `description_gmc` jest deferred (czeka na decyzje uzytkownika).
- Plan 07-01 obejmuje wydzielenie XML feed z `cron_universal`, reczny refresh w `/clients` i diagnostyke `offer_id=2084` dla `pomysloweprezenty.pl`.
Last session: 2026-05-01T10:59:46+02:00
Stopped at: APPLY complete for Plan 08-01
Next action: Run $paul-unify .paul/phases/08-products-page-size/08-01-PLAN.md
Resume file: .paul/phases/08-products-page-size/08-01-PLAN.md

View File

@@ -0,0 +1,12 @@
# 2026-05-01
## Co zrobiono
- [08-products-page-size, Plan 01]
- Task 1: Wlacz wybor liczby produktow w DataTables
- Task 2: Ogranicz i ujednolic length w kontrolerze produktow
## Zmienione pliki
- `templates/products/main_view.php`
- `autoload/controls/class.Products.php`

View File

@@ -0,0 +1,151 @@
---
phase: 08-products-page-size
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- templates/products/main_view.php
- autoload/controls/class.Products.php
autonomous: true
delegation: off
---
<objective>
## Goal
Dodac w tabeli produktow na `/products` wybor liczby produktow wyswietlanych na stronie.
## Purpose
Uzytkownik ma sam decydowac, czy chce przegladac mniej rekordow szybciej, czy wiecej rekordow naraz bez przechodzenia po wielu stronach.
## Output
Zmodyfikowana konfiguracja DataTables dla `#products` oraz bezpieczna obsluga parametru `length` w endpointzie `/products/get_products/`.
</objective>
<context>
<clarifications>
- **Doprecyzowanie** - Brak pytan doprecyzowujacych; wymaganie jest jednoznaczne po analizie kodu.
-> Odpowiedz: opcja wyboru liczby produktow na strone ma dotyczyc glownej tabeli produktow na `/products`.
</clarifications>
## Project Context
@.paul/STATE.md
@.paul/phases/07-xml-feed-cron-refresh/07-01-SUMMARY.md
## Source Files
@templates/products/main_view.php
@autoload/controls/class.Products.php
@autoload/factory/class.Products.php
## Notes
- `.paul/PROJECT.md` i `.paul/ROADMAP.md` nie istnieja w tym projekcie.
- `.paul/codebase/ARCHITECTURE` i `.paul/codebase/DB_SCHEMA` sa puste/szkieletowe.
- `.paul/SPECIAL-FLOWS.md` nie istnieje, wiec sekcja specjalnych skills jest pominieta.
</context>
<acceptance_criteria>
## AC-1: Widoczny wybor liczby rekordow
```gherkin
Given uzytkownik jest na stronie /products
When tabela produktow zostanie zainicjalizowana
Then widzi kontrolke wyboru liczby produktow na strone
And domyslna wartosc pozostaje 25
```
## AC-2: Wybor zmienia limit tabeli
```gherkin
Given uzytkownik wybral klienta i tabela ma dane
When zmieni liczbe produktow na strone na jedna z dozwolonych wartosci
Then DataTables przeladowuje dane z nowa wartoscia length
And endpoint /products/get_products/ zwraca maksymalnie tyle rekordow, ile wybrano
```
## AC-3: Przegladarka pamieta wybor limitu
```gherkin
Given uzytkownik zmienil liczbe produktow na strone
When odswiezy strone /products albo wroci do niej pozniej w tej samej przegladarce
Then tabela startuje z ostatnio wybrana liczba produktow na strone
```
## AC-4: Limit jest bezpiecznie walidowany po stronie serwera
```gherkin
Given request do /products/get_products/ zawiera length spoza dozwolonego zakresu
When kontroler obsluguje request
Then uzywa bezpiecznej wartosci domyslnej albo maksymalnej
And nie przekazuje niekontrolowanego limitu do zapytania SQL
```
</acceptance_criteria>
<tasks>
<task type="auto">
<name>Task 1: Wlacz wybor liczby produktow w DataTables</name>
<files>templates/products/main_view.php</files>
<action>
Zmien konfiguracje `new DataTable( '#products', ... )`:
- ustaw `lengthChange: true`,
- zostaw domyslne `pageLength: 25`, jesli przegladarka nie ma zapisanego wyboru,
- dodaj `lengthMenu` z konserwatywnymi opcjami, np. 10, 25, 50, 100,
- dodaj polski tekst `language.lengthMenu`, np. "Pokaz _MENU_ produktow",
- zapisz wybrana wartosc w `localStorage` i uzyj jej przy ponownej inicjalizacji tabeli,
- nie zmieniaj definicji kolumn, filtracji, sortowania ani logiki reloadow.
</action>
<verify>php -l templates/products/main_view.php</verify>
<done>AC-1, AC-2 i AC-3 sa spelnione: kontrolka jest widoczna, domyslna wartosc to 25, DataTables wysyla wybrane `length`, a przegladarka pamieta wybor.</done>
</task>
<task type="auto">
<name>Task 2: Ogranicz i ujednolic length w kontrolerze produktow</name>
<files>autoload/controls/class.Products.php</files>
<action>
W `Products::get_products()` dodaj lokalna walidacje parametru `length`:
- rzutuj wartosc z `\S::get( 'length' )` na int,
- dopusc tylko ustalone opcje z UI: 10, 25, 50, 100,
- dla braku lub niedozwolonej wartosci ustaw 25,
- zachowaj obecna obsluge `start`, sortowania, filtrow i wywolania `\factory\Products::get_products()`.
Unikaj zmiany zapytan SQL w `factory`, bo `get_products()` juz rzutuje `limit` i `start` na liczby.
</action>
<verify>php -l autoload/controls/class.Products.php</verify>
<done>AC-2 i AC-4 sa spelnione: endpoint honoruje dozwolone limity i ignoruje wartosci spoza listy.</done>
</task>
</tasks>
<boundaries>
## DO NOT CHANGE
- Nie zmieniac schematu bazy ani migracji.
- Nie zmieniac logiki filtrow klient/kampania/grupa/CL1/CL4.
- Nie zmieniac kolumn, bulk delete, edycji produktu, historii produktu ani integracji AI.
- Nie zmieniac `autoload/factory/class.Products.php`, chyba ze podczas APPLY wyjdzie koniecznosc naprawy zwiazana bezposrednio z limitem.
## SCOPE LIMITS
- Zakres obejmuje tylko glowna tabele `#products` na `/products`.
- Nie dodawac globalnego ustawienia uzytkownika w bazie.
- Nie zmieniac paginacji tabeli historii produktu.
</boundaries>
<verification>
Before declaring plan complete:
- [ ] `php -l templates/products/main_view.php`
- [ ] `php -l autoload/controls/class.Products.php`
- [ ] Manualnie na `/products`: kontrolka limitu jest widoczna i domyslnie ustawiona na 25.
- [ ] Manualnie na `/products`: wybor 10/25/50/100 przeladowuje tabele i zachowuje filtry.
- [ ] Manualnie na `/products`: po odswiezeniu strony tabela zachowuje ostatnio wybrany limit.
- [ ] All acceptance criteria met
</verification>
<success_criteria>
- Tabela produktow pozwala wybrac liczbe produktow na strone.
- Domyslnie pozostaje 25 produktow na strone.
- Przegladarka pamieta ostatnio wybrany limit tabeli produktow.
- Backend akceptuje tylko dozwolone limity.
- Brak nowych bledow PHP lint w modyfikowanych plikach.
</success_criteria>
<output>
After completion, create `.paul/phases/08-products-page-size/08-01-SUMMARY.md`
</output>

View File

@@ -0,0 +1,37 @@
---
phase: 08-products-page-size
plan: 01
completed: 2026-05-01T09:27:11.436Z
---
# Phase 08-01 Summary
****
## Acceptance Criteria Results
| Criterion | Status |
|-----------|--------|
| Task 1: Wlacz wybor liczby produktow w DataTables | Pass — Dodano wybor 10/25/50/100, domyslnie 25 z localStorage, zapis przez length.dt. Finalny uklad zrealizowany oficjalnym layout DataTables 2: info po lewej, paging + pageLength po prawej. Style w layout/style.scss i skompilowane do layout/style.css. Uzytkownik potwierdzil UAT: 'Teraz jest ok'. |
| Task 2: Ogranicz i ujednolic length w kontrolerze produktow | Pass — Kontroler /products/get_products/ akceptuje tylko 10/25/50/100, fallback 25. php -l autoload/controls/class.Products.php OK. |
## Accomplishments
- Task 1: Wlacz wybor liczby produktow w DataTables: Dodano wybor 10/25/50/100, domyslnie 25 z localStorage, zapis przez length.dt. Finalny uklad zrealizowany oficjalnym layout DataTables 2: info po lewej, paging + pageLength po prawej. Style w layout/style.scss i skompilowane do layout/style.css. Uzytkownik potwierdzil UAT: 'Teraz jest ok'.
- Task 2: Ogranicz i ujednolic length w kontrolerze produktow: Kontroler /products/get_products/ akceptuje tylko 10/25/50/100, fallback 25. php -l autoload/controls/class.Products.php OK.
## Files Modified
- `templates/products/main_view.php`
- `autoload/controls/class.Products.php`
- `layout/style.scss`
- `layout/style.css`
- `layout/style.css.map`
## Deviations
Plan poczatkowo zakladal tylko templates/products/main_view.php i autoload/controls/class.Products.php. W trakcie UAT dodano layout/style.scss oraz skompilowane layout/style.css i layout/style.css.map, bo wymaganie wygladu i pozycji kontrolki wymagalo stylowania. Finalnie usunieto obejscia DOM i zastosowano oficjalny layout DataTables 2.
---
*Phase: 08-products-page-size, Plan: 01*
*Completed: 2026-05-01*