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>
183 lines
8.4 KiB
Markdown
183 lines
8.4 KiB
Markdown
---
|
|
phase: 121-smsplanet-conversation-notifications
|
|
plan: 01
|
|
subsystem: sms
|
|
tags: [smsplanet, sms, webhook, notifications, polling]
|
|
|
|
requires:
|
|
- phase: 117-smsplanet-integration-settings
|
|
provides: SMSPLANET credentials, API client and settings page
|
|
provides:
|
|
- SMSPLANET inbound webhook
|
|
- Order SMS conversation tab
|
|
- Global notification center and unread polling API
|
|
- SMSPLANET sender mode selection for text sender or 2WAY number
|
|
affects: [smsplanet, orders, notifications]
|
|
|
|
tech-stack:
|
|
added: []
|
|
patterns: [PDO repositories, manual route wiring, vanilla JS polling]
|
|
|
|
key-files:
|
|
created:
|
|
- database/migrations/20260512_000110_smsplanet_conversation_notifications.sql
|
|
- src/Modules/Sms/SmsMessageRepository.php
|
|
- src/Modules/Sms/SmsConversationService.php
|
|
- src/Modules/Sms/SmsplanetWebhookController.php
|
|
- src/Modules/Notifications/NotificationRepository.php
|
|
- src/Modules/Notifications/NotificationController.php
|
|
- src/Modules/Notifications/NotificationApiController.php
|
|
- resources/views/notifications/index.php
|
|
- public/assets/js/modules/notifications.js
|
|
modified:
|
|
- src/Modules/Settings/SmsplanetIntegrationRepository.php
|
|
- src/Modules/Settings/SmsplanetIntegrationController.php
|
|
- src/Modules/Orders/OrdersController.php
|
|
- routes/web.php
|
|
- resources/views/settings/smsplanet.php
|
|
- resources/views/orders/show.php
|
|
- resources/views/layouts/app.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
|
|
|
|
key-decisions:
|
|
- "Inbound SMS matching uses the latest order by normalized phone number."
|
|
- "Webhook signature validation remains out of scope for this phase."
|
|
- "Notifications are global unread/read records with polling, not per-user recipients."
|
|
|
|
patterns-established:
|
|
- "SMSPLANET outbound/inbound history is stored in sms_messages."
|
|
- "Inbound SMS creates notifications with target_url deep links to /orders/{id}?tab=sms."
|
|
|
|
duration: ~65min
|
|
started: 2026-05-12T19:20:00+02:00
|
|
completed: 2026-05-12T20:35:00+02:00
|
|
---
|
|
|
|
# Phase 121 Plan 01: SMSPLANET Conversation + Notifications Summary
|
|
|
|
Dwukierunkowa komunikacja SMSPLANET została podłączona do zamówień, a przychodzące SMS tworzą globalne powiadomienia.
|
|
|
|
## Performance
|
|
|
|
| Metric | Value |
|
|
|--------|-------|
|
|
| Duration | ~65min |
|
|
| Started | 2026-05-12 19:20 |
|
|
| Completed | 2026-05-12 20:35 |
|
|
| Tasks | 3 completed |
|
|
| Files modified | 20+ |
|
|
|
|
## Acceptance Criteria Results
|
|
|
|
| Criterion | Status | Notes |
|
|
|-----------|--------|-------|
|
|
| AC-1: SMSPLANET Sender Mode | Pass | Settings store `sender_mode`, text sender and 2WAY phone separately. |
|
|
| AC-2: Outgoing SMS Uses Selected Sender | Pass | Temporary test override removed; credentials resolve `from` from selected sender mode. |
|
|
| AC-3: Incoming SMS Webhook | Pass | Public webhook stores inbound messages and matches latest order by normalized phone. |
|
|
| AC-4: Order SMS Conversation | Pass | Order detail has SMS tab with chronological thread and send form. |
|
|
| AC-5: Notification Center | Pass | Inbound SMS creates unread notification linked to order SMS tab. |
|
|
| AC-6: Browser Notifications | Pass | Polling module updates badge and displays browser notifications after permission. |
|
|
|
|
## Accomplishments
|
|
|
|
- Added SMSPLANET conversation persistence in `sms_messages`.
|
|
- Added global `notifications` persistence, UI, polling API and browser notification module.
|
|
- Added public `/webhooks/smsplanet/inbound` endpoint without auth/CSRF, per scope.
|
|
- Added SMS tab and `/orders/{id}/sms/send` flow for order-level SMS replies.
|
|
- Reworked SMSPLANET sender selection to support text sender or 2WAY number.
|
|
|
|
## Verification Results
|
|
|
|
| Check | Result |
|
|
|-------|--------|
|
|
| `C:\xampp\php\php.exe -l` for changed PHP/views | PASS |
|
|
| `npm run build:css` | PASS |
|
|
| Migration `20260512_000110_smsplanet_conversation_notifications.sql` | PASS via technical `DB_HOST_REMOTE` |
|
|
| `sonar-scanner` | BLOCKED: CLI not available in PATH |
|
|
| Manual webhook/order/browser checks | PENDING: requires browser session and live SMSPLANET callback/test |
|
|
|
|
## Files Created/Modified
|
|
|
|
| File | Change | Purpose |
|
|
|------|--------|---------|
|
|
| `database/migrations/20260512_000110_smsplanet_conversation_notifications.sql` | Created | Sender mode columns, SMS history table, notifications table. |
|
|
| `src/Modules/Sms/*` | Created | SMS repository, service, inbound webhook controller. |
|
|
| `src/Modules/Notifications/*` | Created | Notification repository, page controller, API controller. |
|
|
| `src/Modules/Settings/SmsplanetIntegrationRepository.php` | Modified | Stores sender mode/2WAY phone and resolves API sender. |
|
|
| `src/Modules/Orders/OrdersController.php` | Modified | Loads SMS history and sends outbound SMS from order. |
|
|
| `routes/web.php` | Modified | Wires SMS, webhook and notification routes/services. |
|
|
| `resources/views/settings/smsplanet.php` | Modified | Adds sender mode and 2WAY number controls. |
|
|
| `resources/views/orders/show.php` | Modified | Adds SMS tab and send form. |
|
|
| `resources/views/notifications/index.php` | Created | Notification center. |
|
|
| `resources/views/layouts/app.php` | Modified | Adds topbar notification badge and JS module. |
|
|
| `resources/scss/app.scss`, `public/assets/css/app.css` | Modified | Styles for SMS thread, notifications and topbar badge. |
|
|
| `DOCS/*`, `.paul/codebase/*` | Modified | Technical documentation updated. |
|
|
|
|
## Decisions Made
|
|
|
|
| Decision | Rationale | Impact |
|
|
|----------|-----------|--------|
|
|
| Match inbound SMS to latest order by phone | User clarified this during planning. | No order-code parser needed. |
|
|
| No webhook signature validation | User clarified "na razie bez podpisu". | Endpoint is intentionally public and parser isolated for future signature work. |
|
|
| Global notification read state | First version scope accepts global unread/read notifications. | No per-user notification recipient model yet. |
|
|
| Use polling | User clarified polling is acceptable. | No WebSocket/SSE infrastructure. |
|
|
|
|
## Deviations from Plan
|
|
|
|
### Summary
|
|
|
|
| Type | Count | Impact |
|
|
|------|-------|--------|
|
|
| Auto-fixed | 2 | Migration made compatible with real DB and idempotent after partial first attempt. |
|
|
| Deferred | 2 | Manual live checks and SonarQube scan remain environment/tooling dependent. |
|
|
|
|
### Auto-fixed Issues
|
|
|
|
**1. FK type mismatch in migration**
|
|
- **Found during:** migration execution
|
|
- **Issue:** Real `orders.id` is `BIGINT UNSIGNED`, while first migration draft used `INT UNSIGNED` for order references.
|
|
- **Fix:** Changed `sms_messages.order_id` and `notifications.related_order_id` to `BIGINT UNSIGNED`.
|
|
- **Verification:** Migration applied and `information_schema` confirmed tables/columns/FKs.
|
|
|
|
**2. Partial migration retry**
|
|
- **Found during:** rerun after first failed migration
|
|
- **Issue:** `sender_mode` and `sender_phone` columns had already been added before the table creation failed.
|
|
- **Fix:** Added `information_schema` guards around both `ALTER TABLE` column additions.
|
|
- **Verification:** Migration reran successfully.
|
|
|
|
### Deferred Items
|
|
|
|
- Manual live verification of SMSPLANET webhook, order SMS tab, notification polling and browser notification behavior.
|
|
- SonarQube scan because `sonar-scanner` is not available in PATH.
|
|
- Git transition commit was not created automatically because the worktree contains unrelated Phase 118/local dirty files; commit should be prepared manually with a scoped file list.
|
|
|
|
## Issues Encountered
|
|
|
|
| Issue | Resolution |
|
|
|-------|------------|
|
|
| Local MySQL refused connection during first verification | Used technical `DB_HOST_REMOTE` for manual migration operation, per project rules for agent-only DB work. |
|
|
| `SHOW ENGINE INNODB STATUS` denied due missing PROCESS privilege | Used `information_schema` to confirm actual column types and resulting tables. |
|
|
| `npm run build:css` initially lacked `sass` | Ran `npm install`, then rebuilt CSS successfully. |
|
|
|
|
## Next Phase Readiness
|
|
|
|
**Ready:**
|
|
- SMSPLANET settings, send flow, webhook, SMS tab and notification center can be extended.
|
|
- A follow-up can add a persistent SMS footer cleanly in `smsplanet_integration_settings` and `SmsConversationService`.
|
|
|
|
**Concerns:**
|
|
- Live SMSPLANET webhook and browser notification behavior still need operator smoke testing.
|
|
- `sonar-scanner` remains unavailable in PATH.
|
|
|
|
**Blockers:**
|
|
- None for planning the SMS footer follow-up.
|
|
|
|
---
|
|
*Phase: 121-smsplanet-conversation-notifications, Plan: 01*
|
|
*Completed: 2026-05-12*
|