feat(141): group integrations hub sections

This commit is contained in:
2026-05-18 10:24:40 +02:00
parent 7fd88038e4
commit ca0b37a86f
13 changed files with 587 additions and 87 deletions

View File

@@ -13,8 +13,8 @@ Sprzedawca moĹĽe obsĹugiwać zamĂłwienia ze wszystkich kanaĹĂłw
| Attribute | Value |
|-----------|-------|
| Version | 3.9.0-dev |
| Status | v3.9 Stabilizacja i splata dlugu technicznego complete - Phase 140 shopPRO Polkurier Delivery Mapping closed |
| Last Updated | 2026-05-18 (Phase 140 unified) |
| Status | v3.10 Integrations UI Polish complete - Phase 141 closed |
| Last Updated | 2026-05-18 (Phase 141 unified) |
## Requirements
@@ -140,6 +140,7 @@ Sprzedawca moĹĽe obsĹugiwać zamĂłwienia ze wszystkich kanaĹĂłw
- [x] Security and Legacy Hardening: test SMTP ma strict TLS by default z lokalnym `SMTP_ALLOW_SELF_SIGNED_DEV`, szablony e-mail/SMS blokuja nieznane placeholdery, raw `$_SESSION` jest izolowany w `Session`, a wskazane widoki uzywaja `$component()` zamiast hard `require` — Phase 138
- [x] Sonar Critical/Major Cleanup: Phase 139 odswiezyla baseline Sonar i zmniejszyla OPEN BLOCKER/CRITICAL/MAJOR z 648 do 495 przez delivery-status/statistics cleanup, typowane wyjatki oraz szeroka migracje alert include/import patterns — Phase 139
- [x] shopPRO Polkurier Delivery Mapping: zakladka `Dostawy` integracji shopPRO pozwala mapowac forme dostawy na Polkurier, laduje uslugi z `PolkurierShipmentService::getDeliveryServices()` i zapisuje `provider='polkurier'` w `carrier_delivery_method_mappings` bez migracji DB — Phase 140
- [x] Integrations Hub Grouped Sections: `/settings/integrations` pokazuje lekkie sekcje dla marketplace, kurierow i pozostalych integracji, bez starego naglowka/opisu wspolnego panelu — Phase 141
- [x] Integracja polkurier.pl (fundament): pojedyncza globalna konfiguracja w `/settings/integrations/polkurier`, szyfrowany Token API + login, karta w hubie integracji obok Apaczki i realny test polaczenia przez `apimetod=test_auth_api` zweryfikowany na zywym koncie operatora; `ShipmentProviderRegistry` netkniety — `PolkurierShipmentService/TrackingService` w kolejnych fazach — Phase 127
- [x] polkurier ShipmentService + TrackingService + UI prepare panel: pelen kontrakt API (createShipment/getLabel/getStatus/cancelOrder/getAvailableCarriers), `PolkurierShipmentService` implementujacy `ShipmentProviderInterface` z normalizacja shipmenttype (lowercase) i splitem ulicy na street/housenumber/flatnumber, `PolkurierTrackingService` mapujacy statusy O/P/A/WP/D/Z/W na znormalizowane, panel "polkurier" w `prepare.php` z dynamiczna lista uslug z `available_carriers`, seed migracja `delivery_status_mappings(provider='polkurier')` z 7 wpisami z PDF v1.11; live test na #114/#115 zakonczony sukcesem po 4 iteracjach (ReferenceError → uppercase shipmenttype → orderno parsing → A4/A6); rozmiar etykiety sterowany w panelu klienta polkurier.pl (Ustawienia konta → Preferencje etykiet), NIE przez API — Phase 128
- [x] Order User Notes module (Phase 129): pelen CRUD notatek autorskich operatora per zamowienie. Reuse `order_notes` przez nowy `note_type='user'` z `user_id` (FK→users SET NULL) + `author_name` (snapshot) + indeks `idx_order_notes_type_order`. `OrderNotesService` z autoryzacja DB-level (`WHERE user_id = :user_id`, rowCount=0 ⇒ 403). Sekcja `#notes` w "Wiadomosci i zalaczniki" w `/orders/{id}` z inline edit form + delete przez `OrderProAlerts.confirm`. Badge `[N]` (indigo neutralny) przy nr zamowienia na `/orders/list` (subquery `user_notes_count` w paginate). Brak admin override (brak systemu rol w aplikacji) — edit/delete tylko dla autora — Phase 129
@@ -322,6 +323,6 @@ Quick Reference:
---
*PROJECT.md — Updated when requirements or context change*
*Last updated: 2026-05-18 after Phase 140 (shopPRO Polkurier Delivery Mapping) closure*
*Last updated: 2026-05-18 after Phase 141 closure*

View File

