13 KiB
13 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous
| phase | plan | type | wave | depends_on | files_modified | autonomous | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 06-integrations-refactoring | 02 | execute | 1 |
|
|
true |
Purpose
Po tym planie IntegrationsRepository będzie lean (~225 linii): tylko settings, logi, product linking, ShopPRO import. ApiloRepository jest jedynym miejscem logiki Apilo.
Output
- IntegrationsController: używa obu repozytoriów (IntegrationsRepository dla settings/logi, ApiloRepository dla apilo*)
- OrderAdminService: 3 metody używają ApiloRepository dla apiloGetAccessToken
- cron.php: apilo* wywołania przez $apiloRepository
- IntegrationsRepository: usunięte metody apilo* (~650 linii mniej)
- IntegrationsRepositoryTest: oczyszczony z duplikatów testów apilo*
Prior Work
@.paul/phases/06-integrations-refactoring/06-01-SUMMARY.md
Source Files
@autoload/admin/Controllers/IntegrationsController.php @autoload/admin/App.php @autoload/Domain/Order/OrderAdminService.php @autoload/Domain/Integrations/IntegrationsRepository.php @tests/Unit/Domain/Integrations/IntegrationsRepositoryTest.php
<acceptance_criteria>
AC-1: IntegrationsController używa ApiloRepository dla apilo*
Given IntegrationsController ma dwa repozytoria: $repository i $apiloRepository
When wywoływana jest dowolna metoda apilo* (apilo_settings, apilo_authorization, itp.)
Then używa $this->apiloRepository->apilo*() a nie $this->repository->apilo*()
AC-2: OrderAdminService i cron.php używają ApiloRepository dla apiloGetAccessToken
Given OrderAdminService::resendToApilo, syncApiloPayment, syncApiloStatus
oraz cron.php potrzebują access tokenu
When wywoływana jest metoda apiloGetAccessToken()
Then używają new ApiloRepository($db) lub $apiloRepository, nie IntegrationsRepository
AC-3: IntegrationsRepository nie zawiera metod apilo*
Given plik IntegrationsRepository.php po cleanup
When sprawdzamy publiczne metody klasy
Then metody apilo* NIE ISTNIEJĄ, pozostają tylko:
getSettings, getSetting, saveSetting,
getLogs, deleteLog, clearLogs,
linkProduct, unlinkProduct, getProductSku,
shopproImportProduct
AC-4: Pełna suite testów green
Given wszystkie zmiany wprowadzone
When uruchamiane jest php phpunit.phar
Then wszystkie testy green (826+ testów, zero regresji)
</acceptance_criteria>
Task 1: Zaktualizuj IntegrationsController i App.php autoload/admin/Controllers/IntegrationsController.php, autoload/admin/App.php **IntegrationsController.php:**1. Dodaj import: `use Domain\Integrations\ApiloRepository;`
2. Dodaj property: `private ApiloRepository $apiloRepository;`
3. Zmień konstruktor na:
```php
public function __construct( IntegrationsRepository $repository, ApiloRepository $apiloRepository )
{
$this->repository = $repository;
$this->apiloRepository = $apiloRepository;
}
```
4. Zamień wszystkie wywołania `$this->repository->apilo*()` na `$this->apiloRepository->apilo*()`:
- linia ~128: `$this->repository->apiloIntegrationStatus()` → `$this->apiloRepository->apiloIntegrationStatus()`
- linia ~150: `$this->repository->apiloAuthorize(...)` → `$this->apiloRepository->apiloAuthorize(...)`
- linia ~159: `$this->repository->apiloIntegrationStatus()` → `$this->apiloRepository->apiloIntegrationStatus()`
- linia ~194: `$this->repository->apiloCreateProduct(...)` → `$this->apiloRepository->apiloCreateProduct(...)`
- linia ~211: `$this->repository->apiloProductSearch(...)` → `$this->apiloRepository->apiloProductSearch(...)`
- linia ~270: `$this->repository->apiloFetchListResult(...)` → `$this->apiloRepository->apiloFetchListResult(...)`
Pozostaw bez zmian: getLogs, clearLogs, getSettings, saveSetting, getProductSku,
linkProduct, unlinkProduct, getSettings('shoppro'), saveSetting('shoppro'), shopproImportProduct
— wszystkie przez `$this->repository`.
**App.php:**
W fabryce 'Integrations' (linia ~384) zmień:
```php
return new \admin\Controllers\IntegrationsController(
new \Domain\Integrations\IntegrationsRepository( $mdb )
);
```
na:
```php
return new \admin\Controllers\IntegrationsController(
new \Domain\Integrations\IntegrationsRepository( $mdb ),
new \Domain\Integrations\ApiloRepository( $mdb )
);
```
php -l autoload/admin/Controllers/IntegrationsController.php — no syntax errors
php -l autoload/admin/App.php — no syntax errors
grep "apiloRepository" autoload/admin/Controllers/IntegrationsController.php — pokazuje 6+ wystąpień
AC-1 spełnione
Task 2: Zaktualizuj OrderAdminService i cron.php
autoload/Domain/Order/OrderAdminService.php, cron.php
**OrderAdminService.php** — 3 metody tworzą IntegrationsRepository i wołają apiloGetAccessToken().
Zmień tylko te 3 miejsca (linie ~422, ~678, ~751):
```php
// PRZED (w każdym z 3 miejsc):
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository($db);
// lub: new \Domain\Integrations\IntegrationsRepository( $mdb );
$accessToken = $integrationsRepository->apiloGetAccessToken();
// PO (w każdym z 3 miejsc):
$apiloRepository = new \Domain\Integrations\ApiloRepository($db);
// lub z $mdb gdzie używano $mdb
$accessToken = $apiloRepository->apiloGetAccessToken();
```
POZOSTAW BEZ ZMIAN (linie ~579, ~628) — te tworzą IntegrationsRepository
i wołają tylko getSettings('apilo') — to metoda generyczna, zostaje w IntegrationsRepository.
**cron.php** — linia ~133:
Po linii `$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );`
dodaj:
```php
$apiloRepository = new \Domain\Integrations\ApiloRepository( $mdb );
```
Zamień wywołania apilo* przez `$integrationsRepository` na `$apiloRepository`:
- linia ~191: `$integrationsRepository->apiloKeepalive(300)` → `$apiloRepository->apiloKeepalive(300)`
- linia ~279: `$integrationsRepository->apiloGetAccessToken()` → `$apiloRepository->apiloGetAccessToken()`
- linia ~560: `$integrationsRepository->apiloGetAccessToken()` → `$apiloRepository->apiloGetAccessToken()`
- linia ~589: `$integrationsRepository->apiloGetAccessToken()` → `$apiloRepository->apiloGetAccessToken()`
- linia ~642: `$integrationsRepository->apiloGetAccessToken()` → `$apiloRepository->apiloGetAccessToken()`
POZOSTAW BEZ ZMIAN w cron.php:
- `$integrationsRepository->getSettings('apilo')` (linie ~188, ~198, ~553, ~586, ~632)
- `$integrationsRepository->saveSetting('apilo', ...)` (linia ~625)
php -l autoload/Domain/Order/OrderAdminService.php — no syntax errors
php -l cron.php — no syntax errors
grep "integrationsRepository->apilo" cron.php — brak wyników (wszystkie apilo przeniesione)
grep "integrationsRepository->apilo" autoload/Domain/Order/OrderAdminService.php — brak wyników
AC-2 spełnione
Task 3: Usuń metody apilo* z IntegrationsRepository + cleanup testów
autoload/Domain/Integrations/IntegrationsRepository.php, tests/Unit/Domain/Integrations/IntegrationsRepositoryTest.php
**IntegrationsRepository.php:**
Usuń następujące bloki (cały kod między komentarzami sekcji a kolejną sekcją):
1. Sekcję "// ── Apilo OAuth" z metodami:
- `apiloAuthorize()`
- `apiloGetAccessToken()`
- `apiloKeepalive()`
- `refreshApiloAccessToken()` (private)
- `shouldRefreshAccessToken()` (private)
- `isFutureDate()` (private)
2. Stałe klasy:
- `private const APILO_ENDPOINTS = [...]`
- `private const APILO_SETTINGS_KEYS = [...]`
3. Sekcję "// ── Apilo API fetch lists" z metodami:
- `apiloFetchList()`
- `apiloFetchListResult()`
- `normalizeApiloMapList()` (private)
- `isMapListShape()` (private)
- `extractApiloErrorMessage()` (private)
4. Z sekcji "// ── Apilo product operations" usuń tylko:
- `apiloProductSearch()`
- `apiloCreateProduct()`
(ZACHOWAJ `getProductSku()` — jest generyczna, używana też przez ShopProductController)
Po usunięciu IntegrationsRepository powinna zawierać:
- settings (settingsTable, getSettings, getSetting, saveSetting)
- logs (getLogs, deleteLog, clearLogs)
- product linking (linkProduct, unlinkProduct, getProductSku)
- ShopPRO import (shopproImportProduct, missingShopproSetting, shopproDb)
**IntegrationsRepositoryTest.php:**
Usuń następujące metody testowe (zostały już przeniesione do ApiloRepositoryTest):
- `testApiloGetAccessTokenReturnsNullWithoutSettings()`
- `testShouldRefreshAccessTokenReturnsFalseForFarFutureDate()`
- `testShouldRefreshAccessTokenReturnsTrueForNearExpiryDate()`
- `testApiloFetchListThrowsForInvalidType()`
- `testApiloFetchListResultReturnsDetailedErrorWhenConfigMissing()`
- `testApiloIntegrationStatusReturnsMissingConfigMessage()`
- `testNormalizeApiloMapListRejectsErrorPayload()`
- `testNormalizeApiloMapListAcceptsIdNameList()`
W metodzie `testAllPublicMethodsExist()` usuń z tablicy `$expectedMethods` wpisy apilo*:
- `'apiloAuthorize'`, `'apiloGetAccessToken'`, `'apiloKeepalive'`, `'apiloIntegrationStatus'`
- `'apiloFetchList'`, `'apiloFetchListResult'`, `'apiloProductSearch'`, `'apiloCreateProduct'`
(Pozostaw: `'getSettings'`, `'getSetting'`, `'saveSetting'`, `'linkProduct'`, `'unlinkProduct'`,
`'getProductSku'`, `'shopproImportProduct'`, `'getLogs'`, `'deleteLog'`, `'clearLogs'`)
Usuń też `testSettingsTableMapping()` i `testShopproProviderWorks()` tylko jeśli są duplikatami
(sprawdź przed usunięciem — jeśli nie mają odpowiedników, zostaw).
php -l autoload/Domain/Integrations/IntegrationsRepository.php — no syntax errors
grep "apilo" autoload/Domain/Integrations/IntegrationsRepository.php — brak wyników (lub tylko komentarze)
php phpunit.phar — wszystkie testy green (826+, zero regresji)
php phpunit.phar tests/Unit/Domain/Integrations/ — oba pliki testów green
AC-3 i AC-4 spełnione
DO NOT CHANGE
autoload/Domain/Integrations/ApiloRepository.php— gotowy, nie modyfikowaćtests/Unit/Domain/Integrations/ApiloRepositoryTest.php— gotowy, nie modyfikowaćautoload/admin/Controllers/ShopProductController.php— używa tylko getSetting(), nie apilo*autoload/admin/Controllers/ShopStatusesController.php— używa tylko getSetting(), nie apilo*autoload/admin/Controllers/ShopTransportController.php— używa tylko getSetting(), nie apilo*autoload/admin/Controllers/ShopPaymentMethodController.php— używa tylko getSetting(), nie apilo*- Logika biznesowa nie zmienia się — czysta migracja wywołań
SCOPE LIMITS
- Nie refaktoryzujemy OrderAdminService poza zmianą 3 instancji na ApiloRepository
- Nie zmieniamy sygnatury metod ani logiki
- Nie przenosimy ShopPRO import do osobnej klasy (to nie ten plan)
<success_criteria>
- IntegrationsController używa ApiloRepository dla wszystkich metod apilo*
- OrderAdminService i cron.php używają ApiloRepository dla apiloGetAccessToken
- IntegrationsRepository nie zawiera żadnych metod apilo*
- Pełna suite testów green bez regresji </success_criteria>