# Considered "Should I Buy This?" v1.0

Upload the **entire contents of this folder** (including the `affiliate-disclosure/` and `tests/` subfolders) to:

`/tools/should-i-buy-this/`

A private, browser-only purchase-decision calculator: total ownership cost, cost/year, cost/use, usage sensitivity, financing cost, optional opportunity cost, optional affordability context, and a multi-alternative comparison engine (buy new, buy used, keep, repair, rent, subscription, custom). It never outputs a Buy/Don't Buy verdict. Built from your "Should I Buy This?" Claude build brief.

## Before publishing — read this first

1. **Verify the Amazon link format yourself before going live.** This build environment has no access to your actual Amazon Associates account, so the "Search on Amazon" link format (`https://www.amazon.co.uk/s?k=<query>&tag=specgeek-21`) could not be checked against Amazon's own Link Checker/SiteStripe tools. It's the standard, widely-documented Associates search-link format, but the brief itself asks for this verification step before deployment (section 14) — please do that check before this goes live.
2. **The tracking ID is `specgeek-21`**, exactly as given in the brief, and it's the only thing you should need to change before this earns commission for the right account. See "Changing affiliate settings" below — it's one line, in one file.
3. Upload the whole folder, not individual files — the calculator, the affiliate disclosure page and the test suite are one deliverable.

## Architecture — why this is four JS files, not one

The brief's most important structural requirement is that affiliate monetisation must be a **separate module from the calculation engine**, with no commission rate ever able to influence a calculated result or comparison ordering. That's enforced by keeping these completely independent:

- **`calc.js`** — the calculation engine. Pure functions only: given some numbers, returns some numbers. No DOM access, no network access, and — this is the important part — no function in this file has a parameter for a commission rate, a provider ID, or anything else from `affiliate.js`. It doesn't know affiliates exist.
- **`affiliate.js`** — the provider registry. Decides what commercial links (if any) to show, after a calculation has already happened. No function in this file receives a calculated cost or comparison result as an input — it only ever receives a product name/category and returns a link. It doesn't know how anything was calculated.
- **`analytics.js`** — the event-tracking stub (see "Analytics" below).
- **`app.js`** — the only file that touches both of the above. It reads the DOM, calls `calc.js` to get numbers, renders them, and separately calls `affiliate.js` to get retailer links and renders those in their own area of the page. It never passes one module's output into the other.

You can see this enforced in the tests too — `tests/calc.test.js` has a test asserting `compareAlternatives` takes exactly one argument (no room for a commission parameter to sneak in later), and `tests/affiliate.test.js` asserts the provider registry never carries a `commission`/`payoutRate` field.

## Changing affiliate settings

**Everything is in `affiliate.js`, in the `PROVIDERS` array near the top of the file.** That's the one place to look for all of this:

