feat(117): smsplanet integration settings
This commit is contained in:
230
.paul/phases/117-smsplanet-integration/117-01-PLAN.md
Normal file
230
.paul/phases/117-smsplanet-integration/117-01-PLAN.md
Normal file
@@ -0,0 +1,230 @@
|
||||
---
|
||||
phase: 117-smsplanet-integration
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- database/migrations/20260512_000108_create_smsplanet_integration_settings.sql
|
||||
- src/Modules/Settings/SmsplanetApiClient.php
|
||||
- src/Modules/Settings/SmsplanetIntegrationRepository.php
|
||||
- src/Modules/Settings/SmsplanetIntegrationController.php
|
||||
- src/Modules/Settings/IntegrationsHubController.php
|
||||
- routes/web.php
|
||||
- resources/views/settings/smsplanet.php
|
||||
- resources/lang/pl.php
|
||||
- DOCS/DB_SCHEMA.md
|
||||
- DOCS/ARCHITECTURE.md
|
||||
- DOCS/TECH_CHANGELOG.md
|
||||
- .paul/codebase/db_schema.md
|
||||
- .paul/codebase/architecture.md
|
||||
- .paul/codebase/tech_changelog.md
|
||||
autonomous: true
|
||||
delegation: auto
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Dodac pierwsza wersje integracji SMSPLANET: jedna globalna konfiguracja konta oraz formularz realnej wysylki testowego SMS-a.
|
||||
|
||||
## Purpose
|
||||
Operator ma moc porownac i zweryfikowac druga bramke SMS bez naruszania istniejacej integracji HostedSMS ani dodawania jeszcze automatyzacji SMS.
|
||||
|
||||
## Output
|
||||
Nowa podstrona `/settings/integrations/smsplanet`, zapis konfiguracji w DB, klient API SMSPLANET, akcja testowej wysylki SMS i wpis w hubie integracji.
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
<clarifications>
|
||||
- **Zakres** - Czy SMSPLANET ma w tej fazie dostac tylko ekran konfiguracji i realny test SMS, analogicznie do HostedSMS?
|
||||
-> Odpowiedz: Na razie tylko konfiguracja + test.
|
||||
- **Autoryzacja** - Ktory sposob autoryzacji SMSPLANET przyjmujemy jako podstawowy w UI?
|
||||
-> Odpowiedz: Obie wersje, czyli Bearer token oraz key + password.
|
||||
- **Konto** - Czy SMSPLANET ma byc jedna globalna konfiguracja tak jak HostedSMS?
|
||||
-> Odpowiedz: Jedna.
|
||||
- **Test** - Czy test SMSPLANET ma realnie wysylac SMS, czy uzywac parametru `test=1` z API SMSPLANET?
|
||||
-> Odpowiedz: Realnie.
|
||||
</clarifications>
|
||||
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
@AGENTS.md
|
||||
@DOCS/DB_SCHEMA.md
|
||||
@DOCS/ARCHITECTURE.md
|
||||
|
||||
## API Context
|
||||
SMSPLANET API docs: `https://smsplanet.pl/doc/slate/index.html#introduction`
|
||||
- API version documented as `2.3.0`, UTF-8, `POST` content type `application/x-www-form-urlencoded`.
|
||||
- Recommended SMS endpoint: `POST https://api2.smsplanet.pl/sms`.
|
||||
- Recommended authorization: `Authorization: Bearer <token>`.
|
||||
- Alternative authorization: request params `key` and `password`.
|
||||
- Required send params: `from`, `to`, `msg`.
|
||||
- Optional params useful for first version: `clear_polish` (`0`/`1`), `transactional` (`0`/`1`), `test` (`0`/`1`). This plan uses real SMS, so do not set `test=1` in the test action.
|
||||
- Success response contains `messageId`; business failure contains `errorMsg` and `errorCode`.
|
||||
- Accepted recipient formats include `600111222`, `48600111222`, `+48600111222`; normalize only whitespace/separators, do not force country prefix beyond validation.
|
||||
|
||||
## Prior Work
|
||||
@.paul/phases/116-hostedsms-integration/116-01-SUMMARY.md
|
||||
@.paul/phases/116-hostedsms-integration/116-01-PLAN.md
|
||||
|
||||
## Source Files
|
||||
@routes/web.php
|
||||
@src/Modules/Settings/HostedSmsApiClient.php
|
||||
@src/Modules/Settings/HostedSmsIntegrationRepository.php
|
||||
@src/Modules/Settings/HostedSmsIntegrationController.php
|
||||
@src/Modules/Settings/IntegrationsRepository.php
|
||||
@src/Modules/Settings/IntegrationSecretCipher.php
|
||||
@src/Modules/Settings/IntegrationsHubController.php
|
||||
@resources/views/settings/hostedsms.php
|
||||
@resources/views/settings/integrations.php
|
||||
@resources/lang/pl.php
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
| Skill | Priority | When to Invoke | Loaded? |
|
||||
|-------|----------|----------------|---------|
|
||||
| sonar-scanner | required | Po APPLY, przed UNIFY | o |
|
||||
|
||||
## Skill Invocation Checklist
|
||||
- [ ] Uruchomic `sonar-scanner` po implementacji, jezeli CLI i SonarQube sa dostepne.
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Zapis konfiguracji SMSPLANET
|
||||
```gherkin
|
||||
Given zalogowany operator jest na stronie ustawien SMSPLANET
|
||||
When wybierze metode autoryzacji, uzupelni wymagane pola, nadpis nadawcy, opcje wysylki i zapisze formularz z poprawnym CSRF
|
||||
Then konfiguracja zostanie zapisana jako jedna globalna integracja, sekrety beda zaszyfrowane przez IntegrationSecretCipher, a zapisane sekrety nie beda widoczne w formularzu
|
||||
```
|
||||
|
||||
## AC-2: Dwie metody autoryzacji
|
||||
```gherkin
|
||||
Given operator konfiguruje SMSPLANET
|
||||
When wybierze Bearer token
|
||||
Then aplikacja wymaga tokenu przy pierwszym zapisie i wysyla test z naglowkiem Authorization Bearer
|
||||
And gdy wybierze key + password, aplikacja wymaga obu sekretow przy pierwszym zapisie i wysyla test z parametrami key/password
|
||||
```
|
||||
|
||||
## AC-3: Walidacja konfiguracji i testu
|
||||
```gherkin
|
||||
Given operator probuje zapisac lub testowac SMSPLANET
|
||||
When brakuje pol wymaganych dla wybranej metody autoryzacji, brakuje nadpisu albo numer/tresc testu sa niepoprawne
|
||||
Then aplikacja pokazuje czytelny blad i nie wykonuje wysylki testowej bez kompletnych danych
|
||||
```
|
||||
|
||||
## AC-4: Realny test wysylki SMSPLANET
|
||||
```gherkin
|
||||
Given konfiguracja SMSPLANET jest zapisana z poprawnymi danymi
|
||||
When operator poda numer testowy i tresc testowa oraz kliknie wysylke testowa
|
||||
Then aplikacja wykona realny POST do SMSPLANET bez parametru test=1, zapisze wynik w polach last_test_* integracji i pokaze messageId albo errorMsg/errorCode z API
|
||||
```
|
||||
|
||||
## AC-5: Widocznosc w panelu integracji
|
||||
```gherkin
|
||||
Given operator otwiera Ustawienia > Integracje
|
||||
When integracja SMSPLANET istnieje albo jeszcze nie jest skonfigurowana
|
||||
Then hub pokazuje wiersz SMSPLANET ze statusem konfiguracji, sekretu, aktywnosci, ostatniego testu i linkiem do ustawien
|
||||
```
|
||||
|
||||
## AC-6: Dokumentacja i zgodnosc projektu
|
||||
```gherkin
|
||||
Given funkcja zostala wdrozona
|
||||
When sprawdzane sa dokumenty techniczne i testy
|
||||
Then DOCS oraz .paul/codebase opisuja nowa tabele, klasy, endpointy i przeplyw, a testy/lint nie wykazuja regresji
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Dodac model konfiguracji SMSPLANET</name>
|
||||
<files>database/migrations/20260512_000108_create_smsplanet_integration_settings.sql, src/Modules/Settings/SmsplanetIntegrationRepository.php</files>
|
||||
<action>
|
||||
Utworz migracje dla pojedynczej tabeli `smsplanet_integration_settings` z rekordem `id=1`, `integration_id` jako UNIQUE FK do `integrations`, polami `auth_method`, `api_token_encrypted`, `api_key`, `api_password_encrypted`, `sender`, `clear_polish`, `transactional`, `created_at`, `updated_at`.
|
||||
Seeduj bazowy rekord `integrations` typu `smsplanet`, nazwa `SMSPLANET`, base_url `https://api2.smsplanet.pl/sms`, timeout 15, aktywny.
|
||||
Repozytorium ma zapewniac bazowy rekord i settings row, zwracac flagi `has_api_token` oraz `has_api_password`, nigdy nie zwracac sekretow w `getSettings()`, zapisywac nowe sekrety tylko gdy pola formularza nie sa puste, wymagac odpowiednich sekretow przy pierwszym zapisie i uzywac `IntegrationSecretCipher` oraz prepared statements.
|
||||
`getCredentials()` ma zwracac tylko kompletna, aktywna konfiguracje z odszyfrowanymi sekretami dla wybranej metody autoryzacji.
|
||||
</action>
|
||||
<verify>C:\xampp\php\php.exe -l src/Modules/Settings/SmsplanetIntegrationRepository.php</verify>
|
||||
<done>AC-1, AC-2 i AC-3 spelnione dla warstwy zapisu konfiguracji.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Dodac klienta API i kontroler ustawien</name>
|
||||
<files>src/Modules/Settings/SmsplanetApiClient.php, src/Modules/Settings/SmsplanetIntegrationController.php, routes/web.php</files>
|
||||
<action>
|
||||
Utworz `SmsplanetApiClient` wykonujacy POST form-urlencoded do `https://api2.smsplanet.pl/sms` z `Accept: application/json`, SSL verification, CA z `SslCertificateResolver`, `User-Agent: orderPRO/1.0` i bez `curl_close()`.
|
||||
Klient ma obslugiwac dwie metody autoryzacji: dla `token` dodaje naglowek `Authorization: Bearer ...`; dla `key_password` dodaje do payloadu `key` i `password`.
|
||||
Payload testu zawiera `from`, `to`, `msg`, opcjonalnie `clear_polish=1` i `transactional=1`; test realny nie ustawia `test=1`.
|
||||
Parsuj odpowiedz JSON: `messageId` przy HTTP 2xx oznacza sukces; `errorMsg`/`errorCode` to blad biznesowy; niepoprawny JSON, cURL i HTTP bez messageId maja dac czytelny komunikat.
|
||||
Utworz `SmsplanetIntegrationController` z akcjami `index`, `save`, `test`. `save` waliduje CSRF i przekazuje payload do repozytorium. `test` waliduje CSRF, numer telefonu po usunieciu spacji, plusa, myslnikow i nawiasow (`^\d{8,15}$`), tresc niepusta i maks. 918 znakow (6 SMS po 153 znaki dla bezpiecznego limitu pierwszej wersji), pobiera credentials i zapisuje `last_test_status`, `last_test_http_code`, `last_test_message` przez `IntegrationsRepository::updateTestResult`.
|
||||
Podlacz DI i trasy: GET `/settings/integrations/smsplanet`, POST `/settings/integrations/smsplanet/save`, POST `/settings/integrations/smsplanet/test`.
|
||||
</action>
|
||||
<verify>C:\xampp\php\php.exe -l src/Modules/Settings/SmsplanetApiClient.php; C:\xampp\php\php.exe -l src/Modules/Settings/SmsplanetIntegrationController.php; C:\xampp\php\php.exe -l routes/web.php</verify>
|
||||
<done>AC-2, AC-3 i AC-4 spelnione dla backendu oraz realnej wysylki testowej.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Dodac UI, hub integracji i dokumentacje</name>
|
||||
<files>resources/views/settings/smsplanet.php, resources/lang/pl.php, src/Modules/Settings/IntegrationsHubController.php, DOCS/DB_SCHEMA.md, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md, .paul/codebase/db_schema.md, .paul/codebase/architecture.md, .paul/codebase/tech_changelog.md</files>
|
||||
<action>
|
||||
Dodaj kompaktowy widok ustawien SMSPLANET wzorowany na HostedSMS, bez inline CSS. Formularz konfiguracji ma pokazac: wybor metody autoryzacji (`token` / `key_password`), token Bearer, key, password, sender (`from`), checkbox `clear_polish`, checkbox `transactional`, aktywnosc.
|
||||
Zastosuj proste progressive enhancement tylko jesli potrzebne: pola niewybranej metody moga pozostac widoczne z opisem, ale walidacja serwerowa decyduje o wymaganiach. Nie dodawaj nowego natywnego `alert()`/`confirm()`.
|
||||
Sekcja testu ma miec numer telefonu i edytowalna tresc z domyslna wartoscia `Test orderPRO SMSPLANET`.
|
||||
Ostatni test pokazuje status, HTTP, `messageId` albo komunikat `errorCode: errorMsg`.
|
||||
Dodaj SMSPLANET do hubu integracji oraz tlumaczenia PL.
|
||||
Zaktualizuj dokumentacje techniczna: tabela `smsplanet_integration_settings`, nowe klasy, trasy, dwie metody autoryzacji i przeplyw testowej wysylki.
|
||||
</action>
|
||||
<verify>C:\xampp\php\php.exe -l resources/views/settings/smsplanet.php; C:\xampp\php\php.exe -l src/Modules/Settings/IntegrationsHubController.php; npm run build --if-present</verify>
|
||||
<done>AC-5 i AC-6 spelnione dla UI, hubu i dokumentacji.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- Nie podpinac `DB_HOST_REMOTE` do runtime aplikacji.
|
||||
- Nie modyfikowac zachowania HostedSMS poza ewentualnym wspoldzielonym wzorcem tylko wtedy, gdy jest to absolutnie potrzebne.
|
||||
- Nie dodawac automatyzacji SMS, szablonow SMS, wysylki z zamowien ani historii wyslanych SMS w tym planie.
|
||||
- Nie dodawac natywnych `alert()` / `confirm()`.
|
||||
- Nie refaktoryzowac istniejacych integracji poza minimalnym dopieciem SMSPLANET do hubu i routes.
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Tylko jedna globalna konfiguracja SMSPLANET.
|
||||
- Tylko realna wysylka testowa SMS z ustawien.
|
||||
- Obslugiwane metody auth w pierwszej wersji: Bearer token oraz key + password.
|
||||
- Bez raportow doreczen, webhookow, sender-field management, czarnej listy, link shortenera, sprawdzania salda i odbierania SMS.
|
||||
- Bez parametryzowanych kampanii masowych; test wysyla pojedynczy SMS do jednego numeru.
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `C:\xampp\php\php.exe bin/migrate.php`
|
||||
- [ ] `C:\xampp\php\php.exe -l` dla nowych/zmienionych plikow PHP
|
||||
- [ ] `npm run build --if-present`
|
||||
- [ ] Manualnie: zapis konfiguracji SMSPLANET dla Bearer token, realna wysylka testowego SMS, komunikat z `messageId`
|
||||
- [ ] Manualnie lub kodowo: walidacja `key_password` wymaga key+password i buduje payload z tymi parametrami
|
||||
- [ ] `sonar-scanner` po APPLY, jezeli CLI i SonarQube sa dostepne
|
||||
- [ ] DOCS i `.paul/codebase` zaktualizowane
|
||||
- [ ] All acceptance criteria met
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Operator moze zapisac jedna konfiguracje SMSPLANET bez ujawniania sekretow.
|
||||
- Operator moze wybrac Bearer token albo key + password i walidacja odpowiada wybranej metodzie.
|
||||
- Operator moze wyslac realny testowy SMS z edytowalna trescia.
|
||||
- Wynik testu jest widoczny w ekranie SMSPLANET i hubie integracji.
|
||||
- Migracje, lint i build przechodza albo blokery srodowiskowe sa jasno opisane w SUMMARY.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/117-smsplanet-integration/117-01-SUMMARY.md`
|
||||
</output>
|
||||
71
.paul/phases/117-smsplanet-integration/117-01-SUMMARY.md
Normal file
71
.paul/phases/117-smsplanet-integration/117-01-SUMMARY.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
phase: 117-smsplanet-integration
|
||||
plan: 01
|
||||
completed: 2026-05-12
|
||||
status: complete-with-environment-gaps
|
||||
---
|
||||
|
||||
# Summary: SMSPLANET Integration Settings + Test SMS
|
||||
|
||||
## Result
|
||||
|
||||
Implemented the first SMSPLANET integration slice: one global configuration screen, encrypted credentials, support for Bearer token and key + password authorization, hub visibility, and a real test SMS flow using `POST https://api2.smsplanet.pl/sms`.
|
||||
|
||||
The implementation also fixes the integration settings checkbox/radio layout reported during UAT by moving the options into the existing compact SCSS component.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
| AC | Status | Notes |
|
||||
|----|--------|-------|
|
||||
| AC-1 Configuration save | PASS | `SmsplanetIntegrationRepository` stores one global row, encrypts token/key/password, and never returns secrets to the view. |
|
||||
| AC-2 Two auth methods | PASS | Bearer token sends `Authorization: Bearer ...`; key + password sends credentials in form payload. First save requires complete credentials for the selected method. |
|
||||
| AC-3 Validation | PASS | Save/test validate CSRF, sender, selected auth method, phone number and message length before API calls. |
|
||||
| AC-4 Real test SMS | IMPLEMENTED, MANUAL PENDING | API client performs real send and does not set `test=1`. Manual live send is pending because local DB/migration verification was blocked. |
|
||||
| AC-5 Hub visibility | PASS | `IntegrationsHubController` includes SMSPLANET with configuration, secret, active and last-test status. |
|
||||
| AC-6 Docs/compliance | PASS WITH TOOLING GAPS | DOCS and `.paul/codebase` updated. PHP lint/build passed. Migration, PHPUnit and Sonar were blocked by local tooling/environment. |
|
||||
|
||||
## Verification
|
||||
|
||||
Passed:
|
||||
- `C:\xampp\php\php.exe -l` for all new/modified PHP files in this phase.
|
||||
- `npm run build --if-present`.
|
||||
- `git diff --check`.
|
||||
|
||||
Blocked or unavailable:
|
||||
- `C:\xampp\php\php.exe bin\migrate.php` failed because local MySQL refused the connection: `SQLSTATE[HY000] [2002]`.
|
||||
- `vendor\bin\phpunit` was not available: `Could not open input file`.
|
||||
- `sonar-scanner` was not available in PATH.
|
||||
- Manual real SMSPLANET send remains pending until the migration is applied and valid SMSPLANET credentials are tested.
|
||||
|
||||
## Deviations
|
||||
|
||||
- `api_key` is stored as `api_key_encrypted` rather than plaintext. This is stricter than the draft task and consistent with the requirement that credentials are secrets.
|
||||
- `IntegrationSecretCipher` had an invalid namespace import and was fixed because SMSPLANET and existing integrations depend on it at runtime.
|
||||
- Checkbox/radio UI was adjusted in `resources/scss/app.scss` after the UAT screenshot showed inconsistent native control sizing/alignment.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `.paul/codebase/architecture.md`
|
||||
- `.paul/codebase/db_schema.md`
|
||||
- `.paul/codebase/tech_changelog.md`
|
||||
- `.paul/phases/117-smsplanet-integration/117-01-PLAN.md`
|
||||
- `.paul/phases/117-smsplanet-integration/117-01-SUMMARY.md`
|
||||
- `DOCS/ARCHITECTURE.md`
|
||||
- `DOCS/DB_SCHEMA.md`
|
||||
- `DOCS/TECH_CHANGELOG.md`
|
||||
- `database/migrations/20260512_000108_create_smsplanet_integration_settings.sql`
|
||||
- `resources/lang/pl.php`
|
||||
- `resources/scss/app.scss`
|
||||
- `resources/views/settings/smsplanet.php`
|
||||
- `routes/web.php`
|
||||
- `src/Modules/Settings/IntegrationSecretCipher.php`
|
||||
- `src/Modules/Settings/IntegrationsHubController.php`
|
||||
- `src/Modules/Settings/SmsplanetApiClient.php`
|
||||
- `src/Modules/Settings/SmsplanetIntegrationController.php`
|
||||
- `src/Modules/Settings/SmsplanetIntegrationRepository.php`
|
||||
|
||||
## Follow-Up
|
||||
|
||||
- Start local MySQL/XAMPP and run `C:\xampp\php\php.exe bin\migrate.php`.
|
||||
- Save real SMSPLANET credentials and run both manual test paths: Bearer token and key + password.
|
||||
- Run Sonar once `sonar-scanner` is available.
|
||||
Reference in New Issue
Block a user