# THIS YOU — Product Price Verification & Regular-Price Policy

## Scope

Apply these changes to the **PRODUCT-FIRST** workflow used before hero-image generation.

This spec updates price handling in:

- product discovery / selection;
- AI product-selection prompt;
- product verification;
- `this_you.product_selection_result.v1`;
- admin product approval UI;
- budget validation;
- magazine / digital issue rendering.

The existing input currently uses a single `price` field in `result_schema`. Keep that field for compatibility, but change its contract: **`price` always means the regular/base retail price, never a temporary discounted price.**

---

# CHANGE 1 — Strict exact-product price verification

## Problem

A product can be selected correctly while the returned price is wrong because it came from:

- a search result snippet;
- cached/indexed data;
- another colour/variant;
- another product in the same collection;
- a temporary sale price;
- stale structured metadata.

Example found during Chapter 1 review:

- Product: Weekday **Uno Loose Suit Trousers — Black**
- Exact product URL was correct.
- Returned price did not match the exact Black product page.

This must be treated as a verification failure.

---

## Required behaviour

### 1. Verify against the exact product page

For every selected product:

1. Open the exact `product_url`.
2. Confirm that the page matches:
   - brand;
   - product name;
   - selected colour / variant;
   - product construction;
   - requested category/slot.
3. Read the **regular/base retail price from that exact product page**.
4. Do not use a search-engine result, search snippet, category page or cached price as the final source of truth.

### 2. Exact variant matters

A price is valid only for the selected variant.

Example:

```text
Uno Loose Suit Trousers — Black
```

must not inherit the price from:

```text
Uno Loose Suit Trousers — Beige
```

even if both pages belong to the same model.

### 3. If price cannot be verified, do not guess

If the exact product page does not expose a trustworthy regular price:

- do not invent a value;
- do not reuse a search-result price;
- do not infer the price from another colour;
- reject that product from the final selection and find a replacement.

The goal is that **every product entering human review already has a price verified against its exact product page**.

---

## Prompt update

Add to `instruction_to_ai` / verification rules:

```text
PRICE VERIFICATION: The returned price must be verified on the exact selected product page and exact selected colour/variant. Search-result snippets, cached prices, category-page prices, prices from another colour/variant, and inferred prices are not valid sources. If the regular price cannot be verified confidently on the exact product page, do not return the product; replace it with another verifiable product.
```

---

## Verification note

`verification_note` should explicitly state that the exact variant and regular price were checked.

Good:

```json
"verification_note": "Exact Weekday product page checked for Uno Loose Suit Trousers, Black. Product name, colour, construction and regular retail price verified."
```

Bad:

```json
"verification_note": "Found via Google."
```

or:

```json
"verification_note": "Price seen in search results."
```

---

# CHANGE 2 — Use only the regular/base price

## Product policy

THIS YOU issues remain purchasable for a season, so temporary sale prices become stale very quickly.

Therefore:

> **THIS YOU always stores, validates and displays the regular/base retail price. Temporary sale, promotional, member, coupon or campaign prices are ignored.**

This applies even if the product is discounted at the moment the issue is generated.

---

## `price` field contract

Keep the existing result schema:

```json
"price": 64.99,
"currency": "EUR"
```

Do **not** introduce sale pricing into the magazine product data.

From now on:

```text
price = regular/base non-discounted retail price
```

Never:

```text
price = current sale price
```

No `sale_price` is required for the THIS YOU production pipeline.

---

## Example

Retail page currently shows:

```text
Regular price: €64.99
Sale price: €39.00
```

THIS YOU result must contain:

```json
{
  "price": 64.99,
  "currency": "EUR"
}
```

The €39 temporary sale price is ignored.

---

## Budget validation

Budget rules must also use the **regular/base price**.

Reader input example:

```json
"budget_max_item": "100.00"
```

Validation:

```text
regular product price <= €100
```

NOT:

```text
sale price <= €100
```

Example:

```text
Regular price: €160
Sale price: €89
Reader max: €100
```

Result:

```text
REJECT
```

The product is outside the reader's configured budget even though it happens to be temporarily discounted.

This prevents the magazine from recommending something that returns to an unaffordable price while the issue is still being sold.

---

## Prompt update

Replace/extend the price rule with:

```text
PRICE POLICY: Always use the product's regular/base non-discounted retail price. Ignore temporary sale prices, promotional prices, member prices, coupon prices and campaign discounts. The `price` field must contain the regular/base price only. Budget validation must also use this regular/base price. If the regular/base price cannot be verified on the exact product page, replace the product.
```

---

# Updated selection rules

Recommended final `selection_rules` wording:

```json
{
  "budget": "Respect the reader budget using the regular/base non-discounted retail price only.",
  "price_policy": "The result price must always be the regular/base retail price. Ignore temporary sale, promotional, member, coupon and campaign prices.",
  "verification": "Use the exact selected product page and exact selected colour/variant. Every non-null price/color/availability statement must be checked on that exact page. Search snippets and cached prices are not valid final verification sources. If the regular price cannot be verified confidently, replace the product. Human verification in the admin remains mandatory."
}
```

---

# Result schema

No breaking schema migration is required.

Keep:

```json
{
  "slot_name": "outerwear / shirt / trousers / shoes / etc",
  "brand": "string",
  "product_name": "string",
  "color_name": "string",
  "price": 0,
  "currency": "EUR",
  "product_url": "https://exact-product-url",
  "match_level": "exact",
  "verification_note": "Exact product/variant and regular retail price verification note."
}
```

New semantic contract:

```text
price = verified regular/base retail price
```

---

# Admin UI

In the product approval screen:

### Display

Show:

```text
PRICE
€64.99
```

Do not show a sale badge or temporary discounted price from the product-selection result.

### Product link

The existing exact product URL remains the verification destination.

The reviewer must be able to open it directly and compare:

- product;
- colour;
- construction;
- regular price.

Human approval remains mandatory.

---

# Magazine rendering

Magazine / PDF / digital issue must use:

```text
product.price
```

Because `product.price` is now guaranteed to mean the regular/base price.

Do not dynamically replace it with a live sale price.

The product link can still take the reader to the retailer, where the retailer may show whatever current sale price applies at that moment.

---

# Acceptance criteria

A product may enter the approved product set only when all are true:

- [ ] Exact product URL opens the intended product.
- [ ] Brand matches.
- [ ] Product name/model matches.
- [ ] Selected colour/variant matches.
- [ ] Visible construction matches the intended hero-image item.
- [ ] Regular/base price is verified from the exact product page.
- [ ] Search snippets are not used as the authoritative price source.
- [ ] Temporary discount/sale price is ignored.
- [ ] `price` contains the regular/base price.
- [ ] Reader budget is checked against the regular/base price.
- [ ] If the regular price cannot be verified, the product is replaced.
- [ ] Human review is still required before image generation.

---

# Expected Chapter 1 behaviour

For the Weekday trousers reviewed during Chapter 1:

```text
Product:
Uno Loose Suit Trousers — Black

Regular price:
€64.99
```

The product result must therefore use:

```json
"price": 64.99,
"currency": "EUR"
```

even if another colour is discounted or the same product becomes temporarily discounted later.

---

## Summary

Two rules become mandatory:

1. **Exact-product verification**  
   Price must come from the exact selected product page and exact selected variant. No cached/search-result/other-variant prices.

2. **Regular price only**  
   THIS YOU uses the regular/base non-discounted price for product data, budget checking and magazine display. Temporary discounts are ignored.
