Skip to content

Product Tag Sync

Refresh product tags, vendor, and status from Shopify into product.tags — updating product attributes (tags, vendor, status) to power tag analytics and UI filters, without requiring a full data acquisition workflow (ProcedureExecution).

Goal: Ensure product attribute accuracy independently of the daily bulk sync.

MethodPathSpecDescription
POST/api/products/tags/syncproduct.yamlEnqueue tag sync job (p99 < 200ms)
GET/api/products/tags/sync/statusproduct.yamlCheck sync job status (?job_id=...)
GET/tagsproduct.yamlList all product tags
GET/tags/{tag_id}product.yamlGet single tag detail
GET/productsproduct.yamlList products (verify synced data)
TableModuleRole
productProductWrite: tags, vendor, status, last_seen upserted from Shopify
product_tagProductWrite: tag records synced from Shopify
ResourceTypePurpose
internalWorkerAPI validation, job enqueue
ingestWorkerFetches tags from Shopify, upserts to DB
CF QueueQueueARTIFACT_TAG_SYNC job delivery
ActorRole
Staff user (Ops/Creative)Triggers sync via UI
Dashboard API WorkerValidates, enqueues job
Ingest WorkerFetches tags, upserts products
Shopify Admin APIProduct data source
  1. Staff clicks “Sync Tags” → POST /api/products/tags/sync
  2. API writes optional workflow execution record and enqueues ARTIFACT_TAG_SYNC
  3. Ingest Worker queries Shopify (prefer GraphQL) with rate-limit backoff
  4. Worker upserts product(tags, vendor, status, last_seen) in chunks — updating attributes on each product
  5. Worker optionally enqueues measurement dataset refresh if classification thresholds depend on tags
Error conditionRecovery
Shopify rate limitDelay retry using queue delaySeconds (up to 12 hours)
PlanetScale limitsUse smaller batches
{
"job_type": "ARTIFACT_TAG_SYNC",
"job_id": "uuid",
"mode": "full",
"requested_at": "ISO8601"
}
  • PASS: Sample product’s tags in Shopify match product.tags after completion
  • FAIL: Orphaned products, malformed JSON in tags, or job unable to complete