---
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>