- **Change the Amazon tracking ID:** edit the `trackingId` value on the `amazon_uk` provider object. The brief expects this to move from `specgeek-21` to a dedicated tool tracking ID (e.g. `consideredtools-21`) at some point — it's a one-line change.
- **Disable Amazon (or any provider) entirely:** set `enabled: false` on its object. It disappears from the retailer area immediately, no other code changes needed.
- **Add a new provider (eBay, Awin, Impact, a direct brand, etc.):** add a new object to the `PROVIDERS` array with the same shape as the Amazon one (see the comment block above the array for what every field means) and a `buildLink()` function for it. Nothing in `app.js` or `calc.js` needs to change — `app.js` already loops over whatever `affiliate.getEnabledProviders()` returns.
- **Change button text or disclosure wording:** `buttonLabel` and `disclosureText` on the relevant provider object. The site-wide "some links are affiliate links..." line lives in the `TOOL_LEVEL_DISCLOSURE` constant just below the `PROVIDERS` array. The dedicated disclosure page's copy is in `affiliate-disclosure/index.html` and isn't config-driven (it's a page of prose) — edit it directly if the Amazon disclosure wording or programme rules change.
- **Restrict a provider to certain categories:** set `categories` to an array of category values (see the `<select id="productCategory">` options in `index.html` for the valid values) instead of `null`.

Nothing here is a secret — tracking IDs are public campaign identifiers that appear in the outbound URL anyway, so they're fine to keep in this browser-side config file. If a future provider integration ever needs an actual secret API key, that belongs in a server-side environment variable behind an endpoint, never in this repository.

## v1 scope vs what's deferred

**Built now** (per the brief's "Suggested v1 scope"): manual product/category/price entry, ownership period, usage, running/maintenance/setup costs, resale value, total ownership cost, cost/year, cost/use, usage sensitivity + "what if I stop using it?", usage break-even, a multi-alternative comparison engine, financing (cash/0%/interest-bearing), optional opportunity cost, optional affordability context, client-side-only privacy, responsive layout, a central affiliate provider registry, the Amazon UK provider with the configurable tracking ID, configurable disclosures, a generic retailer link area, and analytics hooks that exclude personal financial values.

**Deliberately not built yet** (per the brief's "Do not block v1 on" / "Future phases"): live price comparison or retailer APIs, a curated product/ASIN catalogue, additional affiliate providers beyond Amazon, an account system, server-side storage, and local save/export. Adding any of these later should mostly be additive — see "Architecture" above for why the affiliate side in particular should stay a registry change rather than a rewrite.

**One v1 simplification worth knowing about:** alternatives in the comparison engine take a single combined "annual running cost" figure rather than the full repeatable running-cost list the main product gets. This keeps the comparison form usable for adding several alternatives quickly; if you find yourself wanting itemised running costs per alternative too, that's a reasonable follow-up but wasn't in the v1 brief's worked examples.

## Analytics

**v1 ships with no live analytics backend, by design.** Every other tool on the site advertises "zero external network requests" as an explicit trust feature, and there's no analytics platform already wired into the site to plug this into — so rather than guess at one, `analytics.js` defines the event hooks the brief asks for (`calculator_started`, `category_selected`, `calculation_completed`, `retailer_clicked` with provider name) and `app.js` already calls them at the right moments, but `trackEvent()` itself is currently a no-op. Nothing is sent anywhere in this version.

When you're ready to wire up a real provider, `analytics.js` is the only file to touch — see the commented example calls (Plausible/Fathom/GA4) inside `trackEvent()`. Whatever you wire in, keep to what's already being passed: only category-level, non-sensitive event data, never a price, income, savings, debt or other financial value. You can preview what's being called and with what data right now by setting `window.__SIBT_DEBUG_ANALYTICS__ = true` in the browser console — it'll log each event instead of doing nothing.

## Testing

Unit tests cover the calculation engine and the affiliate registry — the two things it matters most to get right and keep right as this evolves. Run them with Node (no install needed, uses Node's built-in test runner — tested on Node 22):

```
node --test tests/*.test.js
```

25 tests, covering: the exact worked example from the build brief (£1,599 purchase, £2.63/use), zero/negative-input edge cases, usage sensitivity and early-stop scenarios, all three financing methods, opportunity cost compounding, affordability context (including that it never produces a verdict field), the comparison engine's alternative-ordering guarantee, and the affiliate registry's link generation and its guarantee of never carrying a commission-rate field.

The calculator itself was also checked end-to-end with Playwright: the brief's worked example reproduces exactly (£2,049 total cost, £2.63/use), all optional sections (financing, opportunity cost, affordability, alternatives) show/hide and calculate correctly, the retailer area builds a correct Amazon search link and shows a sensible message when no product name has been entered yet, and both desktop and mobile layouts were screenshotted and reviewed.

## File structure

```
index.html                    the calculator page
affiliate-disclosure/index.html   the dedicated affiliate disclosure page (linked from the tool + footer)
calc.js                        calculation engine (pure, no DOM/network/affiliate knowledge)
affiliate.js                   affiliate provider registry — EDIT HERE for tracking IDs/providers
analytics.js                   analytics event stub — EDIT HERE to wire up a real provider later
app.js                         UI controller — wires calc.js + affiliate.js + analytics.js to the DOM
styles.css                     stylesheet, matches the rest of the site's dark theme
tests/calc.test.js             unit tests for the calculation engine
tests/affiliate.test.js        unit tests for the affiliate registry
considered-header-logo.png     header logo (same asset used across the site)
robots-addition.txt, sitemap-entry.xml   as usual for this site
```

## Version 1.0

Initial release, built from the "Should I Buy This?" Claude build brief. Total ownership cost, cost/year, cost/use, usage sensitivity and break-even, financing (cash / 0% / interest-bearing), optional opportunity cost, optional affordability context, and a multi-alternative comparison engine, plus a central affiliate provider registry with Amazon UK as the only configured provider so far. See "v1 scope vs what's deferred" above for the roadmap.
