# Attribution Capture

## Objective

Remember how someone arrived so a signup can be traced back to what brought them.

Durable capture of campaign parameters and referrer at first contact, carried through the signup journey and attached to the resulting account.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Capture campaign parameters and the referring document on the very first request of a visit, before any redirect, consent gate, or login bounce can strip them.
2. Store the captured values server-side against the visitor, then remove them from the URL. Do not thread the tags through every subsequent link — a campaign tag in a shared URL misattributes everyone who clicks it.
3. Keep both first touch and last touch as separate fields, and state which one the app reports on. Do not overwrite first touch, ever.
4. Validate against an allowlist of parameter names and cap each value's length. Anything unrecognised is discarded, not stored.
5. Attach the stored attribution to the account at creation and to the first purchase, then leave those records immutable.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Attribution must expire. Define a window — 30 or 90 days — after which a stale first touch stops being credited, or every customer is attributed to a campaign from a year ago.
- Campaign parameters must never reach application logs, error reports, or analytics payloads unfiltered — they routinely carry email addresses and personal identifiers.
- Never append captured tags to an outbound or external return URL. That leaks internal campaign structure to third parties.
- Direct traffic with no referrer is a real category. Record it as direct rather than leaving the field null and guessing later.
- Self-referrals from the app's own domain are not acquisition. Exclude the app's own hosts from the referrer.
- If capture requires consent under the visitor's jurisdiction, record nothing until consent is given — an unattributed signup is better than an unlawful one.
- Cross-device or cross-domain stitching needs an explicit consent basis and a stated identity rule. Do not silently join visitors by IP.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Source data is captured before any redirect or account creation can lose it.
- [ ] First touch and last touch are stored separately and first touch is never overwritten.
- [ ] Only allowlisted parameters within a length cap are stored; the rest are discarded.
- [ ] Captured parameters are scrubbed from URLs, logs, and outbound links.
- [ ] Attribution expires after a stated window rather than being credited indefinitely.
- [ ] Direct and self-referred traffic are classified explicitly, not left null.
- [ ] Attribution is written onto the account at signup and does not change afterwards.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
