# AGENTS.md

## Project identity

This repository contains a **generic reusable headless WooCommerce starter**.

It is not a shop for one brand only.
It is a template base that should be clean enough to clone and adapt for many future shops.

### Core stack
- Next.js App Router
- TypeScript
- Tailwind CSS
- WordPress as CMS
- WooCommerce as ecommerce backend
- Figma as the visual source of truth
- Codex as the coding assistant

### Main project goals
This starter must always stay:
- extremely fast
- reusable
- architecture-first
- production-ready
- easy to adapt to a new shop
- lightweight in frontend and backend behavior
- free of project-specific business logic unless the user explicitly wants it

### Primary technical priorities
In order of importance:
1. correct architecture
2. runtime performance
3. clean reuse
4. fidelity to Figma
5. maintainability
6. accessibility
7. developer clarity

When "quick implementation" conflicts with "correct reusable structure", choose reusable structure.

---

## Required project documents

When working in this starter, always use these files as mandatory sources of truth:

- `FIGMA_HANDOFF_RULES.md`
- `COMPONENT_ARCHITECTURE.md`
- `docs/figma/README.md`
- `docs/woocommerce-minimal-setup.md`

If these documents and the current code disagree:
- first inspect the current implementation
- then update the code or docs so they match
- do not ignore the mismatch

---

## Backend source of truth

### Environment-driven backend
This starter must never silently depend on one old shop domain.

Always use:
- `WORDPRESS_BASE_URL` from `.env.local`

The frontend should assume:
- Next.js runs locally during development
- WordPress and WooCommerce live on the domain defined by `WORDPRESS_BASE_URL`

### Allowed data sources
Use these as the source of truth:
- WordPress custom starter routes under `/wp-json/storefront/v1`
- WooCommerce Store API under `/wp-json/wc/store/v1`

Do not:
- hardcode one old production domain into business logic
- add shop-specific endpoints unless the starter is being intentionally extended for one project
- fetch the same domain through multiple conflicting base URL patterns

---

## Project structure

This starter should keep a stable architecture:

- `app/`
  Route files and API route handlers only
- `components/layout/`
  Shell elements like header, footer, page container
- `components/sections/`
  Page-level blocks such as hero, archive shell, product detail section, checkout section
- `components/ui/`
  Reusable UI primitives and cards
- `lib/`
  Data layer, API clients, shared helpers, route adapters
- `types/`
  Shared storefront domain types
- `wordpress/`
  Reusable WordPress / WooCommerce integration plugin code
- `docs/`
  Rules and setup instructions

Do not collapse these layers together without a strong reason.

---

## Required workflow for every implementation task

For each real implementation task:
1. summarize the scope
2. identify the affected area
3. inspect existing structure first
4. decide whether the task belongs to UI, section, route, data layer, utility, type, or plugin
5. explain the component/data split briefly
6. implement
7. review architecture
8. review performance
9. validate
10. summarize what changed

Do not jump straight into large code output without inspecting the existing starter.

---

## Reuse rules

### Reuse before creating
Before adding a new component, helper, or route:
- check if an equivalent already exists
- check whether composition is enough
- check whether a variant prop is enough
- avoid duplicate structures with slightly different names

### Keep the starter generic
Do not add:
- one-shop-only naming
- one-brand-only content logic
- custom checkout business rules that belong only to one client
- hardcoded design language for one specific brand

If the user wants a project-specific extension:
- implement it cleanly
- isolate it so the reusable base remains understandable

---

## Performance rules

This starter exists to be cloned into real shops, so performance is not optional.

Always consider:
- LCP
- CLS
- INP
- hydration cost
- client-side JS size
- number of requests
- route cacheability
- amount of duplicated backend fetch logic

### Server Components by default
Prefer Server Components for:
- page composition
- content rendering
- product/archive rendering
- initial cart/checkout state reads
- all static or mostly static sections

### Client Components only when justified
Use Client Components only for:
- interactivity
- local state
- browser APIs
- quantity controls
- cart mutations
- wishlist mutations
- checkout form state
- sliders and UI widgets that truly need the client

Do not move full pages to the client because of one interactive control.

