magendoo/module-catalog-quality

Catalog data quality observability for Magento 2 — completeness scoring, filter-blind detection, and gap reporting

Maintainers

Package info

github.com/magendooro/magento2-catalog-quality

Type:magento2-module

pkg:composer/magendoo/module-catalog-quality

Fund package maintenance!

magendoo.ro

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-04-21 06:51 UTC

This package is auto-updated.

Last update: 2026-04-21 06:58:16 UTC


README

Catalog data quality observability for Magento 2.
Know exactly which products are hurting your conversion rate before your customers find out.

Magento 2 PHP License: MIT

What It Does

Magendoo_CatalogQuality scores every product in your catalog against a two-axis quality model — Enrichment (are the important attributes filled in?) and Consistency (do they meet your content rules?) — and combines them into a single Product Health Score (PHS) between 0 and 100. Products are graded A–E.

The module answers three questions that every Magento merchant needs:

  1. Which products are incomplete? — The Gap List shows every product's grade, PHS, priority gaps, and the specific missing attribute codes.
  2. Which products are invisible in layered navigation? — The Filter-Blind detector flags products that have no value for a filterable attribute, making them unfindable when shoppers use your category filters.
  3. Which filter attributes have the worst coverage across categories? — The Filter Coverage Matrix shows fill rates as a colour-coded heatmap, scoped by attribute set.

No auto-fix. No AI. Just clear, actionable diagnostic data.

Screenshots

Dashboard

Catalog Quality Dashboard

The dashboard shows the Catalog Health Index (CHI) — a revenue-weighted average PHS across all scored products — alongside grade distribution, filter-blind product count, and a 30-day CHI trend chart.

Product Gap List

Product Gap List

Every scored product in one grid: grade badge, PHS, P1/P2/P3 gap counts, a filter-blind chip, and colour-coded missing attribute chips. Red chips are filterable attributes directly causing filter-blindness; grey chips are other priority gaps.

Filter Coverage Matrix

Filter Coverage Matrix

Rows are user-defined filterable attributes; columns are active categories (filterable by attribute set). Each cell shows the fill-rate percentage, colour-coded from green (≥90 %) to red (<35 %). Click a cell to open the Gap List pre-filtered by that attribute and category.

Features

  • Two-axis PHS scoring: Enrichment completeness × Consistency conformance multiplier
  • A–E grade thresholds: ≥90 → A, ≥80 → B, ≥70 → C, ≥50 → D, <50 → E
  • Revenue-weighted CHI: weights products by 90-day revenue when sales data is available
  • Filter-blind detection: flags products invisible in layered navigation per store view
  • Attribute Priority System: P1/P2/P3/P4/Ignore per attribute, with category and attribute-set overrides
  • Placeholder blocklist: regex and literal patterns to catch values like "N/A", "TBD", "Lorem ipsum"
  • 9 built-in quality rules: Meta Title, Meta Description, URL Key, Name, Description, Image, Category, Price, Filterable Attribute
  • Conditional attribute groups: score module-specific attributes only when their control flag is on (e.g. base-price fields only when baseprice_is_enabled = 1)
  • Magento indexer integration: incremental updates via MView, full reindex via CLI
  • Nightly CHI snapshots: 30-day trend data stored automatically via cron
  • CSV export of the Gap List and Priority table
  • REST API: 6 endpoints for scores and priorities
  • Inline-editable Priority Grid: change priority levels without leaving the listing
  • Filter Coverage Matrix: attribute set filter, product counts per category column, click-through to Gap List

Requirements

Dependency Version
PHP ≥ 8.2
Magento Open Source / Adobe Commerce 2.4.x
magento/framework ≥ 103.0
magento/module-catalog ≥ 104.0

Installation

Via Composer (recommended)

composer require magendoo/module-catalog-quality
bin/magento module:enable Magendoo_CatalogQuality
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f
bin/magento cache:flush

Manual

  1. Copy the module directory into app/code/Magendoo/CatalogQuality/
  2. Run the same CLI commands above

Initial Setup

After installation, run the full indexer to score all products:

bin/magento indexer:reindex magendoo_cq_product_score

This may take several minutes on large catalogs. The batch size is configurable under Stores → Configuration → Magendoo Extensions → Catalog Quality → Performance.

Admin Screens

Navigate to Catalog Quality in the top-level admin menu.

Screen URL Description
Dashboard /catalogquality/dashboard/index CHI, grade distribution, filter-blind count, 30-day trend
Product Gap List /catalogquality/gaps/index All scored products; filterable by grade, filter-blind status
Filter Coverage Matrix /catalogquality/filters/index Attribute fill-rate heatmap per category
Attribute Priorities /catalogquality/priority/index Inline-editable priority rules

Configuration

Stores → Configuration → Magendoo Extensions → Catalog Quality

Setting Default Description
Enabled Yes Master switch
Revenue-weighted CHI Yes Weight CHI by 90-day product revenue
Indexer Batch Size 500 Products scored per batch during full reindex
Snapshot Retention 90 days How long nightly CHI snapshots are kept

Scoring Algorithm

See docs/scoring-algorithm.md for the full specification.

Summary:

PHS(product, store_view) =
    [Σ weight(attr) × completeness_score(attr)] / [Σ weight(attr)]   ← enrichment
    × conformance_multiplier                                           ← consistency
    × 100

completeness_score:  empty / placeholder → 0.0 | present → 0.5 | meets_bar → 1.0
conformance_mult:    1.0 baseline; CRITICAL rule failure × 0.7; WARNING × 0.9

CHI = Σ(revenue_90d × PHS) / Σ(revenue_90d)     (falls back to equal-weight)

Priority System

See docs/priority-system.md for the full hierarchy.

Quick reference:

Level Weight Meaning
P1 100 Critical — directly impacts conversions (name, price, image, meta)
P2 50 Important — filterable attributes auto-floor here
P3 20 Standard — user-defined attributes not yet classified
P4 5 Low — nice-to-have
Ignore 0 Never scored (system attrs, optional promotional fields)

Priority resolution order (first match wins):

  1. Explicit row with matching category_id
  2. Explicit row with matching attribute_set_id
  3. Explicit global row (no set, no category)
  4. Implicit: SEO attrs → P1; user-defined filterable → P2; user-defined → P3; else → Ignore

Conditional Attribute Groups

Some module attributes should only be scored when they are relevant for a specific product. Configure this in etc/di.xml:

<type name="Magendoo\CatalogQuality\Model\Scoring\ProductScorer">
    <arguments>
        <argument name="conditionalGroups" xsi:type="array">
            <item name="baseprice" xsi:type="array">
                <item name="enabledBy" xsi:type="string">baseprice_is_enabled</item>
                <item name="attributes" xsi:type="array">
                    <item name="0" xsi:type="string">baseprice_product_amount</item>
                    <item name="1" xsi:type="string">baseprice_unit_id</item>
                    <item name="2" xsi:type="string">baseprice_reference_amount</item>
                </item>
            </item>
        </argument>
    </arguments>
</type>

The enabledBy attribute is never scored itself — it acts as a gate. The listed attributes are only evaluated when the gate attribute is truthy (1). The example above wires up Magendoo_BasePrice so that unit-pricing compliance fields only count as gaps on products where base pricing is switched on.

CLI Commands

# Full reindex — score all products (optionally scoped to a store)
bin/magento catalog-quality:rebuild [--store=<store_id>] [--batch=<size>]

# Debug a single product
bin/magento catalog-quality:score <sku> [--store=<store_id>]
# Example output:
# {"sku":"WH-X500","grade":"D","phs":42.15,"filter_blind":true,"p1_gaps":1,"p2_gaps":2,"missing":["cq_connectivity","cq_color"]}

# Export priorities to CSV
bin/magento catalog-quality:priorities:export [--set=<attribute_set_id>] [--format=csv]

REST API

See docs/rest-api.md for request/response schemas.

Method Endpoint Description
GET /V1/catalog-quality/scores/:sku Get quality score for a single SKU
GET /V1/catalog-quality/gaps List gap records (supports search criteria)
POST /V1/catalog-quality/priorities Create or update a single priority rule
POST /V1/catalog-quality/priorities/bulk Bulk upsert priority rules
GET /V1/catalog-quality/priorities List priority rules
DELETE /V1/catalog-quality/priorities/:id Delete a priority rule

All endpoints require an admin bearer token. Authenticate with POST /V1/integration/admin/token.

Database Tables

Table Purpose
magendoo_cq_priority Attribute priority rules (P1–P4/Ignore) per attribute, set, and category
magendoo_cq_priority_history Audit log of priority changes
magendoo_cq_product_score Per-product PHS, grade, gap counts, filter-blind flag
magendoo_cq_attribute_score Per-attribute value states for a product
magendoo_cq_catalog_snapshot Nightly CHI snapshots for trend charts
magendoo_cq_scope_profile Named scope profiles (sellable, pre-launch, full catalog)
magendoo_cq_rule_config Per-rule enabled/severity/parameter overrides
magendoo_cq_placeholder_blocklist Literal and regex patterns for placeholder detection
magendoo_cq_remediation_queue Remediation work queues (Phase 2)
magendoo_cq_remediation_queue_item Items within a remediation queue
magendoo_cq_rule_run_log Indexer run audit log

Extending

Adding a Custom Quality Rule

  1. Implement Magendoo\CatalogQuality\Api\RuleInterface
  2. Register it in etc/di.xml under RulePool
<type name="Magendoo\CatalogQuality\Model\Rule\RulePool">
    <arguments>
        <argument name="rules" xsi:type="array">
            <item name="my_custom_rule" xsi:type="object">
                Vendor\Module\Model\Rule\Enrichment\MyCustomRule
            </item>
        </argument>
    </arguments>
</type>

Adding a Conditional Attribute Group

Register a conditionalGroups item as shown in the Conditional Attribute Groups section above.

License

MIT — © 2025 Magendoo Interactive