diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..f795f41 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,357 @@ + +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Ballistic Builder is a **PCPartPicker-style platform for firearms**, starting with the AR-15 ecosystem. It's a Spring Boot 3.4.3 application that: +- Ingests merchant feeds (AvantLink) and normalizes product data +- Manages complex category mappings and part role classification +- Provides REST APIs for a consumer-facing Builder application +- Enables users to browse parts, compare prices, and assemble builds + +**Critical: This is NOT**: +- An e-commerce platform (does not sell products) +- A marketplace (does not process payments) +- A forum-first community +- An inventory management system + +**It IS**: +- An affiliate-driven aggregation platform +- A data normalization engine disguised as a UI +- Focused on accuracy, clarity, and trust + +Think: *"Build smarter rifles, not spreadsheets."* + +## Core Principles + +When working on this codebase, always prioritize: +- **Accuracy > Completeness** - Correct data is more important than comprehensive data +- **Idempotency > Speed** - Operations must be safely repeatable +- **Explicit data > Heuristics** - Prefer manual mappings over inference when accuracy matters +- **Long-term maintainability > Cleverness** - Code readability 6-12 months out matters more than clever abstractions +- **Incremental delivery** - Small team, phased solutions, clear migration paths + +Avoid introducing: +- Real-time inventory guarantees (merchant feeds are authoritative) +- Payment processing or checkout flows +- Legal/compliance risk (this is an aggregator, not a retailer) +- Over-engineered abstractions or premature optimization +- "Rewrite everything" solutions + +## Common Commands + +### Build & Run +```bash +# Clean build +mvn clean install + +# Run development server (port 8080) +mvn spring-boot:run + +# Run with Spring Boot DevTools hot reload +mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" +``` + +### Testing +```bash +# Run all tests +mvn test + +# Run specific test class +mvn test -Dtest=PlatformResolverTest + +# Run with coverage +mvn clean test jacoco:report +``` + +### Database +```bash +# PostgreSQL connection details in application.properties +# Default: jdbc:postgresql://r710.gofwd.group:5433/ss_builder +# User: postgres +``` + +### API Documentation +- Swagger UI: http://localhost:8080/swagger-ui.html +- OpenAPI spec: http://localhost:8080/v3/api-docs + +## Architecture Overview + +### Layered Architecture Pattern +``` +Controllers (REST API endpoints) + ↓ +Services (Business logic + validation) + ↓ +Repositories (Spring Data JPA) + ↓ +Models (JPA Entities) + ↓ +PostgreSQL Database +``` + +### Package Structure + +**Core Packages:** +- `catalog/classification/` - Platform resolution and product classification engine +- `controllers/` - REST API endpoints (v1 convention, admin panel) +- `enrichment/ai/` - AI-powered product data enhancement (OpenAI integration) +- `imports/` - CSV/TSV feed import functionality for merchant data +- `model/` - JPA entities (Product, User, Build, Brand, Merchant, etc.) +- `repos/` - Spring Data JPA repositories +- `security/` - JWT authentication, token validation, user details +- `services/` - Business logic layer (interface + impl pattern) +- `web/dto/` - Data Transfer Objects for API contracts +- `web/mapper/` - Entity to DTO conversion utilities + +### Key Technologies +- Java 21 +- Spring Boot 3.4.3 (Spring Data JPA, Spring Security, Spring Mail) +- PostgreSQL 42.7.7 with HikariCP connection pooling +- JWT authentication (JJWT 0.11.5) +- MinIO 8.4.3 (S3-compatible object storage for images) +- Apache Commons CSV 1.11.0 (feed processing) +- SpringDoc OpenAPI 2.8.5 (API documentation) + +## Critical Domain Concepts + +### Product Classification System + +**Platform Resolution**: Products are automatically classified to gun platforms (AR-15, AK-47, etc.) using rule-based logic in `catalog/classification/PlatformResolver`. Rules are stored in the `platform_rule` table and evaluated against product attributes (name, brand, MPN, UPC). + +**Part Role Mapping**: Products are assigned part roles (Upper Receiver, Barrel, etc.) through: +1. Automatic classification via `PartRoleRule` entities +2. Manual merchant category mappings in `MerchantCategoryMap` +3. Manual overrides with `platform_locked` flag + +**Category Normalization**: Raw merchant categories are mapped to `CanonicalCategory` through `CategoryMapping` entities. Unmapped categories are exposed in the admin UI for manual assignment. + +### Merchant Feed Ingestion (Critical) + +The import system is the **heart of the platform**. The `imports/` package handles CSV/TSV feed imports from AvantLink merchants with these critical characteristics: + +**Idempotency by Design**: +- Safe to re-run repeatedly without side effects +- Never duplicates products or offers +- Handles dirty, malformed, or incomplete feeds gracefully + +**Import Modes**: +1. **Full Import** - Products + offers (initial or full sync) +2. **Offer-Only Sync** - Price/stock refresh for existing products + +**Deduplication Rules**: +- Products deduped by **Brand + MPN** (primary key combination) +- UPC fallback for future enhancement +- Offers are **merchant-specific** (same product can have multiple offers) +- Offers track `firstSeenAt` and `lastSeenAt` timestamps + +**Process Flow**: +- Auto-detects delimiters (CSV/TSV) +- Creates or updates `Product` entities +- Upserts `ProductOffer` entities (price, stock, merchant URL) +- Tracks `FeedImport` status and history +- Logs errors without breaking entire import + +**Never Break Idempotency** - Any change to the import system must maintain the property that running imports multiple times produces the same result. + +### Build System + +Users create gun builds (`Build` entity) composed of `BuildItem` entities. Each build can be: +- Public (visible in community) +- Private (user-only) +- Linked to specific platforms +- Priced via aggregated `ProductOffer` data + +### Authentication & Authorization + +**JWT Flow**: +1. User logs in via `/api/auth/login` +2. `JwtService` generates access token (48-hour expiry) +3. Token stored in `AuthToken` table +4. `JwtAuthenticationFilter` validates token on each request +5. Principal stored as UUID string in SecurityContext + +**Roles**: USER, ADMIN (role-based access control via Spring Security) + +**Magic Links**: Users can request passwordless login links (30-day token expiry) + +## Performance Considerations + +### Recent Optimizations +- **API batch sizes reduced**: Catalog endpoints previously returned 2000 products per call, now paginated to ~48 items +- **DTO optimization**: `ProductDTO` streamlined for faster serialization +- **N+1 query prevention**: Use `@EntityGraph` annotations to eagerly fetch relations + +### Caching Strategy +- Spring Caching enabled globally (`@EnableCaching`) +- Product details cached in `ProductV1Controller` +- Clear cache after imports or admin updates + +### Database Query Patterns +- Use `JpaSpecificationExecutor` for dynamic filtering +- Complex aggregations use native PostgreSQL queries +- HikariCP max connection lifetime: 10 minutes + +## API Design Patterns + +### Endpoint Conventions +- Public API: `/api/v1/{resource}` +- Admin API: `/api/v1/admin/{resource}` +- Auth endpoints: `/api/auth/{action}` +- Legacy endpoints return 410 Gone (intentionally deprecated) + +### Request/Response Flow +1. Controller receives request with DTOs +2. Validates input (Spring Validation) +3. Maps DTO to entity via mapper +4. Calls service layer (business logic) +5. Service interacts with repositories +6. Maps entity back to DTO +7. Returns JSON response + +### Authorization Patterns +- JWT token in `Authorization: Bearer ` header +- Role checks via `@PreAuthorize("hasRole('ADMIN')")` or SecurityConfig rules +- User identity extracted from SecurityContext via `JwtAuthenticationFilter` + +## Common Development Patterns + +### Adding a New API Endpoint +1. Create DTO classes in `web/dto/` (request + response) +2. Create/update service interface in `services/` +3. Implement service in `services/impl/` +4. Create controller in `controllers/` (follow naming: `{Resource}V1Controller`) +5. Inject service via constructor +6. Add authorization rules in `SecurityConfig` or `@PreAuthorize` +7. Document with SpringDoc annotations (`@Operation`, `@ApiResponse`) + +### Entity Relationships +- Use `@EntityGraph` to prevent N+1 queries +- Soft delete pattern: `deletedAt` field (filter `WHERE deleted_at IS NULL`) +- Temporal tracking: `createdAt`, `updatedAt` via `@PrePersist`/`@PreUpdate` +- Avoid bidirectional relationships unless necessary + +### Service Layer Pattern +- Define interface: `public interface BrandService { ... }` +- Implement: `@Service public class BrandServiceImpl implements BrandService` +- Use constructor injection for dependencies +- Handle business logic, validation, and transactions + +## Configuration + +### Environment-Specific Settings +Key properties in `src/main/resources/application.properties`: + +```properties +# Database +spring.datasource.url=jdbc:postgresql://r710.gofwd.group:5433/ss_builder + +# JWT +security.jwt.secret=ballistic-test-secret-key-... +security.jwt.access-token-minutes=2880 # 48 hours + +# MinIO (image storage) +minio.endpoint=https://minioapi.dev.gofwd.group +minio.bucket=battlbuilders +minio.public-base-url=https://minio.dev.gofwd.group + +# Email (SMTP) +spring.mail.host=mail.goforwardmail.com +spring.mail.username=info@battl.builders + +# AI/OpenAI +ai.openai.apiKey=sk-proj-... +ai.openai.model=gpt-4.1-mini +ai.minConfidence=0.75 + +# Feature Flags +app.api.legacy.enabled=false +app.beta.captureOnly=true +app.email.outbound-enabled=true +``` + +### CORS Configuration +Allowed origins configured in `CorsConfig`: +- `http://localhost:3000` (React dev) +- `http://localhost:8080`, `8070`, `4200`, `4201` + +## Important Notes + +### Legacy Code +- `ProductController` intentionally returns 410 Gone (deprecated API v0) +- Old `Account` model coexists with newer `User` model +- JSP support included but not actively used + +### Security Warnings +- Credentials in `application.properties` should use environment variables in production +- Rotate OpenAI API key regularly +- Use secrets manager for email passwords +- Ensure magic link tokens have short expiration + +### Multi-Tenancy +- System supports multiple merchants via `Merchant` entity +- Category mappings are merchant-specific (`MerchantCategoryMap`) +- Platform rules engine allows per-merchant classification overrides + +### Testing Strategy +- TestNG framework included +- Minimal test coverage currently +- Key test: `PlatformResolverTest` for classification logic +- Integration tests should cover feed import flows + +## Development Constraints & Guidelines + +### Team Context +This is a **small team** building for **longevity and credibility**. Code decisions should account for: +- Code readability 6-12 months from now +- Incremental delivery over big-bang rewrites +- Clear migration paths when refactoring +- Minimal external dependencies unless truly necessary + +### When Proposing Changes +- **Feature requests**: Propose phased, minimal solutions +- **Refactors**: Explain tradeoffs and provide migration steps +- **Debugging**: Reason from architecture first (check layers: controller → service → repo → entity) +- **Design questions**: Follow the PCPartPicker mental model +- **Scaling concerns**: Assume success but move incrementally + +### What NOT to Suggest +- Rewriting large portions of the codebase +- Adding frameworks for problems that don't exist yet +- Magical inference engines or hidden behavior +- Solutions that introduce legal/compliance risk +- Features that assume this is an e-commerce checkout platform + +### Frontend Assumptions +The Next.js/React frontend depends on this backend for: +- Normalized APIs (backend owns business logic) +- Part role authoritative data +- Backend-driven compatibility rules +- No duplication of backend logic in frontend + +## How to Work with This Codebase + +### To Understand a Feature +1. Find the REST endpoint in `controllers/` +2. Trace the service call in `services/` (interface → impl) +3. Check repository queries in `repos/` +4. Review model relationships in `model/` +5. Check DTOs in `web/dto/` for request/response contracts + +### To Debug an Issue +1. Check controller layer for request validation +2. Verify service layer business logic +3. Inspect repository queries (check for N+1) +4. Review entity relationships and fetch strategies +5. Check application.properties for configuration issues +6. Review logs for SQL queries (Hibernate logging) + +### Red Flags to Watch For +- Breaking idempotency in import system +- Introducing N+1 query problems +- Adding credentials to application.properties +- Creating bidirectional JPA relationships without careful consideration +- Bypassing the service layer from controllers +- Duplicating business logic in DTOs or controllers diff --git a/ai-context.md b/ai-context.md new file mode 100644 index 0000000..e69de29