Documentation
A savings record and its evidence
The single pair a savings record compares, how the confidence score is composed, why the unverified list never changes, and what an approve or reject decision does.
Last reviewed against the product on .
What a saving claims describes the comparison in general. This page is about one record of it: the pair of products on screen, the scored evidence beside them, the fixed list of things nobody has checked, and the review that decides whether the record survives at all.
One record is one pair, and there is only ever one
A savings record compares exactly two products: the one you currently buy, and the cheapest other supplier whose item name, unit and currency all match it exactly. Where several suppliers qualify, the cheapest becomes the candidate and the rest are not shown. There is at most one record per product you buy, so the record is the whole of the comparison for that item, not the first of several options.
The link into the page carries an alternative record id as well as the current one. It cannot change which pair you see, because only one pair exists for that product. It can only fail to match, in which case the page is not found rather than showing a different candidate.
Both prices are each product's most recent imported price. They are not required to have been observed on the same day, or in the same month. How far apart they are is scored rather than hidden, and it is the fourth line in the evidence list.
Match confidence, component by component
| Component | Award | How it is earned |
|---|---|---|
| Item name | 45 | The two normalized item names are identical |
| Purchase unit | 20 | The two normalized units are identical |
| Currency | 15 | The two currency codes are identical |
| Freshness | 10, 7, 4 or 0 | The older of the two latest purchase dates is within 14, 45 or 90 days of your data anchor |
| Coverage | 10, 6 or 2 | Both products have at least 3 imported rows, or both have at least 2, otherwise 2 |
Measured from opportunityConfidence in src/lib/purchasing/intelligence.ts.
The evidence list on the page is exactly this table, rendered as sentences with the award each component actually received. It is not a separate justification written alongside the score; it is the score, itemized. That is why a line can appear claiming a component and still show a low award beside it.
What the label means, and what it cannot mean
| Score | Label | Can appear on a record |
|---|---|---|
| 90 and above | Strong candidate | Yes |
| 80 to 89 | Review candidate | Yes |
| Below 80 | Insufficient evidence | No |
Measured from confidenceLabel in buildOpportunities, src/lib/purchasing/intelligence.ts.
The three exact-match components are not scored so much as required: a pair that fails any of them is never built into a record in the first place. Every record that reaches this page has therefore already banked them, and the two remaining components cannot take a total below the review threshold.
- Banked before scoring
- 80 of 100
- item name, unit and currency, or the pair does not exist
- Lowest reachable total
- 82 of 100
- the banked 80 plus the smallest coverage award
- Highest total
- 100 of 100
- all five components at their maximum
Measured from buildOpportunities and opportunityConfidence in src/lib/purchasing/intelligence.ts.
So "Insufficient evidence" is a label the scoring can define but this surface cannot produce. It is worth knowing for two reasons. A record labelled "Review candidate" is at the bottom of the range rather than in the middle of it, and the separate review decision of the same name, described below, is a different thing entirely.
The unverified list is fixed, not derived
The amber panel is a constant. Every savings record carries the same three lines, in the same order, regardless of the score above it or the suppliers involved.
| Line printed | Varies between records |
|---|---|
| Pack weight is not verified. | No |
| Brand, grade, preparation, and quality equivalence are not verified. | No |
| Availability and contract terms are not verified. | No |
Measured from missingEvidence in buildOpportunities, src/lib/purchasing/intelligence.ts.
Reading it as a per-record finding would be reading it backwards. It is a standing statement that imported purchase data cannot answer those three questions for any pair, which is precisely why the record is a candidate for review rather than an instruction.
The impact figures
| Figure | How it is calculated |
|---|---|
| Per unit | Current unit price minus alternative unit price |
| Per week | Per unit multiplied by observed weekly quantity |
| Per month | Per week multiplied by 52 and divided by 12 |
| Per year | Per week multiplied by 52 |
Measured from the calculation disclosure in app/app/savings/[recordId]/page.tsx and buildOpportunities in src/lib/purchasing/intelligence.ts.
Only one quantity enters that arithmetic, and it is yours. The observed weekly quantity comes from the product you already buy, inside the usage window printed under the figures. Nothing about the alternative supplier's volumes, minimum orders or delivery days is known to the calculation, so the monthly and annual figures are the weekly figure restated rather than three independent results.
The decision is real, and it is made somewhere else
There is no approve button on this page. The record shows the evidence; the decision is recorded by an administrator on the match review screen under the admin area, and it is stored against the supplier pair, item, unit and currency rather than against a record id, so it survives the next import.
| Decision | Effect on the savings surface |
|---|---|
| Pending | The default. The record is listed and its weekly figure counts toward potential savings |
| Approved | Unchanged on screen. The decision and its reviewer are stored, alongside the score and evidence as they stood |
| Rejected | Removed from the listing, the totals, the dashboard and the weekly report |
| Insufficient | Removed in exactly the same way as rejected |
Measured from reviewProductMatch in app/admin/match-review/actions.ts and applyOpportunityDecisions in src/lib/purchasing/intelligence.ts.
The decision status and its review date exist on every record in the data, and neither is printed here. Approved and pending records are indistinguishable on this page, so the record of what was decided lives on the match review screen rather than on the evidence page.
What the record is still not
It is a deterministic price candidate, which is what the page says at the top, and it stops short of the three things nobody has checked. The prices are yours and already paid; whether the cheaper one remains available, arrives in the same pack, and is worth changing a supplier over are all questions the import cannot answer.
Where to look next
What a saving claims is the general statement this record is one instance of. A product record is the other side of the same pair, with its own price history and observed usage. Where no record appears at all, the import contract is usually the reason: a unit or a currency that did not arrive keeps a product out of every comparison on the site.