# Developer Overview

> Curated onboarding runbook for developers working on the AMSOIL Dealer Landing Pages (DLP) codebase - the developer-facing sibling of [SUPPORT_OVERVIEW.md](./SUPPORT_OVERVIEW.md). **Read this once when you start a development task.** It points you at setup, shows where each system lives, lists the conventions that aren't obvious from the code, and links the deep-dive docs.

## How to use this doc

You're working on the platform through Claude Code (or by hand) with this docs MCP available. The general flow:

1. **Get oriented.** Skim the [System map](#system-map) to find which subsystem your task touches and which doc explains it.
2. **Read the relevant deep dive** before changing code - many systems have non-obvious invariants (tier gating, dealer identification, spam-check ordering) that are easy to break.
3. **Follow the conventions** in [Conventions & guardrails](#conventions--guardrails). They encode decisions that are otherwise invisible.
4. **Trust the code over the docs** when they disagree, and fix the doc. Docs describe how things are _supposed_ to work; the code is the source of truth.

## Getting set up

| Step               | Where                                                                                                   |
| ------------------ | ------------------------------------------------------------------------------------------------------- |
| Project intent     | [`../CLAUDE.md`](../CLAUDE.md) - why/what/how, plus the key constraints you must not violate            |
| First run          | [`../README.md`](../README.md) - quick start and tech stack                                             |
| Local dev + Stripe | [LOCAL_DEVELOPMENT.md](./LOCAL_DEVELOPMENT.md) - Stripe webhook forwarding, env routing, dev setup      |
| Architecture       | [ARCHITECTURE.md](./ARCHITECTURE.md) - ERD, tech stack, user journeys, sitemap (read with the diagrams) |
| Full docs index    | [overview.md](./overview.md) - every doc, grouped by topic                                              |

**Daily commands** (see [`../CLAUDE.md`](../CLAUDE.md) for the full list):

```bash
npm run power-cycle   # rebuild containers, keep data (daily use)
npm run clean-start   # wipe DB and rebuild from scratch (use when DB is broken)
npm run build         # production build
npm test              # Jest tests
```

**Worktrees are mandatory.** Never edit files directly in the main repo checkout. Create an isolated worktree (with its own ports) first:

```bash
./scripts/setup-worktree.sh my-feature feature/my-feature
```

**Dev auth for automated QA.** Test accounts (`test-*@claude.dev`) are seeded for browser automation; authenticate via `POST /api/dev/auth/login`. See the "Dev Auth for Automated QA" section of [`../CLAUDE.md`](../CLAUDE.md) for the account/tier table and security notes.

## System map

| Subsystem                | Where the code lives                                                            | Read this                                                                                |
| ------------------------ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Auth & registration      | NextAuth config, `app/api/auth/*`                                               | [auth/README.md](./auth/README.md), [REGISTRATION_SUMMARY.md](./REGISTRATION_SUMMARY.md) |
| Billing & subscriptions  | `lib/stripe-webhook-handlers.ts`, `app/api/webhooks/stripe`, `app/api/checkout` | [billing/README.md](./billing/README.md)                                                 |
| Tiers & feature gating   | `lib/plan-features.ts`, `lib/cms/types.ts`, `lib/tier-handlers.ts`              | [PLAN_FEATURES_MATRIX.md](./PLAN_FEATURES_MATRIX.md)                                     |
| Subdomains & domains     | `proxy.ts`, `lib/apex-config.ts`, `lib/domain-config.ts`                        | [subdomains/README.md](./subdomains/README.md)                                           |
| CMS & editors            | `lib/cms/*`, Puck/Lexical editors, `app/dashboard/*`                            | [editors/README.md](./editors/README.md), [DEALER_EDITORS.md](./DEALER_EDITORS.md)       |
| Lead / contact forms     | `app/api/contact/route.ts`, `app/components/contact-section.tsx`                | [LEAD_FORMS.md](./LEAD_FORMS.md)                                                         |
| Spam & bot protection    | `app/api/contact/route.ts`, `lib/turnstile.ts`, `lib/turnstile-pool.ts`         | [SPAM_PROTECTION.md](./SPAM_PROTECTION.md)                                               |
| Analytics & stats        | `app/api/stats/*`, `lib/stats-utils.ts`                                         | [analytics/README.md](./analytics/README.md), [STATS_API.md](./STATS_API.md)             |
| Email                    | `lib/email`, transactional templates                                            | [email/README.md](./email/README.md), [EMAIL_SERVICE.md](./EMAIL_SERVICE.md)             |
| Admin & impersonation    | `app/admin/*`, `app/api/admin/*`                                                | [admin/README.md](./admin/README.md), [ADMIN_IMPERSONATION.md](./ADMIN_IMPERSONATION.md) |
| Database                 | `prisma/schema.prisma`, `lib/prisma.ts`                                         | [db/README.md](./db/README.md), [PRISMA_JSON_SCHEMAS.md](./PRISMA_JSON_SCHEMAS.md)       |
| Support/admin MCP server | `mcp/dealer-lookup/*`                                                           | [MCP_DEVELOPMENT.md](./MCP_DEVELOPMENT.md), [MCP_SERVER.md](./MCP_SERVER.md)             |

## Deep dives

The systems most often touched - and most often gotten wrong - have dedicated developer docs:

- **[PLAN_FEATURES_MATRIX.md](./PLAN_FEATURES_MATRIX.md)** - the single source of truth for tier abilities and feature gating: the `*_TIERS` arrays and `has*Access()` accessors in `lib/cms/types.ts`, the Stripe price→tier mapping, and the checklist for adding a feature or a tier.
- **[SPAM_PROTECTION.md](./SPAM_PROTECTION.md)** - the defense-in-depth on the contact endpoint (Turnstile → honeypot → timing), why the order matters, and the edge rate-limiting layer.
- **[LEAD_FORMS.md](./LEAD_FORMS.md)** - lead form config, the multi-method dealer-identification logic (and why subdomain alone is unsafe), and the submission/email pipeline.
- **[analytics/README.md](./analytics/README.md)** - the pageview/click/lead tracking pipeline end to end, plus the tier gating and admin bypass.
- **[MCP_DEVELOPMENT.md](./MCP_DEVELOPMENT.md)** - how the `dealer-lookup` MCP server is built and how to add a tool.

## Common developer tasks

Step-by-step walkthroughs (each is one end-to-end change from source to test):

| Task                     | Guide                                                                                                                 |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Add a Puck component     | [editors/ADDING_A_PUCK_COMPONENT.md](./editors/ADDING_A_PUCK_COMPONENT.md)                                            |
| Add an email template    | [email/ADDING_AN_EMAIL_TEMPLATE.md](./email/ADDING_AN_EMAIL_TEMPLATE.md)                                              |
| Add a page type          | [ADDING_A_PAGE_TYPE.md](./ADDING_A_PAGE_TYPE.md)                                                                      |
| Add an API route         | [CONTRIBUTING.md#common-recipes](./CONTRIBUTING.md#common-recipes)                                                    |
| Add a tier-gated feature | [PLAN_FEATURES_MATRIX.md → Adding a feature with tier gating](./PLAN_FEATURES_MATRIX.md#adding-a-new-plan-or-feature) |
| Add an MCP tool          | [MCP_DEVELOPMENT.md](./MCP_DEVELOPMENT.md)                                                                            |

## Conventions & guardrails

These are project decisions that the code won't enforce for you. Most are recorded in [`../CLAUDE.md`](../CLAUDE.md); the consequential ones:

- **Worktrees only.** All edits go through a git worktree (`./scripts/setup-worktree.sh`), never the main checkout.
- **Migrations:** use `npx prisma migrate dev` (and `migrate deploy` in CI/prod). **Never `prisma db push`** - it bypasses migration tracking and causes drift.
- **Tier checks go through accessors.** Use `hasLeadFormAccess(tier)`, `hasCMSAccess(tier)`, etc. from `lib/cms/types.ts` - do **not** inline checks like `tier === 'professional'`. See [PLAN_FEATURES_MATRIX.md](./PLAN_FEATURES_MATRIX.md).
- **Publishing requires a ZO number.** A dealer can't publish without `dealerNumber`. `dealerNumber` is **intentionally nullable** - do not "fix" it with a `NOT NULL` migration (see [ZO_NUMBER_COMPLIANCE.md](./ZO_NUMBER_COMPLIANCE.md)). Add publish guards via `lib/zo-guard.ts`.
- **Dealer identification needs the full tuple.** Two dealers can share a subdomain across parent domains (`bobsoil.myamsoil.com` vs `bobsoil.shopamsoil.com`). Resolve on `(subdomain, domainPrefix, domain)`, never subdomain alone. See [LEAD_FORMS.md](./LEAD_FORMS.md).
- **Routing:** internal dealer-site routes live at `/sites/[subdomain]/[domainSlug]`; the proxy rewrites dealer hosts there. Authenticated users are redirected from `/` to `/dashboard` by `proxy.ts`. The old `/landing` route redirects to `/`.
- **Subdomains are read-only after creation** (admin override only).

## Testing

- Jest: `npm test`. Tests live next to the code (`__tests__/` or `*.test.ts`).
- Property-based testing with `fast-check` - when and how: [PROPERTY_BASED_TESTING.md](./PROPERTY_BASED_TESTING.md).
- The MCP server has its own suite under `mcp/dealer-lookup/__tests__/` - see [MCP_DEVELOPMENT.md](./MCP_DEVELOPMENT.md).

## Where the source of truth is

- **Runtime behavior:** the code, then the database. Docs are a map, not the territory - if a doc is wrong, fix it as part of your change.
- **Tier gating:** `lib/cms/types.ts` (runtime gates) and `lib/plan-features.ts` (display copy) - these are two separate tables that must agree in spirit; see the pitfalls in [PLAN_FEATURES_MATRIX.md](./PLAN_FEATURES_MATRIX.md).
- **Support-side context:** [SUPPORT_OVERVIEW.md](./SUPPORT_OVERVIEW.md) explains the system vocabulary (status enums, tiers, addons) from the dealer's perspective - useful when a bug report comes in through support.

## Related

- [overview.md](./overview.md) - full documentation index
- [SUPPORT_OVERVIEW.md](./SUPPORT_OVERVIEW.md) - support-side runbook (the sibling of this doc)
- [CONTRIBUTING.md](./CONTRIBUTING.md) - documentation standards and API-route recipe
