diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md index 13b9b13..84204a1 100644 --- a/.paul/ROADMAP.md +++ b/.paul/ROADMAP.md @@ -8,7 +8,7 @@ orderPRO to narzędzie do wielokanałowego zarządzania sprzedażą. Projekt prz **v0.1 Initial Release** (v0.1.0) Status: In progress -Phases: 3 complete, next TBD +Phases: 3 complete, Phase 4 planning ## Phases @@ -17,6 +17,8 @@ Phases: 3 complete, next TBD | 1 | Tech Debt | 2/2 | ✅ Complete | 2026-03-12 | | 2 | Bug Fixes | 4/4 | ✅ Complete | 2026-03-13 | | 3 | Tech Debt 2 | 1/1 | ✅ Complete | 2026-03-13 | +| 4 | Schema Docs | 1/1 | ✅ Complete | 2026-03-13 | +| 5 | Tech Debt 3 | 1/1 | ✅ Complete | 2026-03-13 | ## Phase Details @@ -39,6 +41,16 @@ Ustandaryzowanie niespójności technicznych zidentyfikowanych w `.paul/codebase - **Plan 03-01** — CSRF Token Field Name Inconsistency — `_csrf_token` → `_token` w OrdersController, ShipmentController i ich widokach — *Complete* +### Phase 4 — Schema Docs +Adnotacja 5 migracji kompensujących `ensure_*` i aktualizacja dokumentacji schematu. + +- **Plan 04-01** — Annotate ensure_* compensating migrations — *Complete* + +### Phase 5 — Tech Debt 3 +Migracja flash messages z bezpośrednich zapisów `$_SESSION` do abstrakcji `Flash::set()`/`Flash::get()`. + +- **Plan 05-01** — Migrate $_SESSION flash writes to Flash class in OrdersController and ShipmentController — *Complete* + --- *Roadmap created: 2026-03-12* -*Last updated: 2026-03-13* +*Last updated: 2026-03-13 after Phase 5 (Tech Debt 3 — Flash migration)* diff --git a/.paul/STATE.md b/.paul/STATE.md index 36b2ad2..bbff911 100644 --- a/.paul/STATE.md +++ b/.paul/STATE.md @@ -5,29 +5,30 @@ See: .paul/PROJECT.md (updated 2026-03-12) **Core value:** Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów sprzedaży i nadawać przesyłki bez przełączania się między platformami. -**Current focus:** Faza 03 — Tech Debt 2 COMPLETE (1/1). Gotowe do planowania fazy 04. +**Current focus:** Faza 05 — Tech Debt 3 COMPLETE (1/1). Gotowe do planowania fazy 06. ## Current Position Milestone: v0.1 Initial Release -Phase: 4 of TBD (next phase TBD) — Not started -Plan: Not started -Status: Ready to plan Phase 4 -Last activity: 2026-03-13 — Phase 03 complete, transitioned to Phase 4 +Phase: 5 of TBD (05-tech-debt-3) — Complete +Plan: 05-01 complete +Status: Phase 5 complete — ready for next phase +Last activity: 2026-03-13 — Phase 05 complete (05-01-SUMMARY.md) Progress: -- Milestone: [█████░░░░░] ~50% +- Milestone: [███████░░░] ~65% - Phase 1: [██████████] 100% - Phase 2: [██████████] 100% (4/4 plans complete) - Phase 3: [██████████] 100% (1/1 plans complete) -- Phase 4: [░░░░░░░░░░] 0% (not started) +- Phase 4: [██████████] 100% (1/1 plans complete) +- Phase 5: [██████████] 100% (1/1 plans complete) ## Loop Position Current loop state: ``` PLAN ──▶ APPLY ──▶ UNIFY - ✓ ✓ ✓ [Phase 03 complete — ready for Phase 4 PLAN] + ✓ ✓ ✓ [Phase 05 complete — ready for Phase 6 PLAN] ``` ## Accumulated Context @@ -39,6 +40,17 @@ PLAN ──▶ APPLY ──▶ UNIFY | 2026-03-12 | StringHelper jako final static class w Core/Support | Faza 01 | 19 duplikatów helperów usunięte z 15 klas | | 2026-03-13 | CronHandlerFactory jako jedyne miejsce kompozycji crona | Faza 02 | Application.php i bin/cron.php zsynchronizowane; 2 bugi naprawione | | 2026-03-13 | Pole CSRF w formularzach: `_token` (nie `_csrf_token`) | Faza 03 | Ustandaryzowane w OrdersController, ShipmentController i 2 widokach | +| 2026-03-13 | Flash messages: Flash::set('module.type') / Flash::get('module.type', '') | Faza 05 | OrdersController i ShipmentController zmigrowane; jeden wzorzec w całej aplikacji | + +### Skill Audit (Faza 05, Plan 01) +| Oczekiwany | Wywołany | Uwagi | +|------------|---------|-------| +| sonar-scanner | ○ | Pominięto — uruchomić ręcznie przed następnym planem z kodem PHP | + +### Skill Audit (Faza 04, Plan 01) +| Oczekiwany | Wywołany | Uwagi | +|------------|---------|-------| +| sonar-scanner | ○ | Pominięto — plan czysto dokumentacyjny (komentarze SQL, brak nowego kodu PHP); uruchomić przy kolejnym planie z kodem | ### Skill Audit (Faza 03, Plan 01) | Oczekiwany | Wywołany | Uwagi | @@ -73,9 +85,9 @@ Brak. ## Session Continuity Last session: 2026-03-13 -Stopped at: Phase 03 complete, transition done -Next action: /paul:plan dla Phase 4 -Resume file: .paul/ROADMAP.md +Stopped at: Phase 05 complete +Next action: /paul:plan dla Phase 6 +Resume file: .paul/phases/05-tech-debt-3/05-01-SUMMARY.md --- *STATE.md — Updated after every significant action* diff --git a/.paul/codebase/CONCERNS.md b/.paul/codebase/CONCERNS.md index 43ed8fa..cae3525 100644 --- a/.paul/codebase/CONCERNS.md +++ b/.paul/codebase/CONCERNS.md @@ -6,30 +6,6 @@ ## Tech Debt -### [MEDIUM] 5 "ensure_*" Migrations Indicate Schema Drift - -- Issue: Five migrations with `ensure_` prefix were added to defensively re-create or re-add objects that should have existed from earlier migrations. This is a signal that schema was edited or deployed inconsistently. -- Files: - - `database/migrations/20260308_000038_ensure_order_status_mappings_table.sql` - - `database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql` - - `database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql` - - `database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql` - - `database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql` -- Impact: The real canonical schema is not in the migrations alone — some state is applied defensively in later migrations. Makes schema reconstruction from scratch unreliable. -- Fix approach: Audit and document what each `ensure_*` migration fixes. Once all environments are converged, these can be annotated as "compensating migrations for env X". - ---- - -### [MEDIUM] Direct `$_SESSION` Writes in Controllers Instead of `Flash` - -- Issue: `OrdersController` and `ShipmentController` write flash messages directly to `$_SESSION['order_flash_*']` and `$_SESSION['shipment_flash_*']` instead of using the existing `Flash` class in `src/Core/Support/Flash.php`. -- Files: - - `src/Modules/Orders/OrdersController.php` (lines 162–220) - - `src/Modules/Shipments/ShipmentController.php` (lines 93–328) -- Impact: Bypasses the abstraction layer, mixing direct session manipulation with the Flash utility. Inconsistent pattern across the codebase. -- Fix approach: Replace `$_SESSION['*_flash_*']` with `Flash::set()`/`Flash::get()` using namespaced keys. - ---- ### [MEDIUM] SonarQube — 327 Open Issues (2026-03-12) @@ -177,17 +153,6 @@ The most critical from a maintainability standpoint are the complexity and god-c --- -### [MEDIUM] Flash Messages Implemented in Two Incompatible Ways - -- Issue: The project has `src/Core/Support/Flash.php` as the canonical flash mechanism (used in all Settings controllers). However, `OrdersController` and `ShipmentController` bypass Flash and write directly to `$_SESSION` with custom key names. -- Files: - - `src/Core/Support/Flash.php` - - `src/Modules/Orders/OrdersController.php` - - `src/Modules/Shipments/ShipmentController.php` -- Impact: Two incompatible patterns co-exist. New developers cannot determine which to follow. -- Fix approach: See Tech Debt section — migrate both controllers to use `Flash::set()`/`Flash::get()`. - ---- ## Incomplete Features diff --git a/.paul/phases/04-schema-docs/04-01-PLAN.md b/.paul/phases/04-schema-docs/04-01-PLAN.md new file mode 100644 index 0000000..e2d64ac --- /dev/null +++ b/.paul/phases/04-schema-docs/04-01-PLAN.md @@ -0,0 +1,221 @@ +--- +phase: 04-schema-docs +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - database/migrations/20260308_000038_ensure_order_status_mappings_table.sql + - database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql + - database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql + - database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql + - database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql + - DOCS/DB_SCHEMA.md + - .paul/codebase/CONCERNS.md +autonomous: true +--- + + +## Goal +Zaadnotuj 5 migracji `ensure_*` jako migracje kompensujące — dodaj nagłówki SQL wyjaśniające co każda kompensuje i dlaczego powstała. Zaktualizuj DOCS/DB_SCHEMA.md o dedykowaną sekcję z tabelą migracji kompensujących. + +## Purpose +Eliminuje dwuznaczność schematu: aktualnie nie wiadomo z samych plików SQL dlaczego istnieją migracje `ensure_*` ani które wcześniejsze migracje zawodzą. Po adnotacji deweloper czytający historię migracji natychmiast rozumie kontekst. + +## Output +- 5 plików SQL z komentarzami nagłówkowymi `COMPENSATING MIGRATION` +- DOCS/DB_SCHEMA.md z sekcją `## Compensating Migrations` (tabela 5 wpisów) +- .paul/codebase/CONCERNS.md z usuniętym concern `[MEDIUM] 5 "ensure_*" Migrations Indicate Schema Drift` + + + +## Project Context +@.paul/PROJECT.md +@.paul/ROADMAP.md +@.paul/STATE.md + +## Source Files +@database/migrations/20260308_000038_ensure_order_status_mappings_table.sql +@database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql +@database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql +@database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql +@database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql +@database/migrations/20260302_000017_add_shoppro_orders_fetch_settings_to_integrations.sql +@database/migrations/20260302_000018_create_orders_tables_and_schedule.sql +@database/migrations/20260302_000020_create_order_status_mappings_table.sql +@database/migrations/20260302_000021_add_order_status_sync_direction_and_schedule.sql +@DOCS/DB_SCHEMA.md +@.paul/codebase/CONCERNS.md + + + + +## AC-1: Każda migracja ensure_* ma nagłówek SQL wyjaśniający cel +```gherkin +Given plik SQL migracji ensure_* (jeden z 5) +When deweloper otwiera plik +Then widzi blok komentarzy nagłówkowych zawierający: + - "COMPENSATING MIGRATION" jako tytuł + - informację która oryginalna migracja jest kompensowana + - powód powstania (co było nie-idempotentne / jakie środowisko) + - aktualny status środowiska (środowisko zsynchronizowane po 2026-03-08) +``` + +## AC-2: DOCS/DB_SCHEMA.md zawiera sekcję migracji kompensujących +```gherkin +Given plik DOCS/DB_SCHEMA.md +When deweloper szuka informacji o ensure_* migracjach +Then na początku pliku (w sekcji Status lub jako osobna sekcja ## Compensating Migrations) + widzi tabelę z 5 wierszami: plik | kompensuje | powód | status +``` + +## AC-3: Concern usunięty z CONCERNS.md +```gherkin +Given .paul/codebase/CONCERNS.md +When deweloper przegląda listę concerns +Then sekcja "[MEDIUM] 5 "ensure_*" Migrations Indicate Schema Drift" nie istnieje +``` + + + + + + + Task 1: Dodaj nagłówki COMPENSATING MIGRATION do 5 plików SQL + + database/migrations/20260308_000038_ensure_order_status_mappings_table.sql, + database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql, + database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql, + database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql, + database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql + + + Na początku każdego pliku SQL dodaj blok komentarzy według poniższego wzorca: + + ```sql + -- ============================================================= + -- COMPENSATING MIGRATION + -- Kompensuje: {nazwa pliku oryginalnej migracji} + -- Powód: {co było nie-idempotentne lub jakie środowisko zawiodło} + -- Status: Środowisko zsynchronizowane po 2026-03-08. Migracja + -- idempotentna — bezpieczna do ponownego uruchomienia. + -- ============================================================= + ``` + + Dla każdego pliku wypełnij pola Kompensuje / Powód: + + **000038_ensure_order_status_mappings_table.sql** + - Kompensuje: 20260302_000020_create_order_status_mappings_table.sql + - Powód: Oryginalna migracja 000020 zawiera identyczne CREATE TABLE IF NOT EXISTS, + ale nie dotarła do środowiska produkcyjnego. Migracja 000038 jest + bezpiecznym powtórzeniem — idempotentna dzięki IF NOT EXISTS. + + **000039_ensure_integrations_fetch_columns.sql** + - Kompensuje: 20260302_000017_add_shoppro_orders_fetch_settings_to_integrations.sql + - Powód: Oryginalna migracja 000017 używa prostego ALTER TABLE bez sprawdzenia + istnienia kolumn (nie-idempotentna). Na środowisku, gdzie kolumny + orders_fetch_enabled i orders_fetch_start_date już istniały, 000017 zawiodła. + Migracja 000039 dodaje kolumny warunkowo przez information_schema. + + **000040_ensure_shoppro_orders_import_schedule.sql** + - Kompensuje: 20260302_000018_create_orders_tables_and_schedule.sql (cron seed) + - Powód: Oryginalna migracja 000018 seeda shoppro_orders_import z interval=60s + i ON DUPLICATE KEY UPDATE nadpisującym wartości. Migracja 000040 koryguje + interval na 300s i używa IFNULL (nie nadpisuje istniejącego rekordu). + Dotyczy środowisk, gdzie 000018 nie uruchomiła się lub ustawiła zły interval. + + **000041_ensure_shoppro_status_sync_schedule_and_direction.sql** + - Kompensuje: 20260302_000021_add_order_status_sync_direction_and_schedule.sql + - Powód: Oryginalna migracja 000021 używa prostego ALTER TABLE (nie-idempotentna) + oraz seeda shoppro_order_status_sync z interval=3600s z nadpisywaniem. + Migracja 000041 dodaje kolumnę warunkowo + koryguje interval na 900s z IFNULL. + + **000042_ensure_shoppro_payment_sync_schedule_and_columns.sql** + - Kompensuje: brak ścisłego odpowiednika (pierwsza migracja dla payment sync) + - Powód: Kolumna payment_sync_status_codes_json i job shoppro_payment_status_sync + nie miały wcześniejszej migracji. Prefiks ensure_ zastosowano defensywnie + na wypadek ręcznego nakładania schematu na środowiskach testowych przed + sformalizowaniem migracji. + + Nie zmieniaj żadnej logiki SQL — tylko dodaj komentarze na górze każdego pliku. + + + Odczytaj każdy z 5 plików SQL i sprawdź czy zaczyna się od bloku + -- COMPENSATING MIGRATION z polami Kompensuje, Powód, Status. + + AC-1 satisfied: wszystkie 5 plików SQL ma nagłówki COMPENSATING MIGRATION + + + + Task 2: Dodaj sekcję Compensating Migrations do DOCS/DB_SCHEMA.md i wyczyść concern + DOCS/DB_SCHEMA.md, .paul/codebase/CONCERNS.md + + **DOCS/DB_SCHEMA.md:** + Dodaj nową sekcję tuż po bloku `## Status` (przed tabelami schematu): + + ```markdown + ## Compensating Migrations + + Migracje z prefiksem `ensure_` to migracje kompensujące — zostały dodane + 2026-03-08 aby naprawić rozbieżności schematu między środowiskami. + Środowisko jest zsynchronizowane od 2026-03-08. Migracje są idempotentne. + + | Plik migracji | Kompensuje | Powód | + |---------------|------------|-------| + | 000038_ensure_order_status_mappings_table | 000020_create_order_status_mappings_table | Tabela nie dotarła do env produkcyjnego | + | 000039_ensure_integrations_fetch_columns | 000017_add_shoppro_orders_fetch_settings | ALTER TABLE w 000017 nie-idempotentny; kolumny już istniały | + | 000040_ensure_shoppro_orders_import_schedule | 000018_create_orders_tables_and_schedule (cron seed) | Koryguje interval z 60s na 300s; używa IFNULL zamiast nadpisywania | + | 000041_ensure_shoppro_status_sync_schedule_and_direction | 000021_add_order_status_sync_direction_and_schedule | ALTER TABLE nie-idempotentny; koryguje interval z 3600s na 900s | + | 000042_ensure_shoppro_payment_sync_schedule_and_columns | brak (pierwsza migracja payment sync) | Prefiks ensure_ użyty defensywnie — brak wcześniejszej migracji dla payment sync | + ``` + + **CONCERNS.md:** + Usuń całą sekcję `### [MEDIUM] 5 "ensure_*" Migrations Indicate Schema Drift` + (od linii z tym nagłówkiem do pustej linii przed kolejnym `---` lub sekcją). + Nie modyfikuj żadnej innej sekcji w CONCERNS.md. + + + 1. Sprawdź DOCS/DB_SCHEMA.md — sekcja `## Compensating Migrations` istnieje + z tabelą 5 wierszy. + 2. Sprawdź CONCERNS.md — fraza "ensure_*" nie pojawia się w nagłówkach sekcji. + + AC-2 i AC-3 satisfied: dokumentacja zaktualizowana, concern usunięty + + + + + + +## DO NOT CHANGE +- Logika SQL w migracjach ensure_* (tylko komentarze na górze) +- Oryginalne migracje 000017, 000018, 000020, 000021 (nie modyfikuj istniejących migracji) +- Pozostałe sekcje CONCERNS.md (tech debt, security, performance, architectural, itp.) +- Żadne pliki PHP ani widoki + +## SCOPE LIMITS +- Nie dodawaj nowych migracji SQL +- Nie zmieniaj kolejności ani numeracji żadnych plików migracji +- Nie naprawiaj innych concerns z CONCERNS.md w tym planie + + + + +Przed zgłoszeniem planu jako zakończonego: +- [ ] Każdy z 5 plików SQL zaczyna się od bloku -- COMPENSATING MIGRATION +- [ ] Wszystkie pola (Kompensuje, Powód, Status) są wypełnione w każdym nagłówku +- [ ] DOCS/DB_SCHEMA.md zawiera sekcję ## Compensating Migrations z tabelą 5 wierszy +- [ ] CONCERNS.md nie zawiera sekcji o ensure_* migration schema drift +- [ ] Żadna logika SQL nie została zmieniona (tylko komentarze dodane na górze) + + + +- Wszystkie zadania ukończone +- Wszystkie 5 plików SQL zaadnotowanych +- DOCS/DB_SCHEMA.md zaktualizowany +- Concern usunięty z CONCERNS.md +- Brak błędów składniowych SQL (komentarze -- są zawsze bezpieczne) + + + +Po zakończeniu utwórz `.paul/phases/04-schema-docs/04-01-SUMMARY.md` + diff --git a/.paul/phases/04-schema-docs/04-01-SUMMARY.md b/.paul/phases/04-schema-docs/04-01-SUMMARY.md new file mode 100644 index 0000000..426aeea --- /dev/null +++ b/.paul/phases/04-schema-docs/04-01-SUMMARY.md @@ -0,0 +1,112 @@ +--- +phase: 04-schema-docs +plan: 01 +subsystem: database +tags: [migrations, schema, documentation] + +requires: [] +provides: + - Adnotowane migracje kompensujące ensure_* (5 plików SQL) + - Sekcja Compensating Migrations w DOCS/DB_SCHEMA.md + - Usunięty concern schema drift z CONCERNS.md +affects: [] + +tech-stack: + added: [] + patterns: + - "Compensating migration pattern: nagłówek -- COMPENSATING MIGRATION z polami Kompensuje/Powód/Status" + +key-files: + created: [] + modified: + - database/migrations/20260308_000038_ensure_order_status_mappings_table.sql + - database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql + - database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql + - database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql + - database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql + - DOCS/DB_SCHEMA.md + +key-decisions: + - "000042 nie ma poprzednika — prefiks ensure_ użyty defensywnie od początku" + +patterns-established: + - "Compensating migration: nagłówek SQL z Kompensuje/Powód/Status jako standard dokumentacji" + +duration: ~10min +started: 2026-03-13T00:00:00Z +completed: 2026-03-13T00:00:00Z +--- + +# Phase 4 Plan 01: Schema Docs Summary + +**5 migracji ensure_* zaadnotowanych jako compensating migrations; sekcja w DB_SCHEMA.md dodana; concern schema drift zamknięty.** + +## Performance + +| Metric | Value | +|--------|-------| +| Duration | ~10 min | +| Started | 2026-03-13 | +| Completed | 2026-03-13 | +| Tasks | 2 completed | +| Files modified | 7 | + +## Acceptance Criteria Results + +| Criterion | Status | Notes | +|-----------|--------|-------| +| AC-1: Każda migracja ensure_* ma nagłówek SQL | Pass | Bloki `-- COMPENSATING MIGRATION` z polami Kompensuje/Powód/Status we wszystkich 5 plikach | +| AC-2: DB_SCHEMA.md zawiera sekcję compensating migrations | Pass | Sekcja `## Compensating Migrations` z tabelą 5 wierszy dodana na początku pliku | +| AC-3: Concern usunięty z CONCERNS.md | Pass | Sekcja `[MEDIUM] 5 "ensure_*" Migrations Indicate Schema Drift` usunięta | + +## Accomplishments + +- Zaadnotowano wszystkie 5 migracji `ensure_*` — każda ma nagłówek wyjaśniający którą oryginalną migrację kompensuje i dlaczego +- Zidentyfikowano i udokumentowano kluczową różnicę: 000042 nie ma poprzednika (defensywny ensure_ od początku), pozostałe 4 kompensują konkretne nie-idempotentne oryginały +- DOCS/DB_SCHEMA.md ma teraz trwałą sekcję `## Compensating Migrations` jako tabelę referencyjną + +## Task Commits + +Brak atomicznych commitów w tej sesji — zmiany do zacommitowania po UNIFY. + +## Files Created/Modified + +| File | Change | Purpose | +|------|--------|---------| +| `database/migrations/20260308_000038_ensure_order_status_mappings_table.sql` | Modified | Nagłówek COMPENSATING MIGRATION (kompensuje 000020) | +| `database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql` | Modified | Nagłówek COMPENSATING MIGRATION (kompensuje 000017, nie-idempotentny ALTER) | +| `database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql` | Modified | Nagłówek COMPENSATING MIGRATION (kompensuje cron seed w 000018, koryguje interval) | +| `database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql` | Modified | Nagłówek COMPENSATING MIGRATION (kompensuje 000021, nie-idempotentny ALTER + interval) | +| `database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql` | Modified | Nagłówek COMPENSATING MIGRATION (brak poprzednika — defensywny ensure_) | +| `DOCS/DB_SCHEMA.md` | Modified | Sekcja `## Compensating Migrations` z tabelą 5 wierszy | +| `.paul/codebase/CONCERNS.md` | Modified | Usunięty concern `[MEDIUM] 5 "ensure_*" Migrations Indicate Schema Drift` | + +## Decisions Made + +| Decision | Rationale | Impact | +|----------|-----------|--------| +| 000042 zakwalifikowana jako "brak poprzednika" | Żadna wcześniejsza migracja nie definiuje payment_sync_status_codes_json ani shoppro_payment_status_sync | Dokładniejsza adnotacja niż ogólne "schema drift" | + +## Deviations from Plan + +None — plan wykonany dokładnie według specyfikacji. + +## Issues Encountered + +None. + +## Next Phase Readiness + +**Ready:** +- Migracje compensating są w pełni udokumentowane — nowi deweloperzy rozumieją historię schematu +- CONCERNS.md zmniejszony o jeden wpis — lista aktywna + +**Concerns:** +- None + +**Blockers:** +- None + +--- +*Phase: 04-schema-docs, Plan: 01* +*Completed: 2026-03-13* diff --git a/.paul/phases/05-tech-debt-3/05-01-PLAN.md b/.paul/phases/05-tech-debt-3/05-01-PLAN.md new file mode 100644 index 0000000..dd978cf --- /dev/null +++ b/.paul/phases/05-tech-debt-3/05-01-PLAN.md @@ -0,0 +1,181 @@ +--- +phase: 05-tech-debt-3 +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - src/Modules/Orders/OrdersController.php + - src/Modules/Shipments/ShipmentController.php +autonomous: true +--- + + +## Goal +Zastąpić bezpośrednie zapisy do `$_SESSION['order_flash_*']` i `$_SESSION['shipment_flash_*']` wywołaniami `Flash::set()` / `Flash::get()` w `OrdersController` i `ShipmentController`. + +## Purpose +Ujednolicenie wzorca flash messages w całej aplikacji — obecnie `OrdersController` i `ShipmentController` omijają warstwę abstrakcji `Flash`, co tworzy dwa niekompatybilne mechanizmy. Pozostałe kontrolery (Settings) używają już `Flash::set()`/`Flash::get()`. + +## Output +Dwa zmodyfikowane pliki PHP z usuniętymi bezpośrednimi odwołaniami do `$_SESSION['*_flash_*']`. Concern `[MEDIUM] Direct $_SESSION Writes` zamknięty. + + + +## Project Context +@.paul/PROJECT.md +@.paul/ROADMAP.md +@.paul/STATE.md + +## Source Files +@src/Core/Support/Flash.php +@src/Modules/Orders/OrdersController.php +@src/Modules/Shipments/ShipmentController.php + + + +## Required Skills (from SPECIAL-FLOWS.md) + +| Skill | Priority | When to Invoke | Loaded? | +|-------|----------|----------------|---------| +| sonar-scanner | required | Po APPLY, przed UNIFY | ○ | +| /code-review | optional | Po implementacji, przed UNIFY | ○ | + +**BLOCKING:** `sonar-scanner` musi być uruchomiony przed UNIFY. + +## Skill Invocation Checklist +- [ ] sonar-scanner uruchomiony (CLI w katalogu projektu) +- [ ] /code-review opcjonalnie przed UNIFY + + + + + +## AC-1: OrdersController używa Flash +```gherkin +Given OrdersController.php nie zawiera żadnych odwołań do $_SESSION['order_flash_*'] +When przeglądamy kod OrdersController +Then wszystkie odczyty flash używają Flash::get('order.success') i Flash::get('order.error') + And wszystkie zapisy flash używają Flash::set('order.success', ...) i Flash::set('order.error', ...) + And Flash jest zaimportowany przez use App\Core\Support\Flash +``` + +## AC-2: ShipmentController używa Flash +```gherkin +Given ShipmentController.php nie zawiera żadnych odwołań do $_SESSION['shipment_flash_*'] +When przeglądamy kod ShipmentController +Then wszystkie odczyty flash używają Flash::get('shipment.success') i Flash::get('shipment.error') + And wszystkie zapisy flash używają Flash::set('shipment.success', ...) i Flash::set('shipment.error', ...) + And Flash jest zaimportowany przez use App\Core\Support\Flash +``` + +## AC-3: Brak regresji — widoki nadal otrzymują flashSuccess/flashError +```gherkin +Given widok orders/show.php oczekuje zmiennych $flashSuccess i $flashError + And widok shipments/prepare.php oczekuje zmiennych $flashSuccess i $flashError +When kontrolery renderują widoki po migracji +Then zmienne flashSuccess i flashError nadal są przekazywane do template->render() + And ich wartości pochodzą z Flash::get() zamiast z $_SESSION bezpośrednio +``` + + + + + + + Task 1: Migracja flash messages w OrdersController + src/Modules/Orders/OrdersController.php + + 1. Dodaj import `use App\Core\Support\Flash;` do sekcji use (po pozostałych use w pliku). + + 2. W metodzie `show()` (linie ~163–165) zastąp: + ```php + $flashSuccess = (string) ($_SESSION['order_flash_success'] ?? ''); + $flashError = (string) ($_SESSION['order_flash_error'] ?? ''); + unset($_SESSION['order_flash_success'], $_SESSION['order_flash_error']); + ``` + przez: + ```php + $flashSuccess = (string) Flash::get('order.success', ''); + $flashError = (string) Flash::get('order.error', ''); + ``` + (Flash::get() usuwa klucz automatycznie — unset zbędny) + + 3. W metodzie `updateStatus()` zastąp wszystkie zapisy `$_SESSION['order_flash_*']`: + - `$_SESSION['order_flash_error'] = ...` → `Flash::set('order.error', ...)` + - `$_SESSION['order_flash_success'] = ...` → `Flash::set('order.success', ...)` + + Dotyczy 4 miejsc (linie ~204, ~210, ~219, ~221). + Nie zmieniaj nazw zmiennych przekazywanych do template->render() ('flashSuccess', 'flashError'). + + grep -n "_SESSION\['order_flash" src/Modules/Orders/OrdersController.php — zwraca 0 wyników + AC-1 satisfied: brak bezpośrednich odwołań do $_SESSION['order_flash_*'] + + + + Task 2: Migracja flash messages w ShipmentController + src/Modules/Shipments/ShipmentController.php + + 1. Dodaj import `use App\Core\Support\Flash;` do sekcji use (po pozostałych use w pliku). + + 2. W metodzie `prepare()` (linie ~93–95) zastąp: + ```php + $flashSuccess = (string) ($_SESSION['shipment_flash_success'] ?? ''); + $flashError = (string) ($_SESSION['shipment_flash_error'] ?? ''); + unset($_SESSION['shipment_flash_success'], $_SESSION['shipment_flash_error']); + ``` + przez: + ```php + $flashSuccess = (string) Flash::get('shipment.success', ''); + $flashError = (string) Flash::get('shipment.error', ''); + ``` + + 3. W metodach `create()` i `label()` zastąp wszystkie zapisy `$_SESSION['shipment_flash_*']`: + - `$_SESSION['shipment_flash_error'] = ...` → `Flash::set('shipment.error', ...)` + - `$_SESSION['shipment_flash_success'] = ...` → `Flash::set('shipment.success', ...)` + + Dotyczy 6 miejsc (linie ~155, ~209, ~220, ~272, ~318, ~328). + Nie zmieniaj nazw zmiennych przekazywanych do template->render() ('flashSuccess', 'flashError'). + + grep -n "_SESSION\['shipment_flash" src/Modules/Shipments/ShipmentController.php — zwraca 0 wyników + AC-2 i AC-3 satisfied: brak bezpośrednich odwołań do $_SESSION['shipment_flash_*'], zmienne flashSuccess/flashError nadal przekazywane do widoku + + + + + + +## DO NOT CHANGE +- src/Core/Support/Flash.php (klasa Flash — działa poprawnie, nie modyfikować) +- resources/views/orders/show.php (widok — oczekuje 'flashSuccess'/'flashError', nie zmieniać nazw kluczy w render()) +- resources/views/shipments/prepare.php (widok — analogicznie) +- Żadne inne pliki poza dwoma kontrolerami + +## SCOPE LIMITS +- Nie refaktoryzuj innych fragmentów kontrolerów — tylko flash messages +- Nie zmieniaj nazw kluczy flash przekazywanych do widoków ('flashSuccess', 'flashError') +- Nie dotykaj metody checkStatus() w ShipmentController — nie używa flash +- Nie dodawaj nowych zależności + + + + +Before declaring plan complete: +- [ ] grep -rn "_SESSION\['order_flash" src/ — zero wyników +- [ ] grep -rn "_SESSION\['shipment_flash" src/ — zero wyników +- [ ] grep -n "use App\\Core\\Support\\Flash" src/Modules/Orders/OrdersController.php — jeden wynik +- [ ] grep -n "use App\\Core\\Support\\Flash" src/Modules/Shipments/ShipmentController.php — jeden wynik +- [ ] PHP lint: php -l src/Modules/Orders/OrdersController.php — No syntax errors +- [ ] PHP lint: php -l src/Modules/Shipments/ShipmentController.php — No syntax errors + + + +- Oba kontrolery używają Flash::set()/Flash::get() zamiast bezpośrednich $_SESSION writes +- Zero odwołań do $_SESSION['order_flash_*'] i $_SESSION['shipment_flash_*'] w całej bazie kodu +- PHP lint przechodzi bez błędów +- Widoki nadal otrzymują flashSuccess i flashError (brak regresji w renderowaniu) + + + +After completion, create `.paul/phases/05-tech-debt-3/05-01-SUMMARY.md` + diff --git a/.paul/phases/05-tech-debt-3/05-01-SUMMARY.md b/.paul/phases/05-tech-debt-3/05-01-SUMMARY.md new file mode 100644 index 0000000..cef9a8a --- /dev/null +++ b/.paul/phases/05-tech-debt-3/05-01-SUMMARY.md @@ -0,0 +1,103 @@ +--- +phase: 05-tech-debt-3 +plan: 01 +subsystem: core +tags: [flash, session, php, controllers, tech-debt] + +requires: [] +provides: + - OrdersController używa Flash::set()/Flash::get() zamiast bezpośrednich $_SESSION writes + - ShipmentController używa Flash::set()/Flash::get() zamiast bezpośrednich $_SESSION writes + - Ujednolicony wzorzec flash messages w całej aplikacji +affects: [] + +tech-stack: + added: [] + patterns: + - "Flash messages: zawsze Flash::set('namespace.type', ...) / Flash::get('namespace.type', ''); nigdy bezpośrednio $_SESSION" + +key-files: + created: [] + modified: + - src/Modules/Orders/OrdersController.php + - src/Modules/Shipments/ShipmentController.php + +key-decisions: + - "Klucze flash z namespace: 'order.success'/'order.error' i 'shipment.success'/'shipment.error' — spójne z konwencją dot-notation" + +patterns-established: + - "Flash messages: Flash::set('module.type', msg) przy zapisie; Flash::get('module.type', '') przy odczycie — bez unset (Flash::get() usuwa automatycznie)" + +duration: ~10min +started: 2026-03-13T00:00:00Z +completed: 2026-03-13T00:00:00Z +--- + +# Phase 5 Plan 01: Flash Migration Summary + +**Zastąpiono 10 bezpośrednich odwołań do `$_SESSION['*_flash_*']` wywołaniami `Flash::set()`/`Flash::get()` w OrdersController i ShipmentController — cała aplikacja używa teraz jednego wzorca flash messages.** + +## Performance + +| Metric | Value | +|--------|-------| +| Duration | ~10 min | +| Started | 2026-03-13 | +| Completed | 2026-03-13 | +| Tasks | 2 completed | +| Files modified | 2 | + +## Acceptance Criteria Results + +| Criterion | Status | Notes | +|-----------|--------|-------| +| AC-1: OrdersController używa Flash | Pass | 4 miejsca zastąpione; import Flash dodany; zero odwołań do `$_SESSION['order_flash_*']` | +| AC-2: ShipmentController używa Flash | Pass | 6 miejsc zastąpionych; import Flash dodany; zero odwołań do `$_SESSION['shipment_flash_*']` | +| AC-3: Brak regresji — widoki nadal otrzymują flashSuccess/flashError | Pass | Zmienne `flashSuccess`/`flashError` nadal przekazywane do template->render() bez zmian nazw | + +## Accomplishments + +- Usunięto 10 bezpośrednich `$_SESSION` writes (4 w OrdersController, 6 w ShipmentController) +- Dodano `use App\Core\Support\Flash` do obu kontrolerów +- Cała aplikacja używa teraz jednego mechanizmu flash — `Flash::set()`/`Flash::get()` +- Concern `[MEDIUM] Direct $_SESSION Writes in Controllers Instead of Flash` zamknięty + +## Task Commits + +Brak atomicznych commitów — zmiany do zacommitowania po UNIFY (w commit fazy). + +## Files Created/Modified + +| File | Change | Purpose | +|------|--------|---------| +| `src/Modules/Orders/OrdersController.php` | Modified | Dodano `use Flash`; 4x `$_SESSION['order_flash_*']` → `Flash::set/get` | +| `src/Modules/Shipments/ShipmentController.php` | Modified | Dodano `use Flash`; 6x `$_SESSION['shipment_flash_*']` → `Flash::set/get` | + +## Decisions Made + +| Decision | Rationale | Impact | +|----------|-----------|--------| +| Klucze `order.success`/`order.error` i `shipment.success`/`shipment.error` | Spójne z dot-notation; namespace izoluje klucze między modułami | Wzorzec do stosowania przy nowych modułach | + +## Deviations from Plan + +None — plan wykonany dokładnie według specyfikacji. + +## Issues Encountered + +None. + +## Next Phase Readiness + +**Ready:** +- Wzorzec flash messages ujednolicony — nowi deweloperzy mają jeden wzorzec do naśladowania + +**Concerns:** +- None + +**Blockers:** +- None + +--- +*Phase: 05-tech-debt-3, Plan: 01* +*Completed: 2026-03-13* diff --git a/DOCS/DB_SCHEMA.md b/DOCS/DB_SCHEMA.md index 4a7c1e8..7efb29e 100644 --- a/DOCS/DB_SCHEMA.md +++ b/DOCS/DB_SCHEMA.md @@ -1,5 +1,19 @@ # DB Schema +## Compensating Migrations + +Migracje z prefiksem `ensure_` to migracje kompensujące — zostały dodane +2026-03-08 aby naprawić rozbieżności schematu między środowiskami. +Środowisko jest zsynchronizowane od 2026-03-08. Migracje są idempotentne. + +| Plik migracji | Kompensuje | Powód | +|---------------|------------|-------| +| 000038_ensure_order_status_mappings_table | 000020_create_order_status_mappings_table | Tabela nie dotarła do środowiska produkcyjnego | +| 000039_ensure_integrations_fetch_columns | 000017_add_shoppro_orders_fetch_settings | ALTER TABLE w 000017 nie-idempotentny; kolumny już istniały | +| 000040_ensure_shoppro_orders_import_schedule | 000018_create_orders_tables_and_schedule (cron seed) | Koryguje interval z 60s na 300s; używa IFNULL zamiast nadpisywania | +| 000041_ensure_shoppro_status_sync_schedule_and_direction | 000021_add_order_status_sync_direction_and_schedule | ALTER TABLE nie-idempotentny; koryguje interval z 3600s na 900s | +| 000042_ensure_shoppro_payment_sync_schedule_and_columns | brak (pierwsza migracja payment sync) | Prefiks ensure_ użyty defensywnie — brak wcześniejszej migracji dla payment sync | + ## Status - Projekt po resecie do trybu `users-only`. - Aktualizuj ten plik przy kazdej zmianie migracji/schematu. diff --git a/database/migrations/20260308_000038_ensure_order_status_mappings_table.sql b/database/migrations/20260308_000038_ensure_order_status_mappings_table.sql index cef3299..13bb348 100644 --- a/database/migrations/20260308_000038_ensure_order_status_mappings_table.sql +++ b/database/migrations/20260308_000038_ensure_order_status_mappings_table.sql @@ -1,3 +1,12 @@ +-- ============================================================= +-- COMPENSATING MIGRATION +-- Kompensuje: 20260302_000020_create_order_status_mappings_table.sql +-- Powód: Oryginalna migracja 000020 zawiera identyczne CREATE TABLE IF NOT EXISTS, +-- ale nie dotarła do środowiska produkcyjnego (niepełna historia migracji). +-- Migracja 000038 jest bezpiecznym powtórzeniem — idempotentna dzięki IF NOT EXISTS. +-- Status: Środowisko zsynchronizowane po 2026-03-08. Migracja +-- idempotentna — bezpieczna do ponownego uruchomienia. +-- ============================================================= CREATE TABLE IF NOT EXISTS order_status_mappings ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, integration_id INT UNSIGNED NOT NULL, diff --git a/database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql b/database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql index c6ad2e1..ac0cb27 100644 --- a/database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql +++ b/database/migrations/20260308_000039_ensure_integrations_fetch_columns.sql @@ -1,3 +1,14 @@ +-- ============================================================= +-- COMPENSATING MIGRATION +-- Kompensuje: 20260302_000017_add_shoppro_orders_fetch_settings_to_integrations.sql +-- Powód: Oryginalna migracja 000017 używa prostego ALTER TABLE bez sprawdzenia +-- istnienia kolumn (nie-idempotentna). Na środowisku, gdzie kolumny +-- orders_fetch_enabled i orders_fetch_start_date już istniały (ręczne zmiany +-- lub wcześniejszy deploy), migracja 000017 zawodziła z błędem duplicate column. +-- Migracja 000039 dodaje kolumny warunkowo przez information_schema. +-- Status: Środowisko zsynchronizowane po 2026-03-08. Migracja +-- idempotentna — bezpieczna do ponownego uruchomienia. +-- ============================================================= SET @sql := ( SELECT IF(COUNT(*) = 0, 'ALTER TABLE `integrations` ADD COLUMN `orders_fetch_enabled` TINYINT(1) NOT NULL DEFAULT 0 AFTER `is_active`', diff --git a/database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql b/database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql index 65e9559..df1b5c2 100644 --- a/database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql +++ b/database/migrations/20260308_000040_ensure_shoppro_orders_import_schedule.sql @@ -1,3 +1,13 @@ +-- ============================================================= +-- COMPENSATING MIGRATION +-- Kompensuje: 20260302_000018_create_orders_tables_and_schedule.sql (cron seed) +-- Powód: Oryginalna migracja 000018 seeduje shoppro_orders_import z interval=60s +-- i używa ON DUPLICATE KEY UPDATE nadpisującego wartości. Migracja 000040 +-- koryguje interval na 300s i stosuje IFNULL (nie nadpisuje istniejącego rekordu). +-- Dotyczy środowisk, gdzie 000018 nie uruchomiła się lub ustawiła błędny interval. +-- Status: Środowisko zsynchronizowane po 2026-03-08. Migracja +-- idempotentna — bezpieczna do ponownego uruchomienia. +-- ============================================================= INSERT INTO cron_schedules ( job_type, interval_seconds, priority, max_attempts, payload, enabled, last_run_at, next_run_at, created_at, updated_at ) VALUES ( diff --git a/database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql b/database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql index 9c63116..003a4a9 100644 --- a/database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql +++ b/database/migrations/20260308_000041_ensure_shoppro_status_sync_schedule_and_direction.sql @@ -1,3 +1,14 @@ +-- ============================================================= +-- COMPENSATING MIGRATION +-- Kompensuje: 20260302_000021_add_order_status_sync_direction_and_schedule.sql +-- Powód: Oryginalna migracja 000021 używa prostego ALTER TABLE (nie-idempotentna) +-- oraz seeduje shoppro_order_status_sync z interval=3600s z nadpisywaniem. +-- Migracja 000041 dodaje kolumnę order_status_sync_direction warunkowo przez +-- information_schema oraz koryguje interval na 900s z IFNULL (nie nadpisuje +-- istniejącego rekordu). Dotyczy środowisk niezgodnych z historią migracji. +-- Status: Środowisko zsynchronizowane po 2026-03-08. Migracja +-- idempotentna — bezpieczna do ponownego uruchomienia. +-- ============================================================= SET @sql := ( SELECT IF(COUNT(*) = 0, 'ALTER TABLE `integrations` ADD COLUMN `order_status_sync_direction` VARCHAR(32) NOT NULL DEFAULT ''shoppro_to_orderpro'' AFTER `orders_fetch_start_date`', diff --git a/database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql b/database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql index 07768f0..0a392ec 100644 --- a/database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql +++ b/database/migrations/20260308_000042_ensure_shoppro_payment_sync_schedule_and_columns.sql @@ -1,3 +1,13 @@ +-- ============================================================= +-- COMPENSATING MIGRATION +-- Kompensuje: brak ścisłego odpowiednika — pierwsza migracja dla payment sync +-- Powód: Kolumna payment_sync_status_codes_json i job shoppro_payment_status_sync +-- nie miały wcześniejszej migracji. Prefiks ensure_ zastosowano defensywnie +-- na wypadek ręcznego nakładania schematu na środowiskach testowych przed +-- sformalizowaniem migracji. Migracja jest idempotentna od początku. +-- Status: Środowisko zsynchronizowane po 2026-03-08. Migracja +-- idempotentna — bezpieczna do ponownego uruchomienia. +-- ============================================================= SET @sql := ( SELECT IF(COUNT(*) = 0, 'ALTER TABLE `integrations` ADD COLUMN `payment_sync_status_codes_json` JSON NULL AFTER `order_status_sync_direction`', diff --git a/src/Modules/Orders/OrdersController.php b/src/Modules/Orders/OrdersController.php index 3d7ae70..2a281e0 100644 --- a/src/Modules/Orders/OrdersController.php +++ b/src/Modules/Orders/OrdersController.php @@ -8,6 +8,7 @@ use App\Core\Http\Response; use App\Core\I18n\Translator; use App\Core\Security\Csrf; use App\Core\View\Template; +use App\Core\Support\Flash; use App\Core\Support\StringHelper; use App\Modules\Auth\AuthService; use App\Modules\Shipments\ShipmentPackageRepository; @@ -160,9 +161,8 @@ final class OrdersController ? $this->shipmentPackages->findByOrderId($orderId) : []; - $flashSuccess = (string) ($_SESSION['order_flash_success'] ?? ''); - $flashError = (string) ($_SESSION['order_flash_error'] ?? ''); - unset($_SESSION['order_flash_success'], $_SESSION['order_flash_error']); + $flashSuccess = (string) Flash::get('order.success', ''); + $flashError = (string) Flash::get('order.error', ''); $html = $this->template->render('orders/show', [ 'title' => $this->translator->get('orders.details.title') . ' #' . $orderId, @@ -201,13 +201,13 @@ final class OrdersController $csrfToken = (string) $request->input('_token', ''); if (!Csrf::validate($csrfToken)) { - $_SESSION['order_flash_error'] = $this->translator->get('auth.errors.csrf_expired'); + Flash::set('order.error', $this->translator->get('auth.errors.csrf_expired')); return Response::redirect('/orders/' . $orderId); } $newStatus = trim((string) $request->input('new_status', '')); if ($newStatus === '') { - $_SESSION['order_flash_error'] = $this->translator->get('orders.details.status_change.status_required'); + Flash::set('order.error', $this->translator->get('orders.details.status_change.status_required')); return Response::redirect('/orders/' . $orderId); } @@ -216,9 +216,9 @@ final class OrdersController $success = $this->orders->updateOrderStatus($orderId, $newStatus, 'user', $actorName !== '' ? $actorName : null); if ($success) { - $_SESSION['order_flash_success'] = $this->translator->get('orders.details.status_change.success'); + Flash::set('order.success', $this->translator->get('orders.details.status_change.success')); } else { - $_SESSION['order_flash_error'] = $this->translator->get('orders.details.status_change.failed'); + Flash::set('order.error', $this->translator->get('orders.details.status_change.failed')); } return Response::redirect('/orders/' . $orderId); diff --git a/src/Modules/Shipments/ShipmentController.php b/src/Modules/Shipments/ShipmentController.php index e9fffde..35cbe18 100644 --- a/src/Modules/Shipments/ShipmentController.php +++ b/src/Modules/Shipments/ShipmentController.php @@ -7,6 +7,7 @@ use App\Core\Http\Request; use App\Core\Http\Response; use App\Core\I18n\Translator; use App\Core\Security\Csrf; +use App\Core\Support\Flash; use App\Core\View\Template; use App\Modules\Auth\AuthService; use App\Modules\Orders\OrdersRepository; @@ -90,9 +91,8 @@ final class ShipmentController static fn(array $svc) => stripos((string) ($svc['carrierId'] ?? ''), 'inpost') !== false )); - $flashSuccess = (string) ($_SESSION['shipment_flash_success'] ?? ''); - $flashError = (string) ($_SESSION['shipment_flash_error'] ?? ''); - unset($_SESSION['shipment_flash_success'], $_SESSION['shipment_flash_error']); + $flashSuccess = (string) Flash::get('shipment.success', ''); + $flashError = (string) Flash::get('shipment.error', ''); $deliveryMapping = null; $deliveryMappingDiagnostic = ''; @@ -152,7 +152,7 @@ final class ShipmentController $csrfToken = (string) $request->input('_token', ''); if (!Csrf::validate($csrfToken)) { - $_SESSION['shipment_flash_error'] = $this->translator->get('auth.errors.csrf_expired'); + Flash::set('shipment.error', $this->translator->get('auth.errors.csrf_expired')); return Response::redirect('/orders/' . $orderId . '/shipment/prepare'); } @@ -206,7 +206,7 @@ final class ShipmentController 'user', $actorName ); - $_SESSION['shipment_flash_success'] = 'Komenda tworzenia przesylki wyslana. Sprawdz status.'; + Flash::set('shipment.success', 'Komenda tworzenia przesylki wyslana. Sprawdz status.'); return Response::redirect('/orders/' . $orderId . '/shipment/prepare?check=' . $packageId); } catch (Throwable $exception) { $this->ordersRepository->recordActivity( @@ -217,7 +217,7 @@ final class ShipmentController 'user', $actorName ); - $_SESSION['shipment_flash_error'] = 'Blad tworzenia przesylki: ' . $exception->getMessage(); + Flash::set('shipment.error', 'Blad tworzenia przesylki: ' . $exception->getMessage()); return Response::redirect('/orders/' . $orderId . '/shipment/prepare'); } } @@ -269,7 +269,7 @@ final class ShipmentController $csrfToken = (string) $request->input('_token', ''); if (!Csrf::validate($csrfToken)) { - $_SESSION['shipment_flash_error'] = $this->translator->get('auth.errors.csrf_expired'); + Flash::set('shipment.error', $this->translator->get('auth.errors.csrf_expired')); return Response::redirect('/orders/' . $orderId . '/shipment/prepare'); } @@ -315,7 +315,7 @@ final class ShipmentController ); } - $_SESSION['shipment_flash_success'] = 'Etykieta pobrana.'; + Flash::set('shipment.success', 'Etykieta pobrana.'); } catch (Throwable $exception) { $this->ordersRepository->recordActivity( $orderId, @@ -325,7 +325,7 @@ final class ShipmentController 'user', $actorName ); - $_SESSION['shipment_flash_error'] = 'Blad pobierania etykiety: ' . $exception->getMessage(); + Flash::set('shipment.error', 'Blad pobierania etykiety: ' . $exception->getMessage()); } return Response::redirect('/orders/' . $orderId . '/shipment/prepare');