feat(121+122): smsplanet conversation, notifications, default footer
Phase 121 — SMSPLANET Conversation + Notifications:
- migration 20260512_000110 adds smsplanet conversation + notifications tables
- src/Modules/Sms (SmsConversationService, SmsMessageRepository, SmsplanetWebhookController)
- src/Modules/Notifications (Repository, Controller, ApiController)
- order SMS tab, notification center, sender mode, inbound webhook
- public notifications.js + layouts/app.php integration
Phase 122 — SMSPLANET Default SMS Footer:
- migration 20260512_000111 adds smsplanet_integration_settings.default_footer
- footer appended to test SMS and order SMS, validated against 918 char limit
- settings textarea + compact order SMS note when footer configured
Bundled (could not split per-phase without hunk staging):
- routes/web.php (also carries Phase 118 fakturownia redirects)
- DOCS/{ARCHITECTURE,DB_SCHEMA,TECH_CHANGELOG}.md (118 + 121 + 122 entries)
- .paul/codebase/{architecture,db_schema,tech_changelog}.md (118 + 121 + 122)
- .paul/STATE.md, ROADMAP.md, changelog/2026-05-12.md (UNIFY closure)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
210
.paul/phases/122-smsplanet-default-sms-footer/122-01-PLAN.md
Normal file
210
.paul/phases/122-smsplanet-default-sms-footer/122-01-PLAN.md
Normal file
@@ -0,0 +1,210 @@
|
||||
---
|
||||
phase: 122-smsplanet-default-sms-footer
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- database/migrations/20260512_000111_smsplanet_default_footer.sql
|
||||
- src/Modules/Settings/SmsplanetIntegrationRepository.php
|
||||
- src/Modules/Settings/SmsplanetIntegrationController.php
|
||||
- src/Modules/Sms/SmsConversationService.php
|
||||
- resources/views/settings/smsplanet.php
|
||||
- resources/views/orders/show.php
|
||||
- resources/lang/pl.php
|
||||
- resources/scss/app.scss
|
||||
- public/assets/css/app.css
|
||||
- DOCS/DB_SCHEMA.md
|
||||
- DOCS/ARCHITECTURE.md
|
||||
- DOCS/TECH_CHANGELOG.md
|
||||
autonomous: true
|
||||
delegation: off
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Dodać w konfiguracji SMSPLANET opcjonalną stałą stopkę, która jest automatycznie dopisywana do każdego SMS wychodzącego przez SMSPLANET.
|
||||
|
||||
## Purpose
|
||||
Operator ma ustawić jeden wspólny podpis/stopkę firmy bez ręcznego kopiowania jej w każdej wiadomości SMS z zamówienia lub testu integracji.
|
||||
|
||||
## Output
|
||||
Nowa migracja DB, rozszerzona konfiguracja SMSPLANET, dopinanie stopki w backendzie wysyłki, widoczna informacja w UI zamówienia oraz aktualizacja dokumentacji.
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
<clarifications>
|
||||
- **Doprecyzowania** — Czy plan wymaga dodatkowych pytań przed utworzeniem?
|
||||
→ Odpowiedź: Nie. Przyjęte założenia: stopka jest opcjonalna; pusta wartość wyłącza funkcję; stopka dotyczy testowych SMS i SMS z zamówienia; finalna treść po dopięciu stopki musi mieścić się w limicie 918 znaków; w historii rozmowy zapisujemy finalną treść wysłaną do SMSPLANET.
|
||||
</clarifications>
|
||||
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
@.paul/codebase/architecture.md
|
||||
@.paul/codebase/db_schema.md
|
||||
@AGENTS.md
|
||||
@DOCS/ARCHITECTURE.md
|
||||
@DOCS/DB_SCHEMA.md
|
||||
@.paul/phases/121-smsplanet-conversation-notifications/121-01-SUMMARY.md
|
||||
|
||||
## Source Files
|
||||
@src/Modules/Settings/SmsplanetIntegrationRepository.php
|
||||
@src/Modules/Settings/SmsplanetIntegrationController.php
|
||||
@src/Modules/Settings/SmsplanetApiClient.php
|
||||
@src/Modules/Sms/SmsConversationService.php
|
||||
@resources/views/settings/smsplanet.php
|
||||
@resources/views/orders/show.php
|
||||
@resources/lang/pl.php
|
||||
@resources/scss/app.scss
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
| Skill | Priority | When to Invoke | Loaded? |
|
||||
|-------|----------|----------------|---------|
|
||||
| sonar-scanner CLI | required | After APPLY, before UNIFY | not loaded |
|
||||
|
||||
## Skill Invocation Checklist
|
||||
- [ ] Run `sonar-scanner` after implementation, then record any new issues in `DOCS/todo.md` according to `.paul/SPECIAL-FLOWS.md`.
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Footer Configuration
|
||||
```gherkin
|
||||
Given SMSPLANET integration settings are opened
|
||||
When operator enters a default SMS footer and saves settings
|
||||
Then orderPRO stores the footer separately from sender/auth settings and shows it again on reload
|
||||
```
|
||||
|
||||
## AC-2: Footer Applied to Test SMS
|
||||
```gherkin
|
||||
Given a default SMS footer is configured
|
||||
When operator sends a test SMS from SMSPLANET settings
|
||||
Then the payload sent to SMSPLANET contains the test message with the footer appended exactly once
|
||||
```
|
||||
|
||||
## AC-3: Footer Applied to Order SMS
|
||||
```gherkin
|
||||
Given a default SMS footer is configured
|
||||
When operator sends SMS from the order conversation tab
|
||||
Then SMSPLANET receives the message body with the footer appended and sms_messages stores the final sent body
|
||||
```
|
||||
|
||||
## AC-4: Empty Footer Does Nothing
|
||||
```gherkin
|
||||
Given the default SMS footer is empty
|
||||
When operator sends a test SMS or an order SMS
|
||||
Then the outgoing message body remains unchanged
|
||||
```
|
||||
|
||||
## AC-5: Length Validation Uses Final Body
|
||||
```gherkin
|
||||
Given message text plus configured footer would exceed 918 characters
|
||||
When operator tries to send SMS
|
||||
Then orderPRO rejects the send with a clear validation error before calling SMSPLANET
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Persist SMSPLANET default footer</name>
|
||||
<files>database/migrations/20260512_000111_smsplanet_default_footer.sql, src/Modules/Settings/SmsplanetIntegrationRepository.php, src/Modules/Settings/SmsplanetIntegrationController.php, DOCS/DB_SCHEMA.md, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
|
||||
<action>
|
||||
Add persistence and settings contract:
|
||||
- Create migration adding nullable `default_footer` TEXT column to `smsplanet_integration_settings`.
|
||||
- Make migration idempotent using `information_schema.COLUMNS`, because Phase 121 showed migrations may be retried after partial execution.
|
||||
- Extend `SmsplanetIntegrationRepository::getSettings()` and `getCredentials()` to expose trimmed `default_footer`.
|
||||
- Extend `saveSettings()` to accept and store `default_footer`; normalize line endings, trim surrounding whitespace, allow empty/null.
|
||||
- Validate footer length conservatively (max 300 characters) so the setting cannot consume the whole SMS limit.
|
||||
- Extend `SmsplanetIntegrationController::save()` to pass the new field.
|
||||
- Update DB/architecture/changelog docs with the new column and footer behavior.
|
||||
- Use PDO prepared statements only.
|
||||
</action>
|
||||
<verify>`C:\xampp\php\php.exe -l` on changed PHP files; inspect migration for valid MySQL syntax and idempotent guards.</verify>
|
||||
<done>AC-1 persistence/contract satisfied.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Apply footer to every outbound SMSPLANET send</name>
|
||||
<files>src/Modules/Settings/SmsplanetIntegrationController.php, src/Modules/Sms/SmsConversationService.php, resources/views/orders/show.php, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
|
||||
<action>
|
||||
Apply footer in backend send paths:
|
||||
- Add a small private method in `SmsConversationService` to build the final outbound body from user text plus `credentials['default_footer']`.
|
||||
- Use a blank line separator between message body and footer when footer is non-empty.
|
||||
- Ensure footer is appended exactly once per send operation; do not mutate the stored configuration value.
|
||||
- Validate the final message body length against the existing 918-character limit before calling `SmsplanetApiClient`.
|
||||
- Store the final sent body in `sms_messages.body`, because conversation history should match what customer received.
|
||||
- Apply the same final-body logic in `SmsplanetIntegrationController::test()` before `sendSms()`, with a shared helper if practical without over-abstracting.
|
||||
- Show a compact note in the order SMS form that a configured footer will be added automatically; do not inline CSS.
|
||||
</action>
|
||||
<verify>`C:\xampp\php\php.exe -l` on changed PHP files/views; manually review that SMSPLANET API calls receive final body and no double footer path exists.</verify>
|
||||
<done>AC-2, AC-3, AC-4 and AC-5 satisfied.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Add footer UI and rebuild styles</name>
|
||||
<files>resources/views/settings/smsplanet.php, resources/lang/pl.php, resources/scss/app.scss, public/assets/css/app.css, DOCS/TECH_CHANGELOG.md</files>
|
||||
<action>
|
||||
Add compact UI for footer:
|
||||
- Add textarea in SMSPLANET settings form labeled as default SMS footer.
|
||||
- Keep UI compact and aligned with the existing two-column settings layout.
|
||||
- Add hint explaining that footer is appended to test SMS and order conversation SMS.
|
||||
- Escape all output with `$e()`.
|
||||
- Put any needed layout styling in `resources/scss/app.scss`; do not add inline styles.
|
||||
- Rebuild `public/assets/css/app.css`.
|
||||
</action>
|
||||
<verify>`C:\xampp\php\php.exe -l resources/views/settings/smsplanet.php resources/lang/pl.php`; `npm run build:css`.</verify>
|
||||
<done>AC-1 UI satisfied and compiled CSS updated.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- Do not modify runtime DB host handling; `DB_HOST_REMOTE` remains agent-only for manual DB operations.
|
||||
- Do not alter inbound webhook parsing or phone/order matching except if needed to keep PHP syntax valid.
|
||||
- Do not add native `alert()` or `confirm()`.
|
||||
- Do not inline CSS in views.
|
||||
- Do not add a new SMS provider or change HostedSMS behavior.
|
||||
- Do not implement per-order/per-user footer overrides in this plan.
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Footer is global SMSPLANET-only configuration.
|
||||
- Footer applies only to outbound SMSPLANET sends from settings test and order conversation.
|
||||
- No UI preview/counter is required in this plan unless it is trivial and does not expand scope.
|
||||
- No automatic migration run on production is required during planning; APPLY should attempt migration when environment is available.
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `C:\xampp\php\php.exe -l` passes for changed PHP files and PHP views.
|
||||
- [ ] `npm run build:css` completes.
|
||||
- [ ] Migration applies when DB is available.
|
||||
- [ ] SMSPLANET settings save and reload footer.
|
||||
- [ ] Test SMS uses message plus footer.
|
||||
- [ ] Order SMS uses message plus footer and stores final body.
|
||||
- [ ] Empty footer leaves body unchanged.
|
||||
- [ ] Over-limit final body is rejected before SMSPLANET API call.
|
||||
- [ ] `DOCS/DB_SCHEMA.md`, `DOCS/ARCHITECTURE.md`, `DOCS/TECH_CHANGELOG.md` updated.
|
||||
- [ ] `sonar-scanner` attempted after APPLY; new issues recorded per `.paul/SPECIAL-FLOWS.md` if scan runs.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Operator can configure one persistent SMSPLANET default footer.
|
||||
- Every outbound SMSPLANET message includes the footer exactly once when configured.
|
||||
- History stores the actual final sent SMS body.
|
||||
- Existing sender mode, inbound webhook and notification behavior remain unchanged.
|
||||
- Verification passes or environment-specific gaps are documented in SUMMARY.md.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/122-smsplanet-default-sms-footer/122-01-SUMMARY.md`.
|
||||
</output>
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
phase: 122-smsplanet-default-sms-footer
|
||||
plan: 01
|
||||
status: applied
|
||||
applied_at: 2026-05-12 21:25:00
|
||||
---
|
||||
|
||||
# APPLY Summary - Phase 122 Plan 01
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
- Task 1: Persist SMSPLANET default footer - PASS
|
||||
- Task 2: Apply footer to every outbound SMSPLANET send - PASS
|
||||
- Task 3: Add footer UI and rebuild styles - PASS
|
||||
|
||||
## Implemented
|
||||
|
||||
- Added `database/migrations/20260512_000111_smsplanet_default_footer.sql` with idempotent `information_schema.COLUMNS` guard for `smsplanet_integration_settings.default_footer`.
|
||||
- Extended `SmsplanetIntegrationRepository` to expose, validate, normalize, persist, and return `default_footer`.
|
||||
- Extended SMSPLANET settings save/test flow so test SMS uses final body with footer and validates the final body against 918 characters.
|
||||
- Extended `SmsConversationService` so order SMS uses final body with footer, stores final body in `sms_messages.body`, and rejects over-limit final body before API call.
|
||||
- Added SMSPLANET settings textarea and compact order SMS note when a footer is configured.
|
||||
- Updated `DOCS/DB_SCHEMA.md`, `DOCS/ARCHITECTURE.md`, `DOCS/TECH_CHANGELOG.md`, and PAUL codebase docs.
|
||||
|
||||
## Verification
|
||||
|
||||
- `C:\xampp\php\php.exe -l src/Modules/Settings/SmsplanetIntegrationRepository.php` - PASS
|
||||
- `C:\xampp\php\php.exe -l src/Modules/Settings/SmsplanetIntegrationController.php` - PASS
|
||||
- `C:\xampp\php\php.exe -l src/Modules/Sms/SmsConversationService.php` - PASS
|
||||
- `C:\xampp\php\php.exe -l src/Modules/Orders/OrdersController.php` - PASS
|
||||
- `C:\xampp\php\php.exe -l resources/views/settings/smsplanet.php` - PASS
|
||||
- `C:\xampp\php\php.exe -l resources/views/orders/show.php` - PASS
|
||||
- `C:\xampp\php\php.exe -l resources/lang/pl.php` - PASS
|
||||
- `npm run build:css` - PASS
|
||||
- `C:\xampp\php\php.exe bin\migrate.php` with standard `DB_HOST=localhost` - FAIL, local MySQL refused connection.
|
||||
- Manual migration run with process-only `DB_HOST=DB_HOST_REMOTE` - PASS, `[ok] 20260512_000111_smsplanet_default_footer.sql`.
|
||||
- `information_schema.COLUMNS` check for `default_footer` - PASS (`TEXT`, nullable).
|
||||
- `sonar-scanner` - FAIL, CLI not available in PATH.
|
||||
|
||||
## Manual Gaps
|
||||
|
||||
- Real SMSPLANET test send with configured footer not executed in browser.
|
||||
- Order conversation SMS send with configured footer not executed in browser.
|
||||
- Empty-footer send path not manually exercised in browser.
|
||||
- Over-limit final body rejection reviewed in code but not manually triggered through UI.
|
||||
|
||||
## Deviations
|
||||
|
||||
- No functional deviation from plan.
|
||||
- SonarQube scan could not run because `sonar-scanner` is not installed or not in PATH.
|
||||
Reference in New Issue
Block a user