@@ -6,12 +6,27 @@ orderPRO to narzedzie do wielokanalowego zarzadzania sprzedaza. Projekt przechod
## Current Milestone
v3.9 Stabilizacja i splata dlugu technicznego
v3.10 Integrations UI Polish - Complete
Maly milestone porzadkujacy ekran `/settings/integrations`, aby rosnaca liczba integracji byla latwiejsza do skanowania bez zmiany backendowych kontraktow providerow.
Progress: 1 of 1 phases complete (100%).
| Phase | Name | Plans | Status |
|-------|------|-------|--------|
| 141 | Integrations Hub Grouped Sections | 1/1 | Complete (2026-05-18; manual UI/Sonar follow-up pending) |
### Phase 141: Integrations Hub Grouped Sections
Focus: Podzielic `/settings/integrations` na lekkie sekcje/kafelki: marketplace (Allegro Sandbox, Allegro Production, shopPRO, Erli), kurierzy (InPost, Apaczka, polkurier.pl) i pozostale (Fakturownia, HostedSMS, SMSPLANET), usuwajac niepotrzebny naglowek/opis "Wspolny panel konfiguracji wszystkich providerow."
Plans: 141-01 (complete; `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md`)
## Previous Milestone
v3.9 Stabilizacja i splata dlugu technicznego - Complete
Milestone porzadkujacy zbudowany z `.paul/codebase/todo.md` i `.paul/codebase/concerns.md`: poprawa znanych bugow, weryfikacja stalych ryzyk, domkniecie security/performance oraz ograniczenie dlugu technicznego, ktory utrudnia kolejne wdrozenia.
Rule for every phase/plan: przed implementacja sprawdzic w kodzie i dokumentacji, czy wpis nadal jest aktualny i czy nie zostal juz wdrozony; nastepnie przedstawic krotki plan operatorowi i zapytac o potwierdzenie. Dopiero po akceptacji wolno wprowadzac zmiany i uruchamiac testy. Jezeli wpis jest nieaktualny albo juz zrealizowany, faza/planu ma zamknac go dokumentacyjnie bez niepotrzebnej zmiany kodu.
Progress: 7 of 7 phases complete (100%).
| Phase | Name | Plans | Status |
@@ -59,7 +74,7 @@ Plans: 139-01 (complete; `.paul/phases/139-sonar-critical-major-cleanup/139-01-S
Focus: Dodac Polkurier do zakladki Dostawy w ustawieniach integracji shopPRO, aby formy dostawy z zamowien shopPRO mogly byc mapowane na lokalna usluge Polkurier i pozniej automatycznie preselectowane przy przygotowaniu przesylki.
Plans: 140-01 (complete; `.paul/phases/140-shoppro-polkurier-delivery-mapping/140-01-SUMMARY.md`)
## Previous Milestone
## Earlier Milestone
v3.8 Erli Marketplace Integration - Complete in code
@@ -621,4 +636,4 @@ Archive: `.paul/milestones/v0.1-ROADMAP.md`
---
*Roadmap created: 2026-03-12*
*Last updated: 2026-05-18 - Phase 140 complete; v3.9 milestone complete; obsolete phases 140+ removed*
*Last updated: 2026-05-18 - Phase 141 complete; v3.10 Integrations UI Polish complete*

View File

@@ -5,19 +5,19 @@
See: .paul/PROJECT.md (updated 2026-05-18)
**Core value:** Sprzedawca moze obslugiwac zamowienia ze wszystkich kanalow sprzedazy i nadawac przesylki bez przelaczania sie miedzy platformami.
**Current focus:** v3.9 Stabilizacja i splata dlugu technicznego complete; Phase 140 shopPRO Polkurier Delivery Mapping unified.
**Current focus:** v3.10 Integrations UI Polish complete; Phase 141 Integrations Hub Grouped Sections unified.
## Current Position
Milestone: v3.9 Stabilizacja i splata dlugu technicznego
Phase: 140 of 140 (shopPRO Polkurier Delivery Mapping) - Complete
Plan: 140-01 complete
Milestone: v3.10 Integrations UI Polish
Phase: 141 of 141 (Integrations Hub Grouped Sections) - Complete
Plan: 141-01 complete
Status: Milestone complete, ready for next milestone or release decision
Last activity: 2026-05-18 00:00 - Unified .paul/phases/140-shoppro-polkurier-delivery-mapping/140-01-PLAN.md
Last activity: 2026-05-18 00:00 - Unified .paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md
Progress:
- Milestone v3.9: [##########] 100% (7 of 7 phases complete)
- Phase 140: [##########] 100% (complete)
- Milestone v3.10: [##########] 100% (1 of 1 phases complete)
- Phase 141: [##########] 100% (complete)
## Loop Position
@@ -30,18 +30,18 @@ PLAN -> APPLY -> UNIFY
## Session Continuity
Last session: 2026-05-18 00:00
Stopped at: Phase 140 complete; v3.9 milestone complete
Stopped at: Phase 141 complete; v3.10 milestone complete
Next action: Run $paul-complete-milestone or start next milestone planning
Resume file: .paul/phases/140-shoppro-polkurier-delivery-mapping/140-01-SUMMARY.md
Resume file: .paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md
## Pending parallel work
- None — Phase 118, 121, 122 wszystkie zacommitowane (8f14851, 360eef1).
## Git State
Last commit: HEAD feat(140): shoppro polkurier delivery mapping
Last phase commit: HEAD feat(140): shoppro polkurier delivery mapping
Previous: feat(139): sonar critical major cleanup
Last commit: HEAD feat(141): group integrations hub sections
Last phase commit: HEAD feat(141): group integrations hub sections
Previous: feat(140): shoppro polkurier delivery mapping
Branch: main
### Skill Audit (Phase 139)
@@ -57,6 +57,12 @@ Branch: main
|----------|---------|-------|
| `sonar-scanner` | gap documented | `sonar-project.properties` exists, but `sonar-scanner` is not available in PATH and the Phase 139 `%TEMP%` fallback scanner is not present. |
### Skill Audit (Phase 141)
| Expected | Invoked | Notes |
|----------|---------|-------|
| `sonar-scanner` | gap documented | Attempted after APPLY with `sonar-scanner --version`; CLI is not available in PATH. |
### Skill Audit (Phase 129)
| Expected | Invoked | Notes |
@@ -129,6 +135,7 @@ Branch: main
- Phase 139 is confirmed by operator. Plan 139-01 must run a fresh `sonar-scanner` before code cleanup; stale API-only results are not enough. Scope should fix as many confirmed issues as safely possible, split across multiple plans if needed.
- Phase 139-01 fresh scan found 648 OPEN BLOCKER/CRITICAL/MAJOR issues; final scan after cleanup found 605. Delivery status target files are clean; `OrdersStatisticsRepository` still needs a class split for `php:S1448`.
- Phase 139-02 final scan found 495 OPEN BLOCKER/CRITICAL/MAJOR issues. `php:S4833` dropped to 3 and selected `php:S112` generic exception clusters were replaced with typed exceptions.
- Phase 141 grouped `/settings/integrations` into presentation-only sections: marketplace, couriers and other. Provider row contracts, routes and settings pages remain unchanged.
### Blockers / Concerns
@@ -139,6 +146,7 @@ Branch: main
- Phase 138 APPLY: `vendor/bin/phpunit` is missing, so new unit tests were linted but not run; `sonar-scanner` is unavailable in PATH. PHP lint, targeted `rg` checks and `git diff --check` passed.
- Phase 139 APPLY: local PATH still does not contain `sonar-scanner`, but the official Windows x64 scanner was downloaded to `%TEMP%` and used successfully. `vendor/bin/phpunit` remains unavailable because `vendor/` is missing and Composer is not installed in PATH.
- Phase 140 APPLY: manual UI smoke was not run because local app/DB session was not started; Sonar scan could not run because `sonar-scanner` is unavailable.
- Phase 141 APPLY: manual UI smoke was not run because local app/browser session was not started; Sonar scan could not run because `sonar-scanner` is unavailable.
- Obsolete Phase 140+ debt plans were removed from the active roadmap on 2026-05-18 by operator decision; performance/debt items can be reintroduced later only if still relevant.
### Deferred Issues
@@ -152,6 +160,8 @@ Branch: main
- Phase 139 follow-up: continue with confirmed groups `php:S1142`, `php:S3776`, `php:S1172`, `php:S1192`, `php:S112`, plus Web table/accessibility issues. `php:S4833` is now only 3 core framework require issues.
- Phase 140 follow-up: manual smoke `/settings/integrations/shoppro?tab=delivery` -> wybierz Polkurier -> zapisz -> odswiez -> mapowanie pozostaje; potem przygotuj przesylke shopPRO i potwierdz preselect `provider='polkurier'`.
- Phase 140 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback.
- Phase 141 follow-up: manual smoke `/settings/integrations` -> potwierdz sekcje marketplace/kurierzy/pozostale, osobne wiersze Allegro Sandbox/Production i poprawne linki Ustawienia.
- Phase 141 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback.
- Phase 138 manual smoke: test a real SMTP SSL/STARTTLS mailbox in strict mode; test invalid and valid e-mail/SMS template saves in UI.
- Manualne testy AC-1..AC-7 dla Phase 112 na zywej bazie (XAMPP online).
- Backfill zamowienia #882 - operator robi recznie po wdrozeniu (poza zakresem planu).

View File

@@ -7,6 +7,11 @@
- Zapis mapowan shopPRO obsluguje `provider='polkurier'` oraz zapis service code i nazwy uslugi w `carrier_delivery_method_mappings`.
- Zaktualizowano dokumentacje architektury, techniczny changelog oraz stan PAUL; stare nieaktualne fazy 140+ usunieto z aktywnej roadmapy.
- Gap: manualny smoke UI i SonarQube scan pozostaja do wykonania po uruchomieniu app/DB i przywroceniu `sonar-scanner`.
- [Phase 141, Plan 01] Podzielono `/settings/integrations` na lekkie sekcje marketplace, kurierzy i pozostale.
- Usunieto stary opis huba "Wspolny panel konfiguracji wszystkich providerow." z renderowanego widoku.
- Zachowano osobne wiersze Allegro Sandbox i Allegro Production oraz dotychczasowe linki konfiguracji providerow.
- Dodano kompaktowe style SCSS dla huba integracji i przebudowano `public/assets/css/app.css`.
- Gap: manualny smoke UI i SonarQube scan Phase 141 pozostaja do wykonania po uruchomieniu app/DB i przywroceniu `sonar-scanner`.
## Zmienione pliki
@@ -19,6 +24,12 @@
- `DOCS/ARCHITECTURE.md`
- `DOCS/TECH_CHANGELOG.md`
- `resources/lang/pl.php`
- `resources/scss/app.scss`
- `public/assets/css/app.css`
- `resources/views/settings/integrations.php`
- `resources/views/settings/shoppro.php`
- `routes/web.php`
- `src/Modules/Settings/IntegrationsHubController.php`
- `src/Modules/Settings/ShopproIntegrationsController.php`
- `.paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md`
- `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md`

View File

@@ -0,0 +1,193 @@
---
phase: 141-integrations-hub-grouped-sections
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- src/Modules/Settings/IntegrationsHubController.php
- resources/views/settings/integrations.php
- resources/lang/pl.php
- resources/scss/app.scss
- public/assets/css/app.css
- DOCS/ARCHITECTURE.md
- DOCS/TECH_CHANGELOG.md
autonomous: true
delegation: off
---
<objective>
## Goal
Podzielic `/settings/integrations` na trzy czytelne grupy: marketplace, kurierzy oraz pozostale integracje, bez obecnego naglowka z opisem "Wspolny panel konfiguracji wszystkich providerow."
## Purpose
Hub integracji ma byc szybszy do skanowania. Operator powinien natychmiast widziec, ktore konfiguracje dotycza kanalow sprzedazy, ktore przewoznikow, a ktore narzedzi pomocniczych.
## Output
Zmieniony model danych dla widoku huba integracji, widok renderujacy lekkie sekcje/kafelki grup oraz style SCSS/CSS dla kompaktowego ukladu.
</objective>
<context>
<clarifications>
- **Uklad** - Jak maja wygladac boksy na stronie Integracje?
-> Odpowiedz: Bardziej sekcje niz karty, lub jakies kafelki.
- **Allegro** - Czy Allegro Sandbox i Allegro Production maja zostac jako dwa osobne wiersze w boksie marketplace?
-> Odpowiedz: Moga byc osobno.
</clarifications>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md
@DOCS/ARCHITECTURE.md
@DOCS/DB_SCHEMA.md
## Source Files
@src/Modules/Settings/IntegrationsHubController.php
@resources/views/settings/integrations.php
@resources/lang/pl.php
@resources/scss/app.scss
@package.json
</context>
<skills>
## Required Skills (from SPECIAL-FLOWS.md)
| Skill | Priority | When to Invoke | Loaded? |
|-------|----------|----------------|---------|
| sonar-scanner | required | Po APPLY, przed UNIFY, jezeli CLI jest dostepny | ○ |
| /frontend-design | optional | Przy dopracowaniu ukladu sekcji/kafelkow | ○ |
**BLOCKING:** Required skill `sonar-scanner` should be attempted after implementation. If unavailable in PATH, document the environment gap in SUMMARY/STATE as in prior phases.
</skills>
<acceptance_criteria>
## AC-1: Brak zbednego hero/naglowka
```gherkin
Given operator otwiera /settings/integrations
When strona sie renderuje
Then nie widzi osobnej karty z naglowkiem "Integracje" i opisem "Wspolny panel konfiguracji wszystkich providerow."
And komunikaty flash/error nadal renderuja sie na gorze strony przez komponent alertu
```
## AC-2: Grupa marketplace
```gherkin
Given hub integracji ma dane Allegro, shopPRO i Erli
When operator oglada sekcje "Integracje z marketplace"
Then widzi w niej Allegro Sandbox, Allegro Production, shopPRO i Erli
And oba srodowiska Allegro pozostaja osobnymi pozycjami z linkami konfiguracji
```
## AC-3: Grupa kurierow
```gherkin
Given hub integracji ma dane przewoznikow
When operator oglada sekcje "Integracje z kurierami"
Then widzi w niej InPost, Apaczka i polkurier.pl
And statusy konfiguracji, sekretow, aktywnosci, ostatniego testu i akcje pozostaja dostepne
```
## AC-4: Grupa pozostalych integracji
```gherkin
Given hub integracji ma dane pozostalych providerow
When operator oglada sekcje "Integracje pozostale"
Then widzi w niej Fakturownie, HostedSMS i SMSPLANET
And kazda pozycja ma ten sam zakres informacji i przycisk konfiguracji co przed zmiana
```
## AC-5: Kompaktowy, responsywny uklad
```gherkin
Given operator korzysta z widoku desktop lub mobile
When lista integracji jest dluga albo szerokie kolumny sie nie mieszcza
Then sekcje sa zwarte, czytelne i nie rozpychaja strony poza viewport
And na mobile tabele pozostaja przewijalne poziomo jak dotychczas
```
</acceptance_criteria>
<tasks>
<task type="auto">
<name>Task 1: Zgrupowac dane huba integracji</name>
<files>src/Modules/Settings/IntegrationsHubController.php</files>
<action>
Zmienic `index()` tak, aby zamiast jednej listy `rows` przekazywal do widoku `groups`.
Kazda grupa ma miec klucz, tytul z tlumaczen i liste wierszy:
- marketplace: Allegro Sandbox, Allegro Production, shopPRO, Erli
- couriers: InPost, Apaczka, polkurier.pl
- other: Fakturownia, HostedSMS, SMSPLANET
Zachowac obecne metody `build*Row()` i ich kontrakty wiersza, zeby nie ruszac logiki statusow ani linkow konfiguracji.
</action>
<verify>`C:\xampp\php\php.exe -l src/Modules/Settings/IntegrationsHubController.php`</verify>
<done>AC-2, AC-3 i AC-4 satisfied: widok dostaje kompletne grupy bez utraty pozycji.</done>
</task>
<task type="auto">
<name>Task 2: Przebudowac widok na lekkie sekcje/kafelki</name>
<files>resources/views/settings/integrations.php, resources/lang/pl.php</files>
<action>
Usunac pierwsza karte z `<h2>` i opisem huba. Komunikaty `errorMessage` i `successMessage` zostawic nad lista.
W widoku iterowac po `groups`; kazda grupa ma renderowac lekka sekcje `.integrations-hub-section` z naglowkiem i tabela tych samych kolumn co obecnie.
Zachowac escape przez `$e()`, `$component('components/alert', ...)` dla alertow i obecny pusty stan dla grup bez pozycji.
Dodac tlumaczenia tytulow grup, usuwajac zaleznosc widoku od niepotrzebnego opisu huba.
</action>
<verify>`C:\xampp\php\php.exe -l resources/views/settings/integrations.php`; `rg -n "Wspolny panel konfiguracji wszystkich providerow|integrations_hub.description" resources/views/settings/integrations.php resources/lang/pl.php` should not find an active rendered description dependency</verify>
<done>AC-1, AC-2, AC-3 i AC-4 satisfied: UI renderuje trzy grupy i nie pokazuje starego naglowka/opisu.</done>
</task>
<task type="auto">
<name>Task 3: Dodac kompaktowe style i zbudowac CSS</name>
<files>resources/scss/app.scss, public/assets/css/app.css, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
<action>
Dodac style dla sekcji huba integracji do `resources/scss/app.scss`:
- lekki kontener sekcji zamiast ciezkiej karty w karcie,
- zwarty naglowek sekcji,
- grid/stack z rozsadnymi odstepami,
- zachowanie `.table-wrap` dla poziomego scrolla.
Uruchomic `npm run build:css`, aby odswiezyc `public/assets/css/app.css`.
Zaktualizowac `DOCS/ARCHITECTURE.md` o kontrakt grup huba integracji i `DOCS/TECH_CHANGELOG.md` o zmiane UI bez migracji DB.
</action>
<verify>`npm run build:css`; `git diff --check`; `rg -n "IntegrationsHubController|Phase 141|hub integracji" DOCS/ARCHITECTURE.md DOCS/TECH_CHANGELOG.md`</verify>
<done>AC-5 satisfied: style sa w SCSS, CSS zbudowany, dokumentacja opisuje nowy uklad.</done>
</task>
</tasks>
<boundaries>
## DO NOT CHANGE
- database/migrations/* - zmiana nie wymaga schematu DB.
- Logika zapisu/testowania integracji w dedykowanych kontrolerach providerow.
- Endpointy `/settings/integrations/*` i linki konfiguracji providerow.
- Kontrakty wierszy `build*Row()` poza ewentualnym uporzadkowaniem grupowania.
## SCOPE LIMITS
- Bez dodawania nowych integracji.
- Bez zmiany statusow, sekretow, aktywnosci ani sposobu pobierania `last_test_at`.
- Bez migracji DB i bez zmian w `.env.example`.
- Bez redesignu podstron konkretnych integracji, tylko hub `/settings/integrations`.
</boundaries>
<verification>
Before declaring plan complete:
- [ ] `C:\xampp\php\php.exe -l src/Modules/Settings/IntegrationsHubController.php`
- [ ] `C:\xampp\php\php.exe -l resources/views/settings/integrations.php`
- [ ] `npm run build:css`
- [ ] `git diff --check`
- [ ] `rg` potwierdza trzy grupy i brak starego opisu w renderowanym widoku
- [ ] `sonar-scanner` attempted if available; environment gap documented if unavailable
- [ ] Manual smoke checklist documented: `/settings/integrations` shows marketplace/couriers/other groups and every Configure button still points to the expected URL
</verification>
<success_criteria>
- `/settings/integrations` renderuje trzy sekcje zgodnie z decyzja operatora.
- Allegro Sandbox i Allegro Production sa nadal osobnymi pozycjami.
- Stary naglowek/opis huba nie jest wyswietlany.
- Nie ma zmian DB ani regresji kontraktow providerow.
- Dokumentacja techniczna i changelog sa zaktualizowane.
</success_criteria>
<output>
After completion, create `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md`.
</output>

View File

@@ -0,0 +1,162 @@
---
phase: 141-integrations-hub-grouped-sections
plan: 01
subsystem: settings-ui
tags: [integrations, ui, scss, settings]
requires:
- phase: 140-shoppro-polkurier-delivery-mapping
provides: completed current integration set including Polkurier mapping
provides:
- grouped integrations hub sections
- compact section styling for /settings/integrations
affects: [settings-integrations, future-provider-additions]
tech-stack:
added: []
patterns: [presentation-only hub grouping, SCSS-first UI styling]
key-files:
created:
- .paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md
- .paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md
modified:
- src/Modules/Settings/IntegrationsHubController.php
- resources/views/settings/integrations.php
- resources/lang/pl.php
- resources/scss/app.scss
- public/assets/css/app.css
- DOCS/ARCHITECTURE.md
- DOCS/TECH_CHANGELOG.md
key-decisions:
- "Hub groups are presentation-only; provider row contracts and routes remain unchanged."
- "Allegro Sandbox and Allegro Production remain separate marketplace rows."
patterns-established:
- "IntegrationsHubController passes grouped view data as `groups` with `key`, `title`, and `rows`."
duration: ~20min
started: 2026-05-18T00:00:00+02:00
completed: 2026-05-18T00:00:00+02:00
---
# Phase 141 Plan 01: Integrations Hub Grouped Sections Summary
`/settings/integrations` now renders compact grouped sections for marketplace, courier, and remaining integrations without the old generic hub description.
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~20min |
| Started | 2026-05-18 |
| Completed | 2026-05-18 |
| Tasks | 3 completed |
| Files modified | 12 |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Brak zbednego hero/naglowka | Pass | The first card with "Integracje" + "Wspolny panel konfiguracji wszystkich providerow." was removed; alerts remain above the grouped list. |
| AC-2: Grupa marketplace | Pass | Marketplace group contains Allegro Sandbox, Allegro Production, shopPRO and Erli. |
| AC-3: Grupa kurierow | Pass | Courier group contains InPost, Apaczka and polkurier.pl with the same status/action columns. |
| AC-4: Grupa pozostalych integracji | Pass | Other group contains Fakturownia, HostedSMS and SMSPLANET with unchanged configure links. |
| AC-5: Kompaktowy, responsywny uklad | Pass | Added lightweight section styles in SCSS and rebuilt compressed CSS; `.table-wrap` horizontal scrolling remains in place. |
## Accomplishments
- Replaced the flat integrations hub table model with grouped view data in `IntegrationsHubController`.
- Rebuilt `resources/views/settings/integrations.php` to render lightweight sections rather than a heavy card/header.
- Added translation keys for the three group titles.
- Added compact SCSS for `.integrations-hub-section` and rebuilt `public/assets/css/app.css`.
- Updated architecture documentation and technical changelog.
## Task Commits
The phase was committed as one transition commit during UNIFY.
| Task | Commit | Type | Description |
|------|--------|------|-------------|
| Task 1: Zgrupowac dane huba integracji | `HEAD` | feat | Controller passes `groups` and preserves row contracts. |
| Task 2: Przebudowac widok na lekkie sekcje/kafelki | `HEAD` | feat | View renders three grouped sections and removes old description. |
| Task 3: Dodac kompaktowe style i zbudowac CSS | `HEAD` | style/docs | SCSS/CSS and docs updated. |
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `.paul/PROJECT.md` | Modified | Moved Phase 141 from active plan to shipped requirement during transition. |
| `.paul/ROADMAP.md` | Modified | Marked v3.10 / Phase 141 complete. |
| `.paul/STATE.md` | Modified | Closed PLAN/APPLY/UNIFY loop and documented Sonar gap. |
| `.paul/changelog/2026-05-18.md` | Modified | Added Phase 141 PAUL changelog entry. |
| `.paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md` | Created | Executable PAUL plan. |
| `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md` | Created | UNIFY summary. |
| `src/Modules/Settings/IntegrationsHubController.php` | Modified | Builds marketplace/courier/other groups. |
| `resources/views/settings/integrations.php` | Modified | Renders grouped sections and alerts without old header card. |
| `resources/lang/pl.php` | Modified | Adds group titles and removes unused hub description. |
| `resources/scss/app.scss` | Modified | Adds compact integrations hub section styling. |
| `public/assets/css/app.css` | Modified | Rebuilt compiled CSS. |
| `DOCS/ARCHITECTURE.md` | Modified | Documents grouped hub contract. |
| `DOCS/TECH_CHANGELOG.md` | Modified | Records Phase 141 technical change. |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Use grouped sections instead of full cards | Operator preferred sections or tile-like grouping; sections keep the screen compact. | Less vertical noise and no nested-card feel. |
| Keep Allegro environments separate | Operator confirmed they can remain separate. | No ambiguity in sandbox/production status or configure URL. |
| Keep grouping presentation-only | Request did not require provider behavior changes. | No migration, no route changes, low regression risk. |
## Deviations from Plan
### Summary
| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed | 1 | Removed stale Phase 141 god-class wording in docs while adding new Phase 141 docs. |
| Deferred | 2 | Manual UI smoke and Sonar scan remain environment-dependent. |
### Auto-fixed Issues
**1. Stale Phase 141 reference in docs**
- **Found during:** Task 3 documentation update.
- **Issue:** Older Phase 139 docs mentioned "Phase 141 god-class splits"; Phase 141 is now integrations hub UI.
- **Fix:** Reworded to "future god-class splits" in `DOCS/ARCHITECTURE.md` and `DOCS/TECH_CHANGELOG.md`.
- **Verification:** `rg -n "Phase 141"` now only finds current Phase 141 context.
### Deferred Items
- Manual smoke: open `/settings/integrations`, confirm three sections and provider links.
- SonarQube: rerun scan after `sonar-scanner` is restored in PATH or fallback scanner is downloaded.
## Issues Encountered
| Issue | Resolution |
|-------|------------|
| `sonar-scanner` unavailable in PATH | Documented as a Phase 141 skill gap in SUMMARY and STATE. |
| Local app/browser smoke not started | Documented manual smoke checklist. |
## Verification Results
| Check | Result |
|-------|--------|
| `C:\xampp\php\php.exe -l src\Modules\Settings\IntegrationsHubController.php` | Pass |
| `C:\xampp\php\php.exe -l resources\views\settings\integrations.php` | Pass |
| `C:\xampp\php\php.exe -l resources\lang\pl.php` | Pass |
| `npm run build:css` | Pass |
| `git diff --check` | Pass, CRLF warnings only |
| `rg` for old hub description in rendered view/lang | Pass, no matches |
| `sonar-scanner --version` | Gap, command not found |
## Next Phase Readiness
**Ready:**
- Hub UI grouping is in place and documented.
- Future provider additions can be assigned to a hub group in one controller method.
**Concerns:**
- Manual UI smoke is still recommended on a running app session.
- SonarQube scan remains pending due to missing CLI.
**Blockers:**
- None.
---
*Phase: 141-integrations-hub-grouped-sections, Plan: 01*
*Completed: 2026-05-18*

View File

@@ -94,7 +94,16 @@ HTTP Request
- Alert rendering in targeted layouts/views uses `Template::$component('components/alert', ...)` instead of direct component includes. Trusted prebuilt alert HTML is still passed as `messageHtml`.
- `SmsTemplateController` and `UsersController` centralize repeated routes, flash keys and validation helpers without changing request routes, flash UX or response status contracts.
- `resources/views/shipments/prepare.php` imports `StringHelper` and `DeliveryStatus` locally instead of using inline fully qualified class names.
- Phase 139-02 final Sonar scan reduced OPEN BLOCKER/CRITICAL/MAJOR issues from 605 to 495. Remaining high-impact work is mostly return/cognitive-complexity cleanup, accessibility, and Phase 141 god-class splits.
- Phase 139-02 final Sonar scan reduced OPEN BLOCKER/CRITICAL/MAJOR issues from 605 to 495. Remaining high-impact work is mostly return/cognitive-complexity cleanup, accessibility, and future god-class splits.
## Integrations Hub
- `IntegrationsHubController` builds `/settings/integrations` as grouped view data instead of one flat table.
- Phase 141 groups remain presentation-only and preserve every provider row contract (`provider`, `instance`, auth/secret/active/test status, configure URL).
- Marketplace group: Allegro Sandbox, Allegro Production, shopPRO, Erli.
- Courier group: InPost, Apaczka, polkurier.pl.
- Other group: Fakturownia, HostedSMS, SMSPLANET.
- The hub view renders lightweight sections with shared table columns; provider-specific settings pages and routes remain unchanged.
## Frontend Enhancement Modules

View File

@@ -1,5 +1,19 @@
# Technical Changelog
## 2026-05-18 - Phase 141 Plan 01: Integrations Hub Grouped Sections
**Co zrobiono:**
- Podzielono `/settings/integrations` na trzy lekkie sekcje: marketplace, kurierzy i pozostale integracje.
- `IntegrationsHubController` przekazuje do widoku `groups` zamiast jednej plaskiej listy `rows`, zachowujac dotychczasowy kontrakt pojedynczego wiersza providera.
- Usunieto stary opis huba "Wspolny panel konfiguracji wszystkich providerow." z renderowanego widoku.
- Dodano kompaktowe style SCSS dla sekcji huba i przebudowano `public/assets/css/app.css`.
**Dlaczego:**
- Liczba integracji urosla i jedna tabela byla trudniejsza do szybkiego skanowania. Grupowanie oddziela kanaly sprzedazy, przewoznikow i narzedzia pomocnicze bez zmiany backendu integracji.
**BREAKING / migracja:**
- Brak migracji DB i brak zmian breaking. Endpointy oraz strony konfiguracji providerow pozostaja bez zmian.
## 2026-05-18 - Phase 140 Plan 01: shopPRO Polkurier Delivery Mapping
**Co zrobiono:**
@@ -24,7 +38,7 @@
- `SmsTemplateController` i `UsersController` dostaly stale dla tras/flashy oraz male helpery walidacji/redirectow bez zmiany kontraktu formularzy.
**Dlaczego:**
- Plan 139-02 mial agresywnie zredukowac najwieksze bezpieczne grupy Sonar po 139-01, szczegolnie `php:S4833` i `php:S112`, bez ruszania schematu DB ani god-class splitow z Phase 141.
- Plan 139-02 mial agresywnie zredukowac najwieksze bezpieczne grupy Sonar po 139-01, szczegolnie `php:S4833` i `php:S112`, bez ruszania schematu DB ani przyszlych god-class splitow.
**BREAKING / migracja:**
- Brak migracji DB i brak zmian breaking. PHPUnit nadal nie jest dostepny w checkoutcie przez brak `vendor/`; wykonano lint, ad-hoc smoke mappera Erli i finalny SonarScanner.

File diff suppressed because one or more lines are too long

View File

@@ -574,9 +574,13 @@ return [
'submenu_label' => 'Sekcje ustawien',
'integrations_hub' => [
'title' => 'Integracje',
'description' => 'Wspolny panel konfiguracji wszystkich providerow.',
'list_title' => 'Skonfigurowane integracje',
'empty' => 'Brak dostepnych integracji.',
'groups' => [
'marketplace' => 'Integracje z marketplace',
'couriers' => 'Integracje z kurierami',
'other' => 'Integracje pozostale',
],
'fields' => [
'provider' => 'Provider',
'instance' => 'Instancja',

View File

@@ -411,6 +411,10 @@ h4.section-title {
margin-top: 8px;
}
.mb-12 {
margin-bottom: 8px;
}
.mt-16 {
margin-top: 12px;
}
@@ -2797,6 +2801,51 @@ details[open] > .order-statuses-side__title .order-statuses-side__arrow {
}
}
.integrations-hub {
display: grid;
gap: 12px;
}
.integrations-hub-section {
background: #fff;
border: 1px solid var(--c-border);
border-radius: 8px;
overflow: hidden;
}
.integrations-hub-section__head {
align-items: center;
background: #f8fafc;
border-bottom: 1px solid #e2e8f0;
display: flex;
justify-content: space-between;
min-height: 40px;
padding: 9px 12px;
}
.integrations-hub-section__title {
color: var(--c-text-strong, #1e293b);
font-size: 14px;
font-weight: 700;
line-height: 1.25;
margin: 0;
}
.integrations-hub-section__table {
margin: 0;
}
.integrations-hub-section__table .table {
margin: 0;
}
.integrations-hub-section__table .table th,
.integrations-hub-section__table .table td {
padding-bottom: 7px;
padding-top: 7px;
white-space: nowrap;
}
.integration-settings-group {
grid-column: 1 / -1;
border: 1px solid var(--c-border);

View File

@@ -1,23 +1,27 @@
<?php
$items = is_array($rows ?? null) ? $rows : [];
$groups = is_array($groups ?? null) ? $groups : [];
?>
<section class="card">
<h2 class="section-title"><?= $e($t('settings.integrations_hub.title')) ?></h2>
<p class="muted mt-12"><?= $e($t('settings.integrations_hub.description')) ?></p>
<?php if (!empty($errorMessage)): ?>
<div class="mt-12"><?php $component('components/alert', ['type' => 'danger', 'message' => (string) $errorMessage, 'dismissible' => true]); ?></div>
<div class="mb-12"><?php $component('components/alert', ['type' => 'danger', 'message' => (string) $errorMessage, 'dismissible' => true]); ?></div>
<?php endif; ?>
<?php if (!empty($successMessage)): ?>
<div class="mt-12"><?php $component('components/alert', ['type' => 'success', 'message' => (string) $successMessage, 'dismissible' => true]); ?></div>
<div class="mb-12"><?php $component('components/alert', ['type' => 'success', 'message' => (string) $successMessage, 'dismissible' => true]); ?></div>
<?php endif; ?>
</section>
<section class="card mt-16 integrations-overview">
<h3 class="section-title"><?= $e($t('settings.integrations_hub.list_title')) ?></h3>
<div class="table-wrap mt-12">
<div class="integrations-hub">
<?php foreach ($groups as $group): ?>
<?php
$groupRows = is_array($group['rows'] ?? null) ? $group['rows'] : [];
$groupKey = preg_replace('/[^a-z0-9_-]/i', '', (string) ($group['key'] ?? 'group'));
?>
<section class="integrations-hub-section integrations-hub-section--<?= $e($groupKey ?: 'group') ?>">
<div class="integrations-hub-section__head">
<h2 class="integrations-hub-section__title"><?= $e((string) ($group['title'] ?? '')) ?></h2>
</div>
<div class="table-wrap integrations-hub-section__table">
<table class="table">
<thead>
<tr>
@@ -31,12 +35,12 @@ $items = is_array($rows ?? null) ? $rows : [];
</tr>
</thead>
<tbody>
<?php if ($items === []): ?>
<?php if ($groupRows === []): ?>
<tr>
<td class="muted" colspan="7"><?= $e($t('settings.integrations_hub.empty')) ?></td>
</tr>
<?php else: ?>
<?php foreach ($items as $item): ?>
<?php foreach ($groupRows as $item): ?>
<tr>
<td><?= $e((string) ($item['provider'] ?? '')) ?></td>
<td><?= $e((string) ($item['instance'] ?? '')) ?></td>
@@ -56,3 +60,5 @@ $items = is_array($rows ?? null) ? $rows : [];
</table>
</div>
</section>
<?php endforeach; ?>
</div>

View File

@@ -32,18 +32,7 @@ final class IntegrationsHubController
public function index(Request $request): Response
{
$rows = [
$this->buildAllegroRow('sandbox'),
$this->buildAllegroRow('production'),
$this->buildApaczkaRow(),
$this->buildPolkurierRow(),
$this->buildInpostRow(),
$this->buildShopproRow(),
$this->buildFakturowniaRow(),
$this->buildHostedSmsRow(),
$this->buildSmsplanetRow(),
$this->buildErliRow(),
];
$groups = $this->buildGroups();
$html = $this->template->render('settings/integrations', [
'title' => $this->translator->get('settings.integrations_hub.title'),
@@ -51,7 +40,7 @@ final class IntegrationsHubController
'activeSettings' => 'integrations',
'user' => $this->auth->user(),
'csrfToken' => Csrf::token(),
'rows' => $rows,
'groups' => $groups,
'errorMessage' => (string) Flash::get('settings_error', ''),
'successMessage' => (string) Flash::get('settings_success', ''),
], 'layouts/app');
@@ -59,6 +48,43 @@ final class IntegrationsHubController
return Response::html($html);
}
/**
* @return array<int, array{key: string, title: string, rows: array<int, array<string, mixed>>}>
*/
private function buildGroups(): array
{
return [
[
'key' => 'marketplace',
'title' => $this->translator->get('settings.integrations_hub.groups.marketplace'),
'rows' => [
$this->buildAllegroRow('sandbox'),
$this->buildAllegroRow('production'),
$this->buildShopproRow(),
$this->buildErliRow(),
],
],
[
'key' => 'couriers',
'title' => $this->translator->get('settings.integrations_hub.groups.couriers'),
'rows' => [
$this->buildInpostRow(),
$this->buildApaczkaRow(),
$this->buildPolkurierRow(),
],
],
[
'key' => 'other',
'title' => $this->translator->get('settings.integrations_hub.groups.other'),
'rows' => [
$this->buildFakturowniaRow(),
$this->buildHostedSmsRow(),
$this->buildSmsplanetRow(),
],
],
];
}
/**
* @return array<string, mixed>
*/