Batch 7.3: Upsert Strategy for Duplicate Leads #77

Closed
opened 2026-05-17 18:54:21 -05:00 by null · 0 comments
Owner

Batch 7.3 — Upsert Strategy for Duplicate Zoho Leads

Phase: 7 — Zoho CRM Integration
Agent: Neo (backend)
Priority: P2 Medium — prevents duplicate lead clutter in Zoho

Problem

Currently if someone submits the contact form twice with the same email, SQLite returns 409 Conflict (correct), but the Zoho forwarding still attempts to create a second lead. Should upsert (update existing) instead of always inserting.

Tasks

  • Before creating a new Zoho lead, search for existing leads with the same email
  • If found: update the existing lead (upsert) with new info
  • If not found: create new lead as before
  • Zoho search API: GET /crm/v8/Leads/search?criteria=Email:equals:{email}
  • If search returns results, use PUT /crm/v8/Leads/{id} to update
  • Add proper error handling for search failures (fall back to create)
  • Log whether operation was create or update
  • Keep fire-and-forget pattern (non-blocking)

Files to modify

  • server/index.js — Add searchZohoLead() and update forwardToZoho() with upsert logic

Acceptance criteria

  • First submission from email: creates new Zoho lead
  • Second submission from same email: updates existing Zoho lead
  • If Zoho search fails: fall back to create (best-effort)
  • SQLite 409 Conflict still returned to client (no change to local behavior)
  • No regressions when ZOHO_ENABLED=false
## Batch 7.3 — Upsert Strategy for Duplicate Zoho Leads **Phase:** 7 — Zoho CRM Integration **Agent:** Neo (backend) **Priority:** P2 Medium — prevents duplicate lead clutter in Zoho ### Problem Currently if someone submits the contact form twice with the same email, SQLite returns 409 Conflict (correct), but the Zoho forwarding still attempts to create a second lead. Should upsert (update existing) instead of always inserting. ### Tasks - Before creating a new Zoho lead, search for existing leads with the same email - If found: update the existing lead (upsert) with new info - If not found: create new lead as before - Zoho search API: `GET /crm/v8/Leads/search?criteria=Email:equals:{email}` - If search returns results, use `PUT /crm/v8/Leads/{id}` to update - Add proper error handling for search failures (fall back to create) - Log whether operation was create or update - Keep fire-and-forget pattern (non-blocking) ### Files to modify - `server/index.js` — Add `searchZohoLead()` and update `forwardToZoho()` with upsert logic ### Acceptance criteria - First submission from email: creates new Zoho lead - Second submission from same email: updates existing Zoho lead - If Zoho search fails: fall back to create (best-effort) - SQLite 409 Conflict still returned to client (no change to local behavior) - No regressions when `ZOHO_ENABLED=false`
null added the
backend
data-integrity
phase-7
labels 2026-05-17 18:54:21 -05:00
null added the
P2 Medium
label 2026-05-17 18:55:33 -05:00
null closed this issue 2026-05-17 19:25:30 -05:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/Queue-North-Website#77
No description provided.