# CMN Test Store — Spec

Static site at `testcmn.nestorhawk.com` used to validate a network's readiness for Google's Commerce Media Network (CMN) integration via Zitcha. Purpose: fire GA4 events with cart data that align exactly with a Merchant Centre feed, so brand-level attribution can be verified end-to-end.

Reference: [CMN Network Readiness Guide](https://zitcha.atlassian.net/wiki/spaces/ZS/pages/2099740686/CMN+Network+Readiness+Guide)

## What this site must do

1. Load the GA4 gtag with a configurable Measurement ID.
2. Render a product catalogue (6 SKUs, 3 brands) that mirrors the Merchant Centre feed exactly.
3. Fire GA4 events on user interaction:
   - `session_start` — automatic via gtag config
   - `add_to_cart` — when a product is added
   - `purchase` — on checkout completion
4. Every `add_to_cart` and `purchase` event must carry cart-data parameters (`item_id`, `quantity`, `price`, `currency`) per line item, plus `transaction_id` on purchase.

## Source of truth: SKU catalogue

Keep these identical between the site's product data and the Merchant Centre feed. `item_id` (GA4) must equal `id` (feed) character-for-character — this is the #1 CMN onboarding failure.

| item_id | title | brand | price | currency |
|---|---|---|---|---|
| SKU-NIKE-001 | Nike Air Trainer | Nike | 120.00 | USD |
| SKU-NIKE-002 | Nike Running Shorts | Nike | 45.00 | USD |
| SKU-APPL-001 | Apple Watch SE | Apple | 280.00 | USD |
| SKU-APPL-002 | AirPods Pro | Apple | 250.00 | USD |
| SKU-ADID-001 | Adidas Samba | Adidas | 110.00 | USD |
| SKU-ADID-002 | Adidas Track Jacket | Adidas | 85.00 | USD |

## GA4 event schema

**`add_to_cart`**
```js
gtag('event', 'add_to_cart', {
  currency: 'USD',
  value: <unit_price>,
  items: [{
    item_id: 'SKU-...',
    item_name: '...',
    item_brand: '...',
    price: <unit_price>,
    quantity: 1
  }]
});
```

**`purchase`**
```js
gtag('event', 'purchase', {
  transaction_id: 'T-<timestamp>',
  currency: 'USD',
  value: <cart_total>,
  items: [ /* one entry per cart line, same shape as above */ ]
});
```

## Configuration

- GA4 Measurement ID should be read from an env-style constant or single `const` at the top of the script (find/replace friendly). Currently placeholder: `PASTE_MEASUREMENT_ID_HERE`.
- `debug_mode: true` must stay on until we're done with DebugView validation.

## Merchant Centre feed

Feed lives at `/feed.tsv` (or wherever the repo places it). Columns:

```
id  title  description  link  image_link  availability  price  condition  brand  custom_label_0  google_product_category
```

- `id` values must match the catalogue above exactly.
- `link` values point to `https://testcmn.nestorhawk.com/product/<id>` — these product detail pages don't need to exist for CMN validation, but returning a 200 is nicer than a 404 if we ever want to verify the feed properly.
- `brand` populated on every row.
- `custom_label_0` populated (used as an alternative filter dimension).

## Verification checklist

- [ ] Site loads at `testcmn.nestorhawk.com` with no console errors
- [ ] `googletagmanager.com/gtag/js?id=G-...` network request fires on page load with real Measurement ID (not placeholder)
- [ ] `session_start` appears in GA4 DebugView within seconds of load
- [ ] Clicking "Add to cart" fires `add_to_cart` with `items[]` populated
- [ ] Clicking "Complete purchase" fires `purchase` with `transaction_id`, `currency`, `value`, and full `items[]`
- [ ] Every line item in every event carries `item_id`, `quantity`, `price`, `currency`
- [ ] A given `item_id` from a DebugView event exists as `id` in `feed.tsv` character-for-character

## Screenshots needed (for the Confluence guide)

1. GA4 DebugView with a `purchase` event and expanded `items[]`
2. Same event drilled into a single line item showing `item_id`, `quantity`, `price`, `currency`
3. Side-by-side of GA4 `item_id` and Merchant Centre `id` matching
4. Merchant Centre products list with `brand` and `custom_label` columns visible
5. Google Ads MCC (create screen or existing MCC overview)
6. GA4 Property Access Management showing admin role

## Out of scope for this repo

- Real product detail pages
- Real payment flow
- Server-side rendering / analytics
- Authentication

Everything is client-side static. The goal is signal fidelity, not UX polish. Add summary somewhere so we know what exist on page.
