Review shows Original vs Enriched for name, description, category, attributes and
SEO meta. Each "Original" must come from a source the pipeline never writes, which
is less obvious than it sounds:
| field | Original comes from | trap |
|---|---|---|
| name / description | `original_name` / `original_description` | `name`/`description` from the API are display-preferred and resolve to the ENRICHED copy |
| category | `feed_category` | `mapped_data.category` is written back by the pipeline; `category_source` says who chose it |
| attributes | `mapped_data.specifications` (feed specs) | `processed_products.attributes` is written to the same value as `processed_attributes` |
| | | EPREL writes one fact under several names — `product-attributes.ts` folds the aliases so it is listed once |
| SEO meta | `mapped_data.meta_*` | most feeds have none, so Enriched shows as **Added** |
Attributes are grouped **Added / Changed / Unchanged**, with unchanged collapsed —
a review should lead with what the run actually did. Alias keys are folded into one
row: enrichment stores `eprel_pdf` and `eprel_pdf_url`, `energy_class` and
`eprel_energy_class`, which otherwise listed the same fact two or three times.
Folding needs a related name AND an identical value, so width and height are never
merged just because they match (`$lib/attribute-diff`, unit-tested).
The product detail endpoint deliberately does **not** apply the SEO-meta omit rule.
That rule keeps meta out of list views for cohorts that do not sell on it, but the
detail payload feeds review, and meta the pipeline actually generated has to be
reviewable — the panel hides the block itself when both sides are empty.
Anything with no Original is labelled **Added** and shown as "not in feed", not
"Matched" — saying Matched about a field the supplier never sent reads as if the
feed had one.
Two things behave this way by design, not by accident:
- **A1 Slovenija and Platform Demo do not GENERATE SEO meta**
(`processing.CompanyOmitsSEOMetaID`). Meta already stored on their rows is still
shown — the read path only hides empty values, so Review and Content display what
the AI actually produced.
- **Rows processed before `category_source` existed** cannot say whether their
`mapped_data.category` came from the feed or from an earlier AI run, so Review
still treats it as feed-supplied. Reprocessing the product records the real