Files
ballistic-builder-spring/CLAUDE.md
Sean 9ec229d4dd added claude.md for ai context and development guidance
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 18:40:48 -05:00

12 KiB

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

# 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

# Run all tests
mvn test

# Run specific test class
mvn test -Dtest=PlatformResolverTest

# Run with coverage
mvn clean test jacoco:report

Database

# PostgreSQL connection details in application.properties
# Default: jdbc:postgresql://r710.gofwd.group:5433/ss_builder
# User: postgres

API Documentation

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 <token> 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:

# 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