Skip to main content

Sync crm_data_id back to CDP for CDP-originated contacts (Qontak One)

Jira Story: TF-3551 · Task: TF-3517 (linked via "Work item split", corrected direction verified) · Epic: TF-3500 (bucket item A6, CDP 26Q3 Engineering Initiatives — re-homed from TF-3477 on 2026-07-21) · Sibling: TF-3526 (chat_data, same root cause → prd)

Overview

When a user creates a contact from CDP, CDP pushes to CRM to create the matching CRM contact — but CRM publishes nothing back carrying the newly created CRM contact id, so on the CDP side contact.crm_data.id stays null/empty for every CDP-originated contact. The BI team reports widespread null/empty crm_data_id for Qontak One clients' CDP-created customers, breaking downstream CRM ⇄ CDP association. The field is only populated on the CRM→CDP sync path (contact-service/internal/app/payload/contact_sync_request.go:105), which never fires for CDP-originated contacts.

Fix (per TF-3517): CRM (qontak.com) publishes a reciprocal event after creating a CDP-originated contact — carrying crm_data_id, qontak_customer_id, and company_sso_id — gated to Qontak One tenants (unified_app = TRUE); CDP (contact-service) consumes it and sets contact.crm_data.id, idempotently.

Open transport question: the Jira description proposes a new Kafka topic + CDP consumer, but the team discussion (2026-07-17, Berlianto/Julio/Puji) converged on API/webhook over Kafka ("overkill" since only CDP consumes it), and the sibling TF-3526 was subsequently revised to reuse the existing /contacts/create sync webhook. TF-3517's transport should be re-decided against that precedent before build starts — including whether it shares TF-3526's DefineTarget duplicate-contact risk.

Scope Changes

  • Backend — CRM publish-back of crm_data_id (qontak.com) + CDP ingestion into contact.crm_data.id (contact-service). Qontak One tenants only; CRM-originated contacts unchanged.

8. User Stories + Acceptance Criteria

User StoryImportanceMockup / Technical NotesAcceptance Criteria
[CRMSYNC-S01] — CDP-originated contacts get their CRM id linked back

As the platform, I want CRM to send the created crm_data_id back to CDP whenever a Qontak One contact is created from CDP, so that CDP-originated contacts are fully associated with their CRM record and BI/downstream joins stop seeing null crm_data_id.
Must HavePublisher gated by Team#unified_app? via Billing::GetSubscriptionDetail (qontak.com/app/models/team.rb:498-511). CDP write reuses the existing CrmData{ID} path (contact_sync_request.go:105). Transport (Kafka vs webhook) to be settled per the Overview note.— Happy Path —
• AC-1: Given a Qontak One tenant, when a contact is created from CDP, then CRM sends back crm_data_id + qontak_customer_id + company_sso_id and CDP sets contact.crm_data.id to the CRM contact id (no longer null/empty).
• AC-2: Given a CRM-originated contact, when it syncs to CDP, then behaviour is unchanged (existing sync path untouched).
— Guard-rail —
• NEG-1: Given a non-Qontak-One tenant, when a contact is created from CDP, then no publish-back occurs and behaviour is unchanged.
• NEG-2: Given a duplicate/replayed event for a contact whose crm_data.id is already set, when it is consumed, then CDP no-ops (never overwrites with a different id; logs a warning).

Verification

Not started — TF-3517 is To Do as of 2026-07-21; CDP-side BE owner is Julio Jeffer (assigned on the board 2026-07-21). Sequenced in Sprint 2 directly under his Customer Segmentation P1 close-out. Cross-team: CRM squad owns the publish side; CDP squad owns the ingestion side. Contract (transport + payload schema) must be agreed and documented before build.