feat: SMS campaigns for people or leads with filters and batching

Add audience tabs, province/city filters, select-all ids, dynamic SMS tokens, and 50-sized create/send chunks.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-17 20:54:32 +03:30
co-authored by Cursor
parent 32c722f42a
commit d62e004e90
10 changed files with 1040 additions and 131 deletions
@@ -0,0 +1,51 @@
# SMS Campaign People/Leads Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** SMS campaigns support people-only or leads-only audiences with full filters, select-all-ids, dynamic field tokens, and 50-sized create/send batches.
**Architecture:** Extend people/leads list filters + `/ids` endpoints; expand sms-campaigns create/add-recipients; personalize body via `renderSmsText` then tracking links; rebuild `SmsCampaignsView` with tabs, filters, and chunked create.
**Tech Stack:** NestJS/Prisma, Vue 3, `@mento/shared`, existing MESSAGE_AUTOMATION_FIELDS / renderSmsText.
## Global Constraints
- One campaign = people XOR leads
- Select-all = all filter matches (confirm count)
- Batch size 50 for create chunks and send cron
- People province/city via company (+ addresses search)
- Dynamic tokens: `{نام}` `{شماره}` `{تاریخ}` `{عنوان}` `{شرکت}`
- Spec: `docs/superpowers/specs/2026-10-17-sms-campaign-people-leads-design.md`
---
### Task 1: Shared types
- [ ] Extend `CreateSmsCampaignRequest` with optional `leadIds`; document XOR
- [ ] Add `AddSmsCampaignRecipientsRequest`, `FilteredIdsResponse`
- [ ] Export constants if needed (`SMS_CAMPAIGN_CHUNK = 50`)
### Task 2: People filters + ids
- [ ] `PeopleService.list` / `listIds`: `province`, `city` on company; address contains
- [ ] Controller query + `GET /people/ids` with 50k cap
### Task 3: Leads ids + region filter
- [ ] Ensure list supports `region`; add `GET /leads/ids`
### Task 4: SMS campaigns API
- [ ] Create with personIds XOR leadIds (max 50 first chunk; force draft if more planned via `queueNow` deferred to client)
- [ ] `POST :id/recipients`
- [ ] Batch send 50 + `renderSmsText` before personalizeSmsBody
### Task 5: Frontend SmsCampaignsView
- [ ] Tabs people/leads, filters, pagination, select-all via /ids
- [ ] Dynamic fields pill
- [ ] Chunked create then optional queue
### Task 6: Verify
- [ ] shared build + api tsc/tests relevant; graphify update