# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Filamenteka is a 3D printing filament inventory management system for tracking Bambu Lab filaments. It consists of: - **Frontend**: Next.js app with React, TypeScript, and Tailwind CSS (static export) - **Backend**: Node.js API server with PostgreSQL database - **Infrastructure**: AWS (Amplify for frontend, EC2 for API, RDS for database) ## Critical Rules - NEVER mention ANY author in commits. No author tags or attribution - NEVER mention AI/assistant names anywhere - Keep commit messages clean and professional with NO attribution - Build for AMD64 Linux when deploying (development is on ARM macOS) - Always run security checks before commits ## Common Commands ```bash # Development npm run dev # Start Next.js development server (port 3000) npm run build # Build static export to /out directory npm run lint # Run ESLint npm test # Run Jest tests npm run test:watch # Run Jest in watch mode # Security & Quality npm run security:check # Check for credential leaks (scripts/security/security-check.js) npm run test:build # Test if build succeeds without creating files ./scripts/pre-commit.sh # Runs security, build, and test checks (triggered by husky) # Database Migrations npm run migrate # Run pending migrations locally npm run migrate:clear # Clear migration history (development only) scripts/update-db-via-aws.sh # Run migrations on production RDS via EC2 # Deployment scripts/deploy-api-update.sh # Deploy API to EC2 via AWS SSM (recommended) scripts/deploy-frontend.sh # Manual frontend deployment helper ``` ## Architecture ### Frontend Structure (Next.js App Router) - `/app` - Next.js 13+ app directory structure - `/page.tsx` - Public filament inventory table - `/upadaj` - Admin panel (password protected) - `/page.tsx` - Admin login - `/dashboard/page.tsx` - Filament CRUD operations - `/colors/page.tsx` - Color management - `/requests/page.tsx` - Customer color requests - `/src` - Source files - `/components` - React components - `/services/api.ts` - Axios instance with auth interceptors - `/data` - Color definitions (bambuLabColors.ts, bambuLabColorsComplete.ts) - `/types` - TypeScript type definitions ### API Structure - `/api` - Node.js Express server (runs on EC2, port 80) - `/server.js` - Main Express server with all routes inline - Database: PostgreSQL on AWS RDS - Endpoints: `/api/login`, `/api/filaments`, `/api/colors`, `/api/sale/bulk`, `/api/color-requests` ### Key Components - `FilamentTableV2` - Main inventory display with sorting/filtering - `SaleManager` - Bulk sale management interface - `ColorCell` - Smart color rendering with gradient support - `EnhancedFilters` - Advanced filtering system - `ColorRequestForm` - Customer color request form - `ColorRequestModal` - Modal for color requests ### Data Models #### Filament Schema (PostgreSQL) ```sql filaments: { id: UUID, tip: VARCHAR(50), # Material type (PLA, PETG, ABS) finish: VARCHAR(50), # Finish type (Basic, Matte, Silk) boja: VARCHAR(100), # Color name refill: INTEGER, # Refill spool count spulna: INTEGER, # Regular spool count kolicina: INTEGER, # Total quantity (refill + spulna) cena: VARCHAR(50), # Price sale_active: BOOLEAN, # Sale status sale_percentage: INTEGER,# Sale discount sale_end_date: TIMESTAMP # Sale expiry } ``` #### Color Schema ```sql colors: { id: UUID, name: VARCHAR(100), # Color name (must match filament.boja) hex: VARCHAR(7), # Hex color code cena_refill: INTEGER, # Refill price (default: 3499) cena_spulna: INTEGER # Regular price (default: 3999) } ``` #### Color Requests Schema ```sql color_requests: { id: UUID, color_name: VARCHAR(255), # Requested color name message: TEXT, # Customer message contact_name: VARCHAR(255), # Customer name (required) contact_phone: VARCHAR(50), # Customer phone (required) status: VARCHAR(20), # Status: pending, reviewed, fulfilled created_at: TIMESTAMP } ``` ## Deployment ### Frontend (AWS Amplify) - Automatic deployment on push to main branch - Build output: Static files in `/out` directory - Config: `amplify.yml`, `next.config.js` (output: 'export') - Security check runs during build (amplify.yml preBuild phase) ### API Server (EC2) - Deployment via `scripts/deploy-api-update.sh` (uses AWS SSM to push updates) - Instance ID: `i-03956ecf32292d7d9` - Server IP: `3.71.161.51` - Domain: `api.filamenteka.rs` - Service: `node-api` (systemd) - Deploy script pulls from GitHub main branch and restarts service - IMPORTANT: When deploying API, remember to build for AMD64 Linux (not ARM macOS) ### Database (RDS PostgreSQL) - Host: `filamenteka.ci7fsdlbzmag.eu-central-1.rds.amazonaws.com` - User: `filamenteka_admin` - Database: `filamenteka` - Migrations in `/database/migrations/` - Schema in `/database/schema.sql` - Use `scripts/update-db-via-aws.sh` for running migrations on production ## Important Patterns ### API Communication - All API calls organized in service modules (`src/services/api.ts`) - Services: `authService`, `colorService`, `filamentService`, `colorRequestService` - Axios instance with interceptors for automatic auth token injection - Auth token stored in localStorage with 24h expiry - Automatic redirect on 401/403 in admin routes (via response interceptor) - Cache busting on filament fetches with timestamp query param ### Color Management - Frontend color mappings in `src/data/bambuLabColors.ts` and `bambuLabColorsComplete.ts` - Database color definitions in `colors` table with pricing (cena_refill, cena_spulna) - ColorMapping interface supports both solid colors (hex string) and gradients (hex array) - Automatic row coloring via ColorCell component based on filament.boja - Special handling for gradient filaments (e.g., Cotton Candy Cloud) - Foreign key constraint: filaments.boja → colors.name (ON UPDATE CASCADE) ### State Management - React hooks for local component state - No global state management library - Data fetching in components with useEffect - Service layer handles all API interactions ### Testing - Jest + React Testing Library - Tests in `__tests__/` directory - Config: `jest.config.js`, `jest.setup.js` - Coverage goal: >80% - Run with `npm test` or `npm run test:watch` - Tests include: component tests, API integration tests, data consistency checks ## Environment Variables ```bash # Frontend (.env.local) NEXT_PUBLIC_API_URL=https://api.filamenteka.rs/api # API Server (.env in /api directory) DATABASE_URL=postgresql://filamenteka_admin:PASSWORD@filamenteka.ci7fsdlbzmag.eu-central-1.rds.amazonaws.com:5432/filamenteka JWT_SECRET=... ADMIN_PASSWORD=... NODE_ENV=production PORT=80 ``` ## Security Considerations - **Authentication**: JWT tokens with 24h expiry (hardcoded admin user for now) - **Password**: Stored in environment variable ADMIN_PASSWORD (bcrypt ready for multi-user) - **SQL Injection**: Prevented via parameterized queries in all database operations - **Credential Leak Detection**: Pre-commit hook runs `scripts/security/security-check.js` - **CORS**: Currently allows all origins (origin: true) - consider hardening for production - **Auth Interceptors**: Automatic 401/403 handling with redirect to login - **Pre-commit Checks**: Husky runs `scripts/pre-commit.sh` which executes: 1. Author mention check (blocks commits with attribution) 2. Security check (credential leaks) 3. Build test (ensures code compiles) 4. Unit tests (Jest with --passWithNoTests) ## Development Workflows ### Adding New Colors 1. Add color to database via admin panel (`/upadaj/colors`) OR via migration 2. Update frontend color mappings in `src/data/bambuLabColors.ts`: ```typescript 'Color Name': { hex: '#HEXCODE' } // Solid color 'Gradient Name': { hex: ['#HEX1', '#HEX2'], isGradient: true } // Gradient ``` 3. Color names must match exactly between database and filament.boja ### Database Migrations When modifying the database: 1. Create migration file in `/database/migrations/` with sequential numbering (e.g., `019_add_new_feature.sql`) 2. Test locally first with `npm run migrate` 3. Run migration on production: - Use `scripts/update-db-via-aws.sh` for remote execution via EC2 - Or SSH to EC2 and run migration directly 4. Update corresponding TypeScript types in `/src/types/` Important database constraints: - `filaments.boja` has foreign key to `colors.name` (ON UPDATE CASCADE) - `filaments.kolicina` has check constraint: `kolicina = refill + spulna` - Always update `colors` table first before adding filaments with new colors ### API Deployment Workflow 1. Make changes to `/api/server.js` 2. Commit and push to main branch 3. Run `./scripts/deploy-api-update.sh` (uses AWS SSM to pull from GitHub and restart) 4. Verify deployment: `curl https://api.filamenteka.rs/` should return `{"status":"ok"}` ### Frontend Deployment Workflow 1. Make changes to app/components/pages 2. Test locally: `npm run dev` 3. Run pre-commit checks: `./scripts/pre-commit.sh` 4. Commit and push to main branch 5. AWS Amplify automatically builds and deploys (monitors main branch) ## Infrastructure ### Terraform (IaC) Infrastructure as Code in `/terraform/`: - **VPC**: `vpc.tf` - Network setup with subnets and routing - **EC2**: `ec2-api.tf` - API server instance (i-03956ecf32292d7d9) - **RDS**: `rds.tf` - PostgreSQL database - **ALB**: `alb.tf` - Application Load Balancer - **ECR**: `ecr.tf` - Docker image registry - **CloudFront**: `cloudfront-frontend.tf` - Frontend CDN distribution - **Cloudflare**: `cloudflare-api.tf` - DNS integration for api.filamenteka.rs - **Configuration**: `variables.tf`, `outputs.tf`, `main.tf` ### Current Stack - **Frontend**: AWS CloudFront + S3 (static Next.js export) - **API**: EC2 instance running Node.js/Express with systemd service - **Database**: AWS RDS PostgreSQL (eu-central-1) - **DNS**: Cloudflare for api.filamenteka.rs - **Deployment**: AWS Amplify for frontend, SSM for API updates