### Minimize client boundaries
Keep client wrappers small.
Do not wrap large static trees in `"use client"` unless unavoidable.

### Avoid unnecessary network duplication
If two files do the same Woo Store API request/session handling:
- centralize it
- do not duplicate auth retry or header/session logic

---

## Data layer rules

### Normalize before rendering
Do not pass raw WordPress or WooCommerce responses directly into presentational UI if a mapping layer is appropriate.

Prefer:
1. fetch
2. validate / normalize
3. map to starter domain type
4. render

### Keep adapters focused
`lib/` should stay split by responsibility:
- content adapter logic
- cart runtime logic
- checkout runtime logic
- Woo client/session utilities
- WordPress route fetch utilities

Do not rebuild one giant `starter-data.ts` god file.

### API route handlers must stay thin
Files in `app/api` should:
- validate input
- call shared lib functions
- return responses

They should not contain deep business logic or repeated Store API orchestration.

---

## WordPress plugin rules

The plugin in `wordpress/` is part of the starter architecture, not a dump folder.

### Plugin responsibilities
The starter plugin should:
- expose lightweight reusable REST payloads
- keep response shapes stable
- use cache where it helps
- invalidate cache on relevant Woo/WordPress changes
- stay generic across shops

### Plugin must not become a monolith
Avoid:
- project-specific pricing rules
- heavy frontend formatting decisions that belong in Next.js
- giant route handlers with repeated query logic
- hardcoded brand/business assumptions unless they are generic enough for the starter

### Cache rules
If a route is stable enough to cache:
- cache it
- version cache groups
- invalidate them on product/variation/taxonomy changes

Do not cache:
- private cart state
- customer-specific state
- anything tied to the current session

---

## Figma-to-code rules

Figma is the visual source of truth for UI work.

If implementing from Figma:
- inspect the exact frame whenever possible
- preserve section boundaries
- preserve hierarchy
- preserve reusable component intent
- preserve state intent
- preserve spacing and rhythm

Do not:
- guess token values if they can be inspected
- invent hover/focus/empty/loading behavior without evidence
- merge multiple distinct sections into one giant component file

If something is unclear:
- say exactly what is unclear
- ask for clarification when it materially affects fidelity

More detailed rules live in:
- `FIGMA_HANDOFF_RULES.md`
- `docs/figma/README.md`

---

## Styling rules

Use Tailwind consistently.

Do:
- keep classlists readable
- extract repeated UI patterns
- preserve visual token consistency

Do not:
- improvise random spacing values without reason
- introduce unrelated styling systems
- hardcode one-brand palette into the base starter unless intentionally updating the template design

---

## Ecommerce rules

### Product UI
Product cards must remain reusable across:
- homepage
- archive
- related products
- wishlist
- sliders

### Archive filters
Archive filtering should stay scalable and extensible:
- desktop and mobile patterns should be supportable
- active filters should be cleanly represented
- URL sync is preferred when appropriate

### Cart and checkout
Cart and checkout must:
- use Woo Store API as the transactional source of truth
- keep mutation code centralized
- avoid fake local-only business states that drift from Woo

### Wishlist
Wishlist can remain lightweight if cookie-based, but its limits should stay obvious and documented.

---

## Validation rules

Before considering a task complete, validate with:
- `npm run typecheck`
- `npm run lint`
- `npx next build --webpack`

If something fails:
- fix it
- report it honestly
- do not pretend the task is done

If `next build` via Turbopack fails because of local sandbox/runtime behavior:
- confirm whether `npx next build --webpack` passes
- report the exact limitation clearly

---

## Forbidden patterns

Do not:
- hardcode one old shop domain into starter logic
- convert entire pages to Client Components without strong reason
- put major business logic inside JSX markup
- duplicate Store API session logic in multiple files
- let the WordPress plugin become one-shop-specific
- invent Figma values when inspectable values exist
- skip validation
- keep build artifacts committed in the starter

---

## Definition of done

A task in this starter is complete only if:
- architecture stays clean
- the change remains generic enough for a reusable base
- server/client boundaries still make sense
- data flow is centralized and understandable
- performance was considered
- Figma fidelity was respected where relevant
- docs were updated if behavior changed
- validation passed or any limitation was stated precisely
