Skip to content

Tag Classification Bulk Update

Maintain mappings of product tags to categories — creating tag classification records that link tags to product collections. Bulk operations enable operational efficiency. Tag classifications drive analytics, designer assignments, and performance groupings.

Goal: Insert/update many (category_name, tag_name) tag classification mappings at once while maintaining the uniqueness invariant.

Tag classification (internal, not yet specced)

Section titled “Tag classification (internal, not yet specced)”
MethodPathDescription
POST/api/tag-classifications/bulkBulk upsert of tag classification mappings
GET/api/tag-classifications/unclassifiedTags not yet assigned to any category
MethodPathSpecDescription
GET/tagsproduct.yamlList all product tags
GET/tags/{tag_id}product.yamlGet a single tag
POST/tagsproduct.yamlCreate a tag
PUT/tags/{tag_id}product.yamlUpdate a tag
GET/categoriesproduct.yamlList product categories

Both tag classification endpoints are protected by CF Access. CRUD target: p99 < 200ms for normal payloads.

TableModuleRole
product_tagProductCRUD: tag classification records (UNIQUE(category_name, tag_name))
product_categoryProductRead: category definitions
productProductRead: product-to-tag links for coverage analysis
ResourceTypePurpose
dashboard-apiCF Worker (internal)Bulk classification endpoint
PlanetScale (Hyperdrive)Managed PostgresTag + category data storage
  1. Staff user (Ops/Creative) selects tags and categories in the UI
  2. UI calls POST /api/tag-classifications/bulk with mapping list
  3. API validates input, performs chunked upsert into product_tag (UNIQUE(category_name, tag_name))
  4. API optionally enqueues analytics refresh if cached aggregate tables exist

Request:

{
"mode": "upsert",
"mappings": [
{ "category_name": "Theme", "tag_name": "floral" },
{ "category_name": "Theme", "tag_name": "abstract" },
{ "category_name": "Device", "tag_name": "iphone-16" }
]
}

Response:

{
"updated": 120,
"created": 34,
"errors": []
}
IssueFallback
Conflicting category updatesDefine “move tag from A to B” semantics (delete prior mapping + insert new)
PlanetScale limitsChunk to < 100k rows per statement
Large payloads exceeding CRUD latencyAccept request quickly, process async if payload exceeds threshold
  • PASS: After bulk call, tag classifications appear in correct category; unclassified endpoint excludes them
  • FAIL: Duplicate classification records; missed inserts; inconsistent uniqueness