Files
orderPRO/.paul/phases/06-sonarqube-quality/06-01-PLAN.md
Jacek Pyziak 3a9cfcd4a2 wip(06-sonarqube-quality): 6 planów SonarQube Quality utworzonych
Plany dla php:S112, S1142, S1192, S3776, S1448, S138 — gotowe do APPLY.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 10:54:57 +01:00

12 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
06-sonarqube-quality 01 execute 1
src/Core/Exceptions/OrderProException.php
src/Core/Exceptions/AllegroApiException.php
src/Core/Exceptions/AllegroOAuthException.php
src/Core/Exceptions/ApaczkaApiException.php
src/Core/Exceptions/ShipmentException.php
src/Core/Exceptions/IntegrationConfigException.php
src/Modules/Settings/AllegroApiClient.php
src/Modules/Settings/AllegroOAuthClient.php
src/Modules/Settings/AllegroTokenManager.php
src/Modules/Settings/AllegroIntegrationRepository.php
src/Modules/Settings/AllegroIntegrationController.php
src/Modules/Settings/AllegroOrderImportService.php
src/Modules/Settings/AllegroOrdersSyncService.php
src/Modules/Settings/ApaczkaApiClient.php
src/Modules/Settings/ApaczkaIntegrationRepository.php
src/Modules/Shipments/ApaczkaShipmentService.php
src/Modules/Shipments/AllegroShipmentService.php
src/Modules/Shipments/ShipmentController.php
src/Modules/Settings/IntegrationSecretCipher.php
src/Modules/Settings/InpostIntegrationRepository.php
src/Modules/Settings/ShopproIntegrationsRepository.php
src/Modules/Settings/ShopproOrdersSyncService.php
src/Modules/Settings/ShopproPaymentStatusSyncService.php
true
## Goal Zastąpić 86+ wywołań `throw new RuntimeException()` dedykowanymi klasami wyjątków per moduł — eliminacja naruszeń SonarQube php:S112.

Purpose

SonarQube flaguje RuntimeException jako zbyt ogólny — łapanie catch (RuntimeException) nie mówi nic o tym, jaki błąd nastąpił. Typowane wyjątki umożliwiają precyzyjny catch w wywołującym kodzie i poprawiają czytelność stacktrace.

Output

Hierarchia klas wyjątków w src/Core/Exceptions/ + podmienione throw w 13 plikach. Liczba S112 w SonarQube spada z 95 do ~5 (pozostałości w Core).

## Project Context @.paul/PROJECT.md @.paul/STATE.md

Source Files

@src/Modules/Settings/AllegroApiClient.php @src/Modules/Settings/AllegroOAuthClient.php @src/Modules/Settings/AllegroTokenManager.php @src/Modules/Shipments/ApaczkaShipmentService.php @src/Modules/Shipments/AllegroShipmentService.php @src/Modules/Settings/ApaczkaApiClient.php @src/Modules/Settings/IntegrationSecretCipher.php

## Required Skills (from SPECIAL-FLOWS.md)
Skill Priority When to Invoke Loaded?
sonar-scanner required Po APPLY, przed UNIFY

Skill Invocation Checklist

  • sonar-scanner uruchomiony po zakończeniu APPLY (CLI w katalogu projektu)

<acceptance_criteria>

AC-1: Hierarchia wyjątków istnieje

Given brak folderu src/Core/Exceptions/
When plan zostaje wykonany
Then folder src/Core/Exceptions/ istnieje z klasami: OrderProException, AllegroApiException, AllegroOAuthException, ApaczkaApiException, ShipmentException, IntegrationConfigException

AC-2: Allegro-specific throws podmienione

Given AllegroApiClient, AllegroOAuthClient, AllegroTokenManager rzucają RuntimeException
When plan zostaje wykonany
Then wszystkie throw w tych plikach używają AllegroApiException lub AllegroOAuthException

AC-3: Apaczka-specific throws podmienione

Given ApaczkaApiClient, ApaczkaShipmentService, ApaczkaIntegrationRepository rzucają RuntimeException
When plan zostaje wykonany
Then wszystkie throw w tych plikach używają ApaczkaApiException

AC-4: Shipment throws podmienione

Given AllegroShipmentService, ShipmentController rzucają RuntimeException
When plan zostaje wykonany
Then wszystkie throw używają ShipmentException

