Skip to Content
Internal docs are powered by Nextra Docs Theme.
SystemsPlatformAPI2Rails to API2 migrationPackagesRelationship construction hand-off

Relationship construction hand-off

Moves the two remaining GoodJob producers of relationship construction — CreateConversationRelationshipsJob and CreateConversationPartRelationshipsJob — behind the API2 BullMQ workers that already execute the work for the provider-sync manifest keys.

Contract

  • Conversation#detect_and_queue_conversation_relationships (subject change or create) and ConversationFieldValue’s commit hook (create or string value change) POST to POST /internal/conversation_relationships/enqueue, which adds one provider-conversation-field-value-link job keyed provider_conversation_field_value_link_<conversationId>_<changeKey>. change_key is the producer’s per-commit token (<record>_<id>_<updated_at iso8601(6)>): a retried delivery of the same commit dedupes onto the already-accepted job, and a later commit cannot be swallowed by a retained completed/failed key.
  • ConversationPart#detect_and_queue_relationship_creation posts to POST /internal/conversation_part_relationships/enqueue, which adds one part-keyed job per reference kind (provider_conversation_part_reference_link_<partId>, ..._jira_link_<partId>, ..._aircall_call_<partId>). Only the all-kinds callback takes this path; a kinds subset stays on the GoodJob job.
  • The workers re-read current state at execution time (subject + all string field values, or the part’s persisted content), so ordering and merge semantics are identical to the GoodJob passes — every write is a thread merge, unique-indexed thread item, or Aircall call part import that is idempotent under replay.
  • Delivery classification matches the other hand-offs: a transport error is ambiguous (API2 may have accepted) and retries through EnqueueApi2ConversationRelationshipsJob / EnqueueApi2ConversationPartRelationshipsJob; an explicit non-2xx falls back to the legacy GoodJob job so the commit is never dropped.

Rollback order

  1. PostHog flags api2_conversation_relationships and api2_conversation_part_relationships (false restores the GoodJob producers immediately; they fail closed when PostHog is unreachable).
  2. A clear API2 delivery failure already falls back to the GoodJob job automatically, so a worker outage degrades rather than drops.
  3. PROVIDER_SYNC_NATIVE_EFFECTS hand-back stays independent: the sync effects applier calls the part callback with via_api2: false, so a kind returned to Rails always executes on GoodJob regardless of the flags.

Verification

  • Assert zero new CreateConversationRelationshipsJob and CreateConversationPartRelationshipsJob executions in each region’s retained GoodJob window after the flag reaches 100% (retained 12-hour rows are historical).

  • BullMQ: provider-conversation-field-value-link and the three part link queues accept and drain; no growth in failed sets beyond the existing provider-sync baseline.

  • Production observation query (per region):

    SELECT job_class, COUNT(*) FROM good_job_executions WHERE job_class IN ('CreateConversationRelationshipsJob', 'CreateConversationPartRelationshipsJob', 'EnqueueApi2ConversationRelationshipsJob', 'EnqueueApi2ConversationPartRelationshipsJob') AND created_at > now() - interval '12 hours' GROUP BY job_class;
  • Bridge jobs should sit near zero; a sustained count means ambiguous delivery (check API2 /internal/conversation_*_relationships/enqueue health and internal_api_key).

Last updated on