# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash npm run dev # Start dev server at localhost:3000 npm run build # Production build (TS errors and ESLint are suppressed — see next.config.mjs) npm run lint # ESLint check ``` No test framework is configured. ## Environment Variables `.env.local` for development: ``` NEXT_PUBLIC_API_BASE_URL=http://localhost:8080 BACKEND_BASE_URL=http://localhost:8080 LAUNCH_ONLY_ROOT=false # Set to "true" to restrict unauthenticated users to root page only NEXT_PUBLIC_SHORTLINK_BASE_URL=http://localhost:8080 ``` In Docker, the Spring Boot service is resolved as `http://battlbuilder-api:8080` (the default in `lib/springProxy.ts` when `SPRING_BASE_URL` is unset). ## Architecture ### Two backends 1. **Spring Boot** — primary data backend. All product catalog, builds, auth, merchant/admin data lives here. 2. **Sanity CMS** — content only (guides/blog posts). Project `zal102rv`, dataset `production`. Queries in `lib/sanity.ts`. ### API proxy pattern Next.js API routes (`app/api/`) act as a thin proxy to Spring Boot. Client code never calls Spring Boot directly. The helper `lib/springProxy.ts` forwards cookies and auth headers to Spring Boot and handles response serialization. ### Authentication - **Session cookie**: `session_token` HTTP-only cookie set by Spring Boot, forwarded by the proxy. - **Client state**: `AuthContext` (`context/AuthContext.tsx`) hydrates from `localStorage` on mount, then verifies against `/api/auth/me`. - **Middleware**: `middleware.ts` enforces route protection. Public paths are whitelisted; `/admin/*` requires login; `/builder`, `/builds`, `/vault` are gated only when `LAUNCH_ONLY_ROOT=true`. ### Route groups - `app/(app)/` — main consumer app layout (TopNav + Footer) - `app/(app)/(builder)/` — builder + parts browser (BuilderNav layout) - `app/(account)/` — account settings pages (AccountChrome sidebar layout) - `app/admin/` — internal admin tools (AdminLeftNavigation layout) - `app/api/` — 50 server-side route handlers proxying to Spring Boot ### Builder domain model The builder is AR-platform-centric. Key concepts: - **`BuilderSlotKey`** (`types/builderSlots.ts`) — the canonical kebab-case category ID (e.g., `"complete-upper"`, `"barrel"`). This is the source of truth for localStorage keys, URL state, and backend part role mapping. - **`CATEGORY_TO_PART_ROLES` / `PART_ROLE_TO_CATEGORY`** (`lib/catalogMappings.ts`) — bidirectional mapping between `BuilderSlotKey` and backend `partRole` strings. Update here when the backend adds new part roles. - **`BUILDER_SLOTS`** (`data/builderSlots.ts`) — defines slot groups (LOWER, UPPER, SYSTEM, ACCESSORIES) and satisfaction patterns (e.g., a complete lower satisfies the lower assembly slot). - **`BuildState`** — `Partial>` stored in `localStorage`. Product IDs are the values. - **Overlap detection** (`lib/buildOverlaps.ts`) — warns users when they select both a complete assembly and individual sub-parts. ### Legacy key aliases `types/builderSlots.ts` exports `normalizeSlotKey()` which maps camelCase legacy keys (e.g., `completeUpper`) to current kebab-case keys. This is needed for backwards-compatible URL/localStorage deserialization. ### API client pattern - Client components use `useApi()` hook (`lib/api.ts`) for fetch calls with `credentials: 'include'`. - Admin-specific API calls live in `lib/api/` (e.g., `adminCategoryMappings.ts`, `adminMerchantMappings.ts`). - Product catalog helpers are in `lib/catalog.ts`. ### Sanity content - `lib/sanity.ts` — Sanity client + GROQ queries for posts. - `lib/sanityFetch.ts` — low-level HTTPS fetch to Sanity IP (bypasses CDN DNS issues in server/Docker environments). - Guides at `/guides/[slug]` are the only public Sanity-driven pages.