AC-5: Brak regresji

Given aplikacja działa przed zmianą
When klasy wyjątków rozszerzają RuntimeException (łańcuch dziedziczenia zachowany)
Then istniejące catch (RuntimeException) w kodzie wywołującym nadal działają

</acceptance_criteria>

Task 1: Utwórz hierarchię klas wyjątków src/Core/Exceptions/OrderProException.php, src/Core/Exceptions/AllegroApiException.php, src/Core/Exceptions/AllegroOAuthException.php, src/Core/Exceptions/ApaczkaApiException.php, src/Core/Exceptions/ShipmentException.php, src/Core/Exceptions/IntegrationConfigException.php Utwórz folder src/Core/Exceptions/ i pliki klas z namespace App\Core\Exceptions.
Hierarchia:
- OrderProException extends \RuntimeException — baza dla wszystkich własnych wyjątków
- AllegroApiException extends OrderProException — błędy HTTP/JSON Allegro API i OAuth
- AllegroOAuthException extends AllegroApiException — specyficznie błędy OAuth (token refresh, brak tokenów)
- ApaczkaApiException extends OrderProException — błędy API Apaczka (HTTP, curl, payload)
- ShipmentException extends OrderProException — błędy tworzenia/pobierania przesyłek (brak zamówienia, brak providera, brak paczki)
- IntegrationConfigException extends OrderProException — błędy konfiguracji integracji (brak rekordu w DB, brak klucza API, brak sekretu)

Każda klasa: minimalna (tylko class declaration + extends). Brak dodatkowych metod — nie powielać logiki.
Nie dodawaj konstruktorów ani innych metod — klasy wyjątków mają być tylko markerami.
php -l src/Core/Exceptions/OrderProException.php (i pozostałe 5 plików) — każdy zwraca "No syntax errors" AC-1 satisfied: folder src/Core/Exceptions/ z 6 klasami istnieje i jest poprawny składniowo Task 2: Podmień RuntimeException w plikach Allegro src/Modules/Settings/AllegroApiClient.php, src/Modules/Settings/AllegroOAuthClient.php, src/Modules/Settings/AllegroTokenManager.php, src/Modules/Settings/AllegroIntegrationRepository.php, src/Modules/Settings/AllegroIntegrationController.php, src/Modules/Settings/AllegroOrderImportService.php, src/Modules/Settings/AllegroOrdersSyncService.php W każdym pliku: 1. Dodaj use App\Core\Exceptions\AllegroApiException; (i AllegroOAuthException tam gdzie dotyczy OAuth) 2. Zastąp throw new RuntimeException(...) odpowiednią klasą: - AllegroApiClient.php (18x): HTTP/JSON/curl błędy → AllegroApiException; błędy OAuth (ALLEGRO_HTTP_401) → AllegroApiException - AllegroOAuthClient.php (6x): wszystkie → AllegroOAuthException - AllegroTokenManager.php (3x): brak połączenia OAuth, brak danych, niepowodzenie refresh → AllegroOAuthException - AllegroIntegrationRepository.php (1x): brak rekordu → IntegrationConfigException (użyj use App\Core\Exceptions\IntegrationConfigException) - AllegroIntegrationController.php (1x): brak credentials → IntegrationConfigException - AllegroOrderImportService.php (2x): błędy importu → AllegroApiException - AllegroOrdersSyncService.php (1x): brak aktywnej integracji → IntegrationConfigException
Uwaga: NIE zmieniaj logiki catch bloków — tylko throw. NIE zmieniaj komunikatów błędów.
Uwaga: \RuntimeException w AllegroIntegrationController (jeśli catch) — NIE ruszać.
php -l src/Modules/Settings/AllegroApiClient.php php -l src/Modules/Settings/AllegroOAuthClient.php php -l src/Modules/Settings/AllegroTokenManager.php grep -r "new RuntimeException" src/Modules/Settings/Allegro*.php — powinno zwrócić 0 wyników AC-2 satisfied: pliki Allegro nie zawierają throw new RuntimeException Task 3: Podmień RuntimeException w plikach Apaczka, Shipment i pozostałych src/Modules/Settings/ApaczkaApiClient.php, src/Modules/Settings/ApaczkaIntegrationRepository.php, src/Modules/Shipments/ApaczkaShipmentService.php, src/Modules/Shipments/AllegroShipmentService.php, src/Modules/Shipments/ShipmentController.php, src/Modules/Settings/IntegrationSecretCipher.php, src/Modules/Settings/InpostIntegrationRepository.php, src/Modules/Settings/ShopproIntegrationsRepository.php, src/Modules/Settings/ShopproOrdersSyncService.php, src/Modules/Settings/ShopproPaymentStatusSyncService.php Podmień RuntimeException: - ApaczkaApiClient.php (9x): curl/HTTP/JSON błędy → ApaczkaApiException - ApaczkaIntegrationRepository.php (4x): brak rekordu/klucza → IntegrationConfigException - ApaczkaShipmentService.php (15x): brak zamówienia/paczki/etykiety → ShipmentException; brak konfiguracji (brak app_id) → IntegrationConfigException; brak danych nadawcy → IntegrationConfigException - AllegroShipmentService.php (8x): brak zamówienia/paczki/przesyłki → ShipmentException; brak danych nadawcy → IntegrationConfigException - ShipmentController.php (3x): nieznany provider, brak paczki, brak providera → ShipmentException - IntegrationSecretCipher.php (3x): brak sekretu, błąd szyfrowania → IntegrationConfigException - InpostIntegrationRepository.php (1x): brak rekordu → IntegrationConfigException - ShopproIntegrationsRepository.php (1x): INTEGRATION_NOT_FOUND → IntegrationConfigException - ShopproOrdersSyncService.php (2x): brak danych API, błąd pobierania zamówień → \RuntimeException (zostawić — są wewnątrz try-catch i message pochodzi z zewnętrznego API) - ShopproPaymentStatusSyncService.php (1x): zostawić jako \RuntimeException (message z zewnętrznego API)
W każdym pliku dodaj odpowiednie use statements na górze.
NIE zmieniaj logiki catch — tylko throw.
php -l src/Modules/Shipments/ApaczkaShipmentService.php php -l src/Modules/Shipments/AllegroShipmentService.php php -l src/Modules/Settings/ApaczkaApiClient.php grep -rn "new RuntimeException" src/ — powinno zwrócić maks. 5 wyników (ShopproOrdersSyncService, ShopproPaymentStatusSyncService, CronRunner, AllegroTokenRefreshHandler — intentional pozostałości) AC-3, AC-4, AC-5 satisfied: Apaczka i Shipment pliki używają typowanych wyjątków; łańcuch dziedziczenia od RuntimeException zachowany

DO NOT CHANGE

  • Bloki catch (RuntimeException) w controllers/handlers — łańcuch dziedziczenia zachowuje kompatybilność, ale NIE ruszaj istniejących catch
  • Komunikaty błędów w throw — tylko typ wyjątku się zmienia
  • src/Core/Exceptions/ — nie tworzyć tu nic poza 6 klasami z tego planu
  • routes/web.php
  • Pliki widoków (resources/views/)

SCOPE LIMITS

  • Nie refaktoryzuj logiki poza podmianą throw
  • Nie dodawaj konstruktorów ani metod do klas wyjątków
  • Nie zmieniaj sposobu obsługi błędów w UI (flash messages, HTTP redirecty)
  • Core wyjątki (Router.php, Template.php, Translator.php, ConnectionFactory.php, Migrator.php) — zostawić jako RuntimeException (mają sens jako generyczne)
Przed zamknięciem planu: - [ ] php -l na wszystkich zmodyfikowanych plikach PHP — zero błędów składniowych - [ ] grep -rn "new RuntimeException" src/ — max 5 wyników (tylko Core + 2 Shoppro intentional) - [ ] ls src/Core/Exceptions/ — 6 plików: OrderProException, AllegroApiException, AllegroOAuthException, ApaczkaApiException, ShipmentException, IntegrationConfigException - [ ] Aplikacja startuje bez błędów (wejście na stronę główną, brak PHP fatal errors w logach) - [ ] sonar-scanner uruchomiony — sprawdź czy S112 violations zmalały

<success_criteria>

  • Wszystkie 3 taski ukończone
  • Zero błędów składniowych PHP
  • grep "new RuntimeException" src/ zwraca ≤5 wyników
  • SonarQube S112 spada z 95 do ≤10 </success_criteria>
Po zakończeniu utwórz `.paul/phases/06-sonarqube-quality/06-01-SUMMARY.md`