Skip to main content

Multi-Source Repost Architecture

The multi-source repost initiative decouples organic-source detection from destination selection so each workflow can express its own automations. This doc explains the target design that extends the current repost system.

Goals

  • Support multiple source accounts per platform (TikTok, Instagram, future) without duplicating orchestrator logic.
  • Allow per-workflow destinations and templates, e.g., “TikTok A1 → Instagram A1” and “TikTok A1 → LinkedIn B2”.
  • Provide per-workflow execution tracking so operators can see what ran for a given organic post and explicitly rerun the workflows they need, without accidental duplicates.
  • Keep rollout safe through staged dual reads/writes even though no backwards-compatibility shim is required today.

Workflow Resolution Flow

  1. Organic triggeronOrganicPostCreated (TikTok/Instagram) now includes the resolved targetId of the source account (${platform}:${accountId}). The trigger queries users/{uid}/automations_workflows where source.targetId == sourceTargetId and status == 'active'.
  2. One workflow → one task – For every matching workflow, the trigger writes/merges users/{uid}/organicPosts/{postId}/workflows/{workflowId} with { status: 'pending' } and enqueues the repost orchestrator with { userId, postId, workflowId, sourceTargetId }. Deterministic task names (repost-${workflowId}-${postId}) prevent duplicate dispatches.
  3. Guardrails – If no workflows match, the trigger simply logs and exits; other workflows for the same post remain untouched.

Repost Orchestrator Contract

HTTP payload:

{
"userId": "uid",
"postId": "tiktok_123",
"workflowId": "wf_A1_to_IG",
"sourceTargetId": "tiktok:acctA1"
}

Orchestrator steps:

  1. Load workflowDoc = users/{uid}/automations_workflows/{workflowId} and verify it is active and its source.targetId matches sourceTargetId.
  2. Load organicPost and check organicPosts/{postId}/workflows/{workflowId}; if status === 'succeeded' or repostSubmissionId exists, short-circuit.
  3. Build the repost targets from workflowDoc.repostTargets, filtering out accounts that are no longer enabled_for_repost. For each valid target emit { platform, accountId, targetId }.
  4. Write postSubmissions/{submissionId} with type: 'repost', workflowId, sourceTargetId, and the resolved targets. Use orchestratePublishing so the fan-out path stays consistent.
  5. Execute repurpose actions (see below) before marking success to catch synchronous configuration errors.
  6. Update organicPosts/{postId}/workflows/{workflowId} with { status: 'succeeded', repostSubmissionId, updatedAt }. Failures write { status: 'failed', lastError } and rely on Cloud Tasks retry/backoff.

Idempotency

  • organicPosts/{postId}/workflows/{workflowId} is the single source of truth for whether a workflow has run.
  • postSubmissions store workflowId + organicPostId + targetIds so operators can correlate fan-out with specific workflows.
  • Deterministic task names + the per-workflow status doc allow replays without touching unrelated workflows.

Template / Repurpose Actions

workflowDoc.repurposeActions replaces the implicit “all template targets” behavior:

  1. During orchestration, the service hands the workflow’s repurposeActions to trigger-templates, which now accepts { workflowId, actions }.
  2. Each action references a templateId, target platform/account, and optional delayHours + AI prompt overrides. This mirrors the existing repurposeLinks data but scoped per workflow.
  3. The handler creates scheduled posts via createAndOrchestratePost exactly like today, but it tags each submission with { workflowId, sourceTargetId } for observability.
  4. Because template automations are workflow-scoped, disabling a workflow automatically prevents both repost and repurpose fan-out for that source pair.

Rollout & Migration

  1. Bootstrap workflows – Define the schema + security rules, then seed initial workflow docs for the internal accounts you’re testing (no dual-write requirement because there are no production users yet).
  2. Update triggers – Ship TikTok/Instagram organic triggers that query workflows exclusively. If a post has no matching workflow, log and exit; no fallback to enabled_for_repost is necessary.
  3. Orchestrator & templates – Deploy the repost orchestrator + template handlers that require { workflowId, sourceTargetId }, writing per-workflow status docs as described above.
  4. QA & instrumentation – Exercise multiple workflows per source in staging, verifying Cloud Tasks fan-out, template jobs, and per-workflow status updates before enabling new platforms.
  5. Cleanup legacy toggles – Remove enabled_for_repost driven fan-out paths, keep the field only for UI gating, and delete any dead code that referenced the global target list.

Adding New Platforms

  • Source onboarding only needs to emit organic posts with the correct source_target_id.
  • Destination onboarding adds provider-specific publish functions as before, but only workflows that reference that target will fire.
  • Templates can be targeted to any future platform by setting repurposeActions[].platform and gating availability through the same workflow system.