Files
shopPRO/.paul/ROADMAP.md
Jacek Pyziak 073069c303 fix: dziala aktualizacja systemu i Wyczysc cache na /admin/update/main_view/ (v0.353)
Zdalny changelog z shoppro.project-dc.pl/updates/changelog.php zwracal
niezbalansowany HTML (niezamkniety <script>/<style>/<textarea>/<!--),
ktory "polykal" reszte dokumentu - inline-script z handlerami
#confirm/#confirmUpdateAll i footer-script z main-layout.php
(#clear-cache-btn) nigdy nie parsowaly sie jako JS. Klienci nie mogli
aktualizowac shopPRO.

Fix w admin/templates/update/main-view.php:
1. Blok <script> z handlerami przeniesiony PRZED sekcje Changelog -
   handlery podpinaja sie niezaleznie od zdalnego HTML.
2. Sanityzacja zdalnego changeloga: preg_replace usuwa komentarze HTML,
   strip_tags z whitelista (<p><br><b><strong><i><em><u><ul><ol><li>
   <h1>-<h6><span><div><a><pre><code><hr>) wycina tagi strukturalne i
   wykonywalne (<script>, <style>, <iframe>, <textarea>).

Skutek uboczny: footer-script z main-layout.php (Wyczysc cache + globalne
wyszukiwanie + sprawdzanie aktualizacji) dziala teraz na podstronie update.

Po wgraniu na instancje: hard-reload (Ctrl+F5) + restart PHP-FPM /
wyczyszczenie OPcache.

Suita PHPUnit: 846 testow / 2348 assertions OK.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-13 23:10:08 +02:00

11 KiB
Raw Blame History

Roadmap: shopPRO

Overview

shopPRO to autorski silnik sklepu internetowego rozwijany iteracyjnie. Projekt jest już na produkcji (v0.333) — roadmap obejmuje planowane funkcje i usprawnienia kolejnych wersji.

Current Milestone

Feature — Product list custom labels quick edit Status: Complete Phases: 1 of 1 complete

Phases

Phase Name Plans Status Completed
1 Sensitive data logging fix 1 Done 2026-03
2 Path traversal + XSS escaping 1 Done 2026-03 (v0.335)
3 Error handling w krytycznych ścieżkach 1 Done 2026-03 (v0.336)
4 CSRF protection — admin panel forms 1 Applied 2026-03 (v0.337)
5 Order bugs fix — duplicate + COD status 1 Applied 2026-03 (v0.338)

Next Milestone

Tech debt — Integrations refactoring Status: Planning

Phase Name Plans Status Completed
6 IntegrationsRepository split → ApiloRepository 2 Done 2026-03

Hotfix

Phase Name Plans Status Completed
7 Coupon Fatal Error — order placement crash 1 Done 2026-03-15
8 Apilo orders not sending — diagnoza i naprawa 1 Done 2026-03-16
9 Apilo email notification + infinite retry 1 Done 2026-03-19
15 Scontainers edit saves as new record 1 Done 2026-04-18
17 Cart summary transport cost fix 1 Done 2026-04-20
18 Google feed permutation URL fix 1 Done 2026-04-30
19 Frontend meta tags fix (category + product) 1 Done 2026-05-13
20 Category edit mojibake fix (UI labels) 1 Done 2026-05-13
21 Admin update view JS fix (przyciski aktualizacji + cache) 1 Done 2026-05-13

Feature

Phase Name Plans Status Completed
10 Edycja personalizacji produktu w koszyku 1 Done 2026-03-19
11 DataLayer GA4 analytics fix 1 Done 2026-03-25
12 summaryView redirect fix — double order block 1 Done 2026-03-25
13 Basket logging + TTL token fix 1 Done 2026-03-25
14 Custom fields delete bug — usunięcie wszystkich pól 1 Done 2026-04-16
16 Product list custom labels quick edit 1 Done 2026-04-19

Phase Details

Phase 4 — CSRF protection

Problem: Brak tokenów CSRF na formularzach panelu admina. State-changing POST endpointy (create/update/delete) są potencjalnie podatne na ataki CSRF.

Scope: Dodanie CSRF tokenów do formularzy i walidacji w panelu administracyjnym.

Reference: .paul/codebase/concerns.md — MEDIUM — Missing CSRF tokens

Phase 6 — IntegrationsRepository split

Problem: IntegrationsRepository ma 875 linii — miesza logikę generyczną (settings, logi, product linking) z logiką specyficzną dla Apilo (~650 linii). Narusza zasadę jednej odpowiedzialności.

Scope:

  • Plan 06-01: Utwórz ApiloRepository z metodami apilo* (non-breaking)
  • Plan 06-02: Zmigruj konsumentów (IntegrationsController, ShopProductController, OrderAdminService, cron.php), usuń apilo* z IntegrationsRepository

Phase 5 — Order bugs fix

Problem 1: Zduplikowane zamówienia — klient widzi błąd i klika złóż zamówienie ponownie. Pierwsze zamówienie trafiło do bazy mimo błędu. Powrót do /podsumowanie regeneruje token i pozwala złożyć drugie zamówienie.

Problem 2: Zamówienia COD (płatność przy odbiorze) dostają status "Zamówienie złożone" zamiast "Przyjęte do realizacji". Kod sprawdza hardkodowane payment_id == 3, które jest inne w tej instancji sklepu.

Scope: Guard w summaryView(), try-catch w basketSave(), kolumna is_cod w pp_shop_payment_methods, użycie flagi zamiast hardkodowanego ID.


Roadmap created: 2026-03-12

Phase 11 — DataLayer GA4 analytics fix

Problem: Eventy dataLayer ecommerce (purchase, begin_checkout, view_item, add_to_cart) używają starego formatu UA (id/name zamiast item_id/item_name), brak currency w view_item, price:0 w purchase, brak eventu view_cart. Remarketing dynamiczny i konwersje GA4 nie działają poprawnie.

Scope: Poprawka 4 istniejących eventów do formatu GA4 + dodanie nowego eventu view_cart na stronie koszyka.

Reference: poprawki_datalayer_projectpro.md — audyt analityki z pomysloweprezenty.pl

Phase 12 — summaryView redirect fix

Problem: Po złożeniu pierwszego zamówienia, guard w summaryView() sprawdzał sesyjny order-submit-last-order-id i redirectował na stronę starego zamówienia. Blokował dostęp do /koszyk-podsumowanie dla kolejnych zamówień. Poprawka z instancji klienta (change.md) do wdrożenia globalnie.

Scope: Usunięcie bloku redirect z summaryView() w ShopBasketController.php. Double-submit protection w basketSave() pozostaje bez zmian.

Phase 13 — Basket logging + TTL token fix

Problem: Brak logowania w basketSave() uniemożliwia diagnozę błędów zamówień. Token zamówienia jednorazowy — nadpisywany przy każdym wejściu na podsumowanie, co powoduje że druga karta, "wstecz" lub odświeżenie unieważnia formularz.

Scope: Dodanie metody logOrder() z 4 punktami logowania, zmiana tokena z jednorazowego na TTL 30 min, redirect przy błędzie tokena na /koszyk-podsumowanie zamiast /koszyk, nowy double-submit guard.

Phase 14 — Custom fields delete bug

Problem: Usunięcie WSZYSTKICH dodatkowych pól z produktu nie działa. jQuery .serialize() nie wysyła klucza custom_field_name[] gdy nie ma żadnych pól → array_key_exists('custom_field_name', $d) w ProductRepository zwraca false → saveCustomFields() nigdy nie jest wywoływany → pola pozostają w bazie.

Scope: Dodanie hidden markera custom_field_name_present w szablonie JS + zmiana warunku w ProductRepository na sprawdzanie tego markera. Test jednostkowy.

Phase 15 - Scontainers edit saves as new record

Problem: Edycja kontenera statycznego (/admin/scontainers/edit/id={id}) zapisuje rekord jako nowy wpis zamiast aktualizacji. W praktyce podczas zapisu gubi się id i repository wykonuje insert.

Scope: Poprawić przekazywanie id w nowym flow formularza ScontainersController + dodać test regresyjny dla edycji, bez zmian globalnych w innych kontrolerach.

Phase 16 - Product list custom labels quick edit

Problem: Na liscie produktow brakuje szybkiego trybu uzupelniania custom_label_0..4. Administrator musi wchodzic do edycji produktu, co spowalnia uzupelnianie danych Google XML.

Scope: Dodac przycisk "Pokaz etykiety niestandardowe" obok "Dodaj produkt", zapisywac jego stan w sesji, pokazac 5 pol custom label pod nazwa produktu, zapisac wartosci do bazy i zapewnic podpowiedzi z juz istniejacych wartosci.

Phase 17 - Cart summary transport cost fix

Problem: Na /koszyk-podsumowanie kazdy transport z flaga delivery_free = 1 pokazywany jest za 0,00 zl, niezaleznie od tego czy koszyk osiagnal prog darmowej dostawy settings.free_delivery. Szablon summary-view.php sprawdza tylko flage, nie wartosc koszyka. Suma koncowa zamowienia jest zaniżona.

Scope: Przekazac z ShopBasketController::summaryView() do szablonu wyliczony transport_cost_effective i flage free_delivery_applies uwzgledniajaca prog. Zaktualizowac summary-view.php aby uzywal tych kluczy zamiast surowej flagi delivery_free. Test jednostkowy dla logiki wyliczenia.

Phase 18 — Google feed permutation URL fix

Problem: URL produktu z permutacją atrybutów w feedzie Google miał format /slug/20-170/21-175 (slash między parami). Wzorzec routingu pp_routes używa [0-9-]+, który nie obejmuje /, więc URL nie matchuje żadnej trasy i index.php ładuje stronę główną. Klienci z GMC trafiają na home zamiast na produkt z wybraną kombinacją.

Scope: Zmienić separator z / na _ w generatorze feedu (ProductRepository::appendCombinationToXml), rozszerzyć regex routingu o _ (Helpers), dodać konwersję _| w warstwie front (LayoutEngine), preselekcja wartości atrybutu w partialu na podstawie permutation_hash z URL. Plus unit testy regex + generator linku.

Phase 19 — Frontend meta tags fix

Problem: Strony kategorii (np. /sen-i-otulenie) i strony produktów (np. /kocyk-niemowlaka-szczeniak-z-balonikiem-fuksja) renderują <title> strony głównej oraz literalne wartości content="keywords"/content="description" zamiast właściwych metatagów SEO z bazy. Niepoprawne meta blokują indeksację Google i Merchant Center.

Scope: Diagnostyka (pp_routes + meta w DB + sesyjny $page), checkpoint:decision z 4 opcjami fixu (routes/engine/data/session), implementacja wybranej opcji w LayoutEngine.php lub index.php, test jednostkowy, human-verify na 3 URL-ach.


Phase 20 — Category edit mojibake fix

Problem: Etykiety formularza edycji kategorii (/admin/shop_category/category_edit/id=X) pokazują double-encoded UTF-8 mojibake: TreĹć zamiast "Treść", JÄ™zyk domyĹlny zamiast "Język domyślny", Sortowanie produktĂłw zamiast "Sortowanie produktów" itp.

Root cause: Plik admin/templates/shop-category/category-edit.php został kiedyś zapisany z UTF-8 zinterpretowanym jako Windows-1252 i ponownie zakodowanym do UTF-8. 9 wystąpień. To JEDYNY taki plik w całym repo — grep Ä[\x{84}-\x{99}]|Ĺ|Ăł po całym admin/templates/, templates/, autoload/ nie wskazuje innych dotknietych plików.

Scope: Podmienić 9 hardcoded labelek na poprawne polskie znaki (Treść, Język domyślny, Tytuł, rozwinięcie, Sortowanie produktów, Wyświetlić podkategorie, Blokuj indeksację). Brak zmian w logice/HTML structure, plik zostaje UTF-8 bez BOM. Human-verify w panelu admina.

Phase 21 — Admin update view JS fix

Problem: Na /admin/update/main_view/ nie działają przyciski "Aktualizuj do wyższej wersji", "Aktualizuj do najwyższej wersji" oraz globalny "Wyczyść cache" z headera admina. Klient nie może zaktualizować systemu. Brak błędu JS w konsoli — kliknięcie tylko dopisuje # do URL.

Root cause: admin/templates/update/main-view.php pobiera zdalny changelog przez file_get_contents z shoppro.project-dc.pl/updates/changelog.php. Odpowiedź zawiera niezbalansowany HTML (niezamknięty <script>, <!--, <style> lub <textarea>), który „połyka" pozostałą część dokumentu jako tekst — inline-script z handlerami i footer-script z main-layout.php nigdy się nie parsują.

Scope: (1) Przenieść blok <script> z handlerami przyciskami PRZED sekcję Changelog. (2) Sanityzować zdalny changelog: preg_replace usuwa komentarze HTML, strip_tags z białą listą tagów formatujących. Jeden plik: admin/templates/update/main-view.php. Human-verify w panelu admina.


Last updated: 2026-05-13 (Phase 21 complete)