3.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
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
- Spring Boot — primary data backend. All product catalog, builds, auth, merchant/admin data lives here.
- Sanity CMS — content only (guides/blog posts). Project
zal102rv, datasetproduction. Queries inlib/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_tokenHTTP-only cookie set by Spring Boot, forwarded by the proxy. - Client state:
AuthContext(context/AuthContext.tsx) hydrates fromlocalStorageon mount, then verifies against/api/auth/me. - Middleware:
middleware.tsenforces route protection. Public paths are whitelisted;/admin/*requires login;/builder,/builds,/vaultare gated only whenLAUNCH_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 betweenBuilderSlotKeyand backendpartRolestrings. 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<Record<BuilderSlotKey, string>>stored inlocalStorage. 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 withcredentials: '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.