Skip to content

content-studio: implement Rust Instagram publish service (#593) #597

@thxforall

Description

@thxforall

Parent

Parent: #593

What to build

Implement the Rust API behavior that publishes an approved Instagram Feed Variant through the single internal Instagram Publish Account.

This slice owns the publish domain rules: env-based account resolution, lazy account upsert, publishable asset validation, bounded synchronous Meta publishing, publish job persistence, and latest publish job data in packet detail responses.

Acceptance criteria

  • Rust config reads INSTAGRAM_PUBLISH_IG_USER_ID, INSTAGRAM_PUBLISH_ACCESS_TOKEN, INSTAGRAM_GRAPH_API_VERSION, and optional INSTAGRAM_PUBLISH_ACCOUNT_LABEL.
  • Missing Instagram publish env returns 503 publish not configured.
  • The matching internal Instagram Publish Account is lazy-upserted and stores only token_ref, never the raw token.
  • A disabled publish account rejects publishing even when env is present.
  • Only approved instagram_feed variants can publish.
  • imageAssetUrl is allowlisted to the public content-studio-assets bucket, rejects data: and arbitrary external URLs, and preflights as public JPEG.
  • Meta calls use a trait/mockable client and target Instagram Login / graph.instagram.com.
  • Publish is synchronous and bounded: completed requests persist published or failed, not stuck processing.
  • Failed publish attempts persist structured error_json.
  • Retrying after a failed job creates a new content_publish_jobs row.
  • If the latest Publish Job for the variant is published, Rust rejects duplicate publishing with 409 Conflict and code already_published before creating a new job.
  • Packet detail returns publishJobsByVariantId with the latest job per variant using created_at DESC, id DESC ordering without mutating variant review status.
  • Rust tests cover success, invalid variant states, missing env, disabled account, invalid asset URL, already-published duplicate prevention, Meta failures, timeout, and latest job map.

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions