Agentic Outbound Zalo OA Marketing Execution Engine
Summary
This plan defines the v2.0 Beta path for a complete marketer workflow:
- Select a segment by
segment_idfrom PostgreSQL and sync matched profiles with phone identity into the correct CRM routes. - Create Zalo OA message template drafts with AI agents (Gemini or OpenAI) and human review.
- Create campaign drafts with AI strategy, schedule, and content plan, then require human approval before run.
Final business outcome:
Segment → CRM sync routing → Phone eligibility filter → AI Zalo template draft → AI campaign draft → Human approval → Dispatch → Track → Feedback into Customer 360.
Verified Ground Truth (Repo Audit)
Database schema reality (database-init/database-schema.sql)
cdp_segmentsexists and supports segment selection bysegment_id.cdp_master_profilesexists with lifecycle, contact, and personalization attributes used for targeting.- CRM entities exist and can anchor channel-level campaign execution:
crm_campaigncrm_campaign_membercrm_campaign_performance_dailycrm_contactcrm_leadcrm_lead_sourcecrm_customer_contactscrm_transactions
cdp_content_itemsexists and can provide message content inventory.
Schema gaps that must be addressed in this story:
- No dedicated
crm_zalo_templatestable exists. - No dedicated
crm_zalo_oa_accountstable exists. - No dedicated Zalo dispatch log table exists.
- No dedicated Zalo opt-out/suppression table exists.
- No explicit campaign linkage for Zalo template/account/channel config exists on
crm_campaign.
Service and orchestration reality
Implemented and active Dagster services:
identity_resolution(identity_resolution_job+ sensor)segmentation(segmentation_job+ change-driven polling sensor)analytics(analytics_job+ hourly schedule)
Placeholders (log + sleep only):
campaign_activationnotification_enginedata_synchemail_enginescoringpersonalization
Implication: this story must convert campaign_activation and notification_engine into real Zalo OA execution jobs, while reusing segmentation and analytics.
Target Marketer Flow (Required)
- Marketer selects
segment_id. - System recomputes segment membership and freezes run snapshot.
- System syncs matched profiles to CRM by lifecycle routing rules:
- Customer route: write/update
crm_customer_contactsandcrm_transactions. - Lead route: write/update
crm_leadandcrm_lead_source. - Contact route (not customer and not lead): write/update
crm_contact.
- Customer route: write/update
- System filters Zalo-eligible recipients (valid phone, consented, not suppressed).
- AI agent creates Zalo OA message template draft (Gemini or OpenAI).
- AI agent creates campaign draft in
crm_campaignwith objective,start_date,end_date, and linked content fromcdp_content_items. - Human review/approval gate moves campaign from
Draftto executable states. - Dispatch runs through Zalo OA adapters; delivery/read/click feedback is normalized into Customer 360 analytics.
Story-level Acceptance Criteria
- Segment can be selected by
segment_idand recomputed before channel dispatch. - Routing rules are enforced exactly:
customer→crm_customer_contacts+crm_transactionslead→crm_lead+crm_lead_source- neither
customernorlead→crm_contact
- Zalo eligibility filters enforce valid phone, consent, and suppression rules.
- AI can produce Zalo template drafts using Gemini or OpenAI.
- AI can produce campaign drafts with objective, schedule, and content plan.
- Campaigns created by AI remain
Draftuntil explicit human approval. - Dispatch and callback ingestion are auditable, idempotent, tenant-safe, and retry-safe.
- E2E automation follows simulator verification patterns and includes API + DB dual checks.
Subtasks (P0 Sprint - 8 Blockers)
SUBTASK-01: Schema and Migration Foundation for Zalo OA
Component: database-init/migrations
Priority: P0 Blocker
Depends on: none
Blocks: SUBTASK-02..08
Estimate: 5 pts
Description
Add missing relational structure for Zalo template lifecycle, account linkage, and dispatch traceability.
Scope of Work
- Create
crm_zalo_templatestable with at least:template_id,tenant_id,name,message_text,variables,status,created_by,approved_by,approved_at,metadata.
- Create
crm_zalo_oa_accountstable with:oa_account_id,tenant_id,oa_name,oa_id,status,config,metadata.
- Create
crm_zalo_dispatch_logstable with:dispatch_id,tenant_id,campaign_id,master_profile_id,phone_hash,provider_message_id,status,sent_at,delivered_at,read_at,error_code,metadata.
- Create
crm_zalo_suppressiontable with:suppression_id,tenant_id,phone_hash,reason,source,created_at,metadata.
- Extend
crm_campaignwith:segment_idFK →cdp_segments.segment_idzalo_template_idFK →crm_zalo_templates.template_idoa_account_idFK →crm_zalo_oa_accounts.oa_account_idapproval_status(Draft,InReview,Approved,Rejected)approved_by,approved_atstrategy_summaryand optionalai_plan.
- Add campaign-content relation table
crm_campaign_content_itemsif not present. - Add sync-run audit table
crm_zalo_sync_runswith per-route and eligibility counts. - Add/extend indexes and RLS policies for all new tenant-scoped tables.
Acceptance Criteria
- Migrations apply and rollback cleanly.
- New FKs enforce campaign-template-account integrity.
- RLS policies exist for all new tenant-scoped tables.
- SQLAlchemy models and Pydantic schemas are updated.
Definition of Done
Schema supports deterministic Zalo OA workflow with governance and dispatch observability.
SUBTASK-02: Segment-ID Driven CRM Sync and Zalo Eligibility
Component: customer360-api/core + backend-system/data_synch
Priority: P0 Blocker
Depends on: SUBTASK-01
Blocks: SUBTASK-03, SUBTASK-05, SUBTASK-08
Estimate: 8 pts
Description
Implement selected-segment sync and recipient eligibility for Zalo OA activation.
Scope of Work
- API endpoint to trigger one-segment Zalo sync run:
POST /api/v1/admin/zalo/sync-segment/{segment_id}- optional dry-run mode returning route and eligibility counts only.
- Recompute selected segment and resolve members from
cdp_master_profiles. - Enforce lifecycle routing into CRM tables:
- Route A:
customer→crm_customer_contacts+crm_transactions - Route B:
lead→crm_lead+crm_lead_source - Route C: non-customer/non-lead →
crm_contact
- Route A:
- Apply Zalo eligibility filters:
- valid normalized phone
- consent/opt-in enabled
- not in
crm_zalo_suppression
- Persist run record in
crm_zalo_sync_runs. - Guarantee idempotent rerun behavior.
Acceptance Criteria
- One selected
segment_idsyncs with deterministic per-route counts. - Zalo eligibility and suppression filters are consistently applied.
- Sync run data is tenant-safe and auditable.
Definition of Done
Marketer can select one segment and produce a deterministic Zalo-eligible audience.
SUBTASK-03: AI Zalo Template Authoring (Gemini/OpenAI)
Component: customer360-api/core + backend-system/notification_engine
Priority: P0 Blocker
Depends on: SUBTASK-01, SUBTASK-02
Blocks: SUBTASK-04, SUBTASK-05, SUBTASK-08
Estimate: 5 pts
Description
Create AI-assisted Zalo message template drafts with compliance guardrails and human governance.
Scope of Work
- Add template generation endpoint/service with provider selection:
- Gemini provider
- OpenAI-compatible provider
- Input contract includes:
- segment context
- objective and offer
- tone/brand constraints
- locale/language
- AI output generates:
- message text variants
- CTA text variants
- required variables and short links placeholders
- Save drafts in
crm_zalo_templateswithDraftstatus. - Add review API: approve/reject/edit template before campaign use.
- Add safety checks: policy keywords, forbidden claims, length limits.
Acceptance Criteria
- Zalo template drafts can be generated through Gemini or OpenAI path.
- Draft templates are persisted and versionable.
- Human approval is mandatory before template can be attached to a runnable campaign.
Definition of Done
AI Zalo template generation works with enforceable governance.
SUBTASK-04: AI Campaign Strategy and Draft Creation (Zalo OA)
Component: customer360-api/core + backend-system/campaign_orchestration
Priority: P0 Blocker
Depends on: SUBTASK-01, SUBTASK-02, SUBTASK-03
Blocks: SUBTASK-05, SUBTASK-08
Estimate: 8 pts
Description
AI should produce Zalo campaign drafts with strategy, schedule, and content linkage; humans must approve before activation.
Scope of Work
- Add campaign planning endpoint/service that takes:
segment_id- approved
zalo_template_id - selected
oa_account_id - objective and schedule constraints
- AI proposes:
- campaign name and objective
- strategy summary
- schedule window (
start_date,end_date) - recommended content set from
cdp_content_items
- Create campaign row in
crm_campaignwith:- status
Draft - approval status
InReview - linked
segment_id,zalo_template_id,oa_account_id
- status
- Persist content links in
crm_campaign_content_items. - Enforce state machine:
- AI can create only
Draft - only authorized human can approve and transition to
Scheduled/Running
- AI can create only
Acceptance Criteria
- AI campaign drafts include objective, schedule, and content plan.
- Draft campaigns cannot run without human approval.
- State transitions are validated and audited.
Definition of Done
AI can prepare complete Zalo campaign drafts while human approval remains mandatory.
SUBTASK-05: Dagster Execution Modernization (Campaign + Notification)
Component: backend-system/campaign_activation + backend-system/notification_engine
Priority: P0 Blocker
Depends on: SUBTASK-02, SUBTASK-03, SUBTASK-04
Blocks: SUBTASK-06, SUBTASK-08
Estimate: 8 pts
Description
Replace placeholders with real orchestration for Zalo OA dispatch.
Scope of Work
- Replace
campaign_activation_jobplaceholder with real orchestration:- validate approval status
- load campaign, template, and eligible audience snapshot
- trigger notification dispatch
- Replace
notification_engine_jobplaceholder with real send pipeline:- render final message payload
- dispatch through Zalo OA adapter
- persist send attempts to
crm_zalo_dispatch_logs
- Integrate with existing real services:
- use
segmentation_joboutputs for selected segment freshness - preserve compatibility with
analytics_jobdownstream verification
- use
- Keep unrelated placeholder services out of this sprint scope.
Acceptance Criteria
campaign_activationandnotification_enginerun real logic, not sleep placeholders.- Dispatch runs are observable, retry-safe, and idempotent.
- Per-recipient send results are auditable.
Definition of Done
Zalo OA execution path is production-like and orchestrated via real jobs.
SUBTASK-06: Zalo Webhooks, Compliance, and Suppression Feedback
Component: customer360-api/core/routers + data-tracking-api
Priority: P0 Blocker
Depends on: SUBTASK-05
Blocks: SUBTASK-07, SUBTASK-08
Estimate: 5 pts
Description
Capture delivery/read/click/unfollow events and keep suppression/compliance state consistent.
Scope of Work
- Add webhook endpoints for Zalo OA callbacks (delivered/read/click/failure/opt-out).
- Correlate events to
campaign_id,provider_message_id, and profile identity when available. - Normalize to canonical event contracts and update suppression on explicit opt-out or policy events.
- Deduplicate repeated callbacks and verify webhook signatures.
Acceptance Criteria
- Webhook events are captured with correct campaign/message correlation.
- Opt-out and failure events update suppression eligibility correctly.
- Duplicate callbacks do not inflate metrics.
Definition of Done
Closed-loop callback handling and suppression updates are operational.
SUBTASK-07: Customer 360 Feedback and Zalo Performance Rollups
Component: backend-system/analytics + customer360-api
Priority: P0 Blocker
Depends on: SUBTASK-06
Blocks: SUBTASK-08
Estimate: 5 pts
Description
Ensure Zalo engagement updates profile intelligence and campaign metrics.
Scope of Work
- Update profile touchpoint timestamps from Zalo events.
- Trigger segmentation refresh behavior after relevant profile updates.
- Roll up Zalo metrics into campaign performance surfaces.
- Keep tenant-safe and auditable data changes.
Acceptance Criteria
- Profile timestamps update correctly after sent/delivered/read/click events.
- Segment refresh is triggered by relevant profile changes.
- Campaign performance views include Zalo channel metrics.
Definition of Done
Zalo engagement data becomes actionable inside profile and campaign analytics.
SUBTASK-08: End-to-End Automated Test Suite (Learn from Simulator)
Component: cross-cutting (all-data-simulator, backend-system, customer360-api)
Priority: P0 Blocker (Beta Gate)
Depends on: SUBTASK-01..07
Estimate: 8 pts
Description
Build a full E2E suite based on proven simulator patterns from:
all-data-simulator/web_user_simulator.pyall-data-simulator/test_web_user_simulator.pyall-data-simulator/run_tracking_analytics_e2e.sh
Required E2E sequence
Select Segment ID → Sync to CRM routes → Filter Zalo-eligible recipients → Generate AI Zalo Template Draft → Generate AI Campaign Draft → Human Approve → Dispatch (mock OA adapter) → Simulate Webhooks → Verify profile and campaign metrics.
Scope of Work
Phase A - Harness baseline
- Reuse contract-check client pattern (request/response strict assertions).
- Reuse deterministic fixture strategy.
- Reuse bounded polling and timeout handling pattern.
- Reuse dual verification pattern (API result + direct PostgreSQL query).
Phase B - CRM routing and eligibility assertions
- For one selected
segment_id, assert lifecycle routing tables receive expected rows. - Assert phone eligibility and suppression filters are deterministic.
Phase C - AI draft and approval assertions
- Assert AI template is created as draft.
- Assert AI campaign is created as draft with objective, strategy, and start/end date.
- Assert campaign cannot run until human approval is recorded.
Phase D - Dispatch and webhook assertions
- Mock dispatch path writes one record per eligible recipient.
- Webhook simulation updates event facts and suppression state.
- Idempotency and retry paths validated.
Phase E - Feedback and analytics assertions
- Verify profile timestamp changes and campaign metric updates.
- Validate API summary and direct DB values agree.
Phase F - CI release gate
- Required CI check for Beta.
- Separate fast PR smoke and full nightly profiles.
- Emit actionable failure artifacts.
Acceptance Criteria
- Full required sequence passes with deterministic fixtures.
- CRM routing and Zalo eligibility behavior are verified exactly.
- AI draft + human approval gate is verified.
- Dispatch/webhook/feedback loop is verified.
- CI gate is green and enforced for release.
Definition of Done
Objective evidence exists that the complete Zalo OA workflow works end to end and follows repository-proven test patterns.
Technical Execution Checklist (Epic Gate)
Use this checklist as the implementation tracker for all technical tasks in this epic.
A. Task Naming Convention Checklist
- All sprint tasks use
SUBTASK-XX: <Action + Domain>format. - API route handlers use
verb_noun_scopenaming (example:sync_segment_zalo). - Service methods use
action_domain_objectnaming (example:generate_zalo_campaign_draft). - Dagster assets/ops/jobs use explicit domain prefixes (example:
zalo_sync_*,zalo_dispatch_*,campaign_*). - New PostgreSQL tables follow module prefix rules:
- CRM module tables use
crm_*. - CDP module tables use
cdp_*. - System tables use
sys_*.
- CRM module tables use
- New environment variables for this epic use
CRM_ZALO_*plus provider-specific standard names.
B. PostgreSQL Data Tables Checklist
- Create
crm_zalo_templatestable with message payload, variables, approvals, metadata, andtenant_id. - Create
crm_zalo_oa_accountstable for account-level dispatch configuration. - Create
crm_zalo_dispatch_logstable for message-level delivery lifecycle. - Create
crm_zalo_suppressiontable for opt-out/failure-based suppression state. - Alter
crm_campaignto addsegment_id,zalo_template_id,oa_account_id, approval fields, and AI planning fields. - Create
crm_campaign_content_itemsrelation table if not already available. - Create
crm_zalo_sync_runsaudit table. - Add FK constraints for all cross-table relationships.
- Add unique constraints for idempotency-sensitive entities.
- Add tenant-aware indexes for query hot paths.
- Add or update RLS policies for all new tenant-scoped tables.
- Add forward and rollback migration scripts and verify both directions.
C. Backend Tasks Checklist
- Implement
POST /api/v1/admin/zalo/sync-segment/{segment_id}with optional dry-run. - Recompute segment membership before sync and persist run metrics.
- Implement lifecycle routing logic exactly:
customer→crm_customer_contactsandcrm_transactionslead→crm_leadandcrm_lead_source- non-customer and non-lead →
crm_contact
- Implement recipient eligibility filters (valid phone, consent, suppression).
- Implement idempotent upsert logic for sync targets and dispatch writes.
- Implement AI template draft generation with provider switch (
gemini/openai). - Implement template review APIs (
approve,reject,edit) and enforce approval requirement. - Implement AI campaign draft creation with objective, strategy, schedule, and content linkage.
- Enforce campaign state machine so AI-created campaigns remain
Draftuntil human approval. - Replace
campaign_activationplaceholder with real execution flow. - Replace
notification_engineplaceholder with real Zalo OA dispatch flow. - Implement Zalo webhook ingestion, signature validation, and dedup handling.
- Implement suppression updates and performance rollup updates.
- Add E2E automation that follows simulator pattern.
D. Required Environment Config Checklist
- Define AI provider selector:
CRM_ZALO_AI_PROVIDER(openaiorgemini)
- Define OpenAI credentials/config when provider is OpenAI:
OPENAI_API_KEYOPENAI_MODEL
- Define Gemini credentials/config when provider is Gemini:
GEMINI_API_KEYGEMINI_MODEL
- Define Zalo OA credentials/config:
CRM_ZALO_OA_APP_IDCRM_ZALO_OA_APP_SECRETCRM_ZALO_OA_ACCESS_TOKENCRM_ZALO_OA_REFRESH_TOKENCRM_ZALO_OA_API_BASE_URL
- Define sender and compliance defaults:
CRM_ZALO_BRAND_NAMECRM_ZALO_TRACKING_BASE_URLCRM_ZALO_UNSUBSCRIBE_BASE_URL
- Define runtime controls:
CRM_ZALO_BATCH_SIZECRM_ZALO_RATE_LIMIT_PER_SECCRM_ZALO_MAX_RETRIESCRM_ZALO_RETRY_BACKOFF_MS
- Define webhook security values:
CRM_ZALO_WEBHOOK_SIGNING_SECRET
- Ensure values exist in
.env.exampleand active environment files used by services.
E. Definition of Ready and Done Checklist
- Ready: all required schema migrations are reviewed before backend implementation starts.
- Ready: all required environment keys are documented and available in deployment manifests.
- Done: unit tests pass for services, repositories, and routers touched by this epic.
- Done: E2E workflow passes from segment sync to approved Zalo dispatch and feedback updates.
- Done: audit logs and tenant-isolation behavior are verified for all new flows.
Out of Scope (v2.1+)
- Advanced conversation bot flows beyond campaign messaging.
- Multi-touch cross-channel attribution optimization loops.
- Autonomous send-time optimization without human override.
- Full modernization of unrelated placeholder services.
Non-Functional Requirements (Beta Gates)
- Tenant isolation and RLS safety.
- SQL safety for generated filters and dynamic queries.
- Audit logging for sync, template generation, approval, dispatch, and webhook actions.
- Secrets management for AI and Zalo OA credentials.
- Retry, idempotency, and circuit-breaker controls for dispatch workflows.