Files
Filamenteka/CLAUDE.md
DaX 58c165749d
Some checks failed
Deploy / deploy (push) Failing after 6m11s
Migrate from GitHub to Gitea with CI/CD
- Add Gitea Actions workflow for automated frontend and API deployment
- Update all raw download URLs from GitHub to Gitea
- Remove deprecated Amplify config and GitHub-specific Terraform variables
- Clean up commented-out Amplify resources from Terraform
- Update documentation to reflect new repository and CI/CD setup
2026-02-16 00:35:08 +01:00

11 KiB

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 (CloudFront + S3 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

# Frontend 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 run typecheck        # Run TypeScript type checking
npm test                 # Run Jest tests
npm run test:watch       # Run Jest in watch mode

# API Development (in /api directory)
cd api && npm run dev    # Start API server with nodemon (port 4000)

# 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
  • BulkFilamentPriceEditor - Bulk price modification interface
  • ColorCell - Smart color rendering with gradient support
  • EnhancedFilters - Advanced filtering system
  • ColorRequestForm - Customer color request form
  • ColorRequestModal - Modal for color requests
  • SaleCountdown - Sale timer display
  • MatomoAnalytics - Analytics tracking
  • BackToTop - Scroll-to-top button
  • MaterialBadge, ColorSwatch, InventoryBadge - Display components

Data Models

Filament Schema (PostgreSQL)

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

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

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 CloudFront + S3)

  • Primary Method: CloudFront distribution with S3 origin
  • S3 bucket: filamenteka-frontend
  • CloudFront Function: index-rewrite for directory-to-index.html routing
  • Build output: Static files in /out directory (Next.js static export)
  • Config: next.config.js (output: 'export'), terraform/cloudfront-frontend.tf
  • Cache: 24h TTL for static assets, GET/HEAD methods cached
  • OAC (Origin Access Control): S3 public access blocked, CloudFront-only access
  • CI/CD: Gitea Actions workflow (.gitea/workflows/deploy.yml) auto-deploys on push to main

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 Gitea 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
  • Test files include:
    • ui-features.test.ts - UI functionality
    • api-integration.test.ts - API interactions
    • no-mock-data.test.ts - Real data validation (ensures no fake/mock data)
    • color-management.test.ts - Color CRUD operations
    • data-consistency.test.ts - Data validation
    • components/*.test.tsx - Component unit tests
    • data/*.test.ts - Data structure validation

Environment Variables

# 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:
    '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

Deployment Workflow (Gitea Actions CI/CD)

Pushing to main triggers .gitea/workflows/deploy.yml which auto-detects what changed:

  • Frontend changes: Runs security check, tests, builds Next.js, deploys to S3 with cache headers, invalidates CloudFront
  • API changes: Sends SSM command to EC2 to download server.js from Gitea and restart the service
  • Both: If a push touches frontend and API files, both deploy steps run

Manual deployment is still available:

  1. Frontend: ./scripts/deploy-frontend.sh
  2. API: ./scripts/deploy-api-update.sh
  3. Verify API: curl https://api.filamenteka.rs/ should return {"status":"ok"}

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
  • CI/CD: Gitea Actions (.gitea/workflows/deploy.yml)
  • Deployment: CloudFront + S3 for frontend, SSM for API updates
  • Repository: git.demirix.dev/dax/Filamenteka
  • CDN: CloudFront PriceClass_100 (US, Canada, Europe)