Product Optimization Scoring (M18)
What It Does#
Scores each product in the PIM catalog for AI search readability using Claude Haiku. Produces a 0–100 aggregate score across four dimensions and a ranked list of improvement recommendations.
Score Dimensions#
Each dimension is scored 0–25:
| Dimension | What It Evaluates |
|---|---|
schema_coverage | Key structured fields present: description, brand, category, price, image |
answer_format | Content reads like how an LLM would answer queries in this product category |
factual_completeness | Fraction of schema fields populated; key spec attributes present |
ai_visibility_alignment | Correlation with existing AI visibility snapshot data for the tenant |
API Endpoints#
POST /api/pim/products/<id>/score/#
Queues scoring for a single product. Returns 202.
GET /api/pim/products/<id>/score/#
Returns the latest ProductOptimizationScore for a product, or 404 if not yet scored.
Response:
POST /api/pim/score-all/#
Queues scoring for every product in the tenant's catalog. Returns 202 with product_count.
Celery Tasks#
| Task | Trigger | Description |
|---|---|---|
apps.pim.tasks.score_product(product_id) | Manual or fan-out | Scores a single product via Claude Haiku |
apps.pim.tasks.score_all_products(tenant_id) | Manual | Fan-out: queues score_product for every product |
apps.pim.tasks.score_all_products_nightly() | Nightly beat (24h) | Iterates all tenants and calls score_all_products |
UI#
- Catalog (
/pim): Score badge column (green ≥70, yellow ≥40, red <40). "Score All" button in toolbar. - Product detail (
/pim/<id>): Optimization tab with score gauge, dimension progress bars, ranked recommendations list, and "Re-score" button.
Data Model#
apps/pim/models.ProductOptimizationScore:
product— OneToOneField to Productscore— FloatField (0–100)dimension_scores— JSONField{schema_coverage, answer_format, factual_completeness, ai_visibility_alignment}recommendations— JSONField[{dimension, action, estimated_impact, priority}]scored_at— DateTimeField (auto_now)
The legacy Product.ai_readability_score field is kept in sync automatically by the scorer.