This commit is contained in:
2026-08-24 03:41:06 +02:00
parent a246ed8fe5
commit 8a690a0464
22 changed files with 1253 additions and 358 deletions
+41
View File
@@ -78,6 +78,47 @@ go run ./cmd/formula-e2e -new-tenant -llm-base http://127.0.0.1:18767/v1
`-llm-base` pins the provider for the run; without it the harness uses whatever
`platformsettings.ResolveOpenAI` returns (admin DB setting first, then env).
## What Review compares
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
provenance.
## Low-confidence categorisation fails the product
The categorize model always answers with *some* id from the list, so a reply like