# 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 to `/out`)
- **Backend**: Node.js Express API server (`/api/server.js`) with PostgreSQL database
- **Infrastructure**: AWS (CloudFront + S3 for frontend, EC2 for API, RDS for database)
- **Repository**: `git.demirix.dev/dax/Filamenteka`

## Critical Rules

- NEVER mention ANY author in commits. No author tags or attribution of any kind
- Build for AMD64 Linux when deploying (development is on ARM macOS)
- Always run security checks before commits (Husky pre-commit hook does this automatically)

## Common Commands

```bash
# Development
npm run dev              # Start Next.js dev server (port 3000)
npm run build            # Build static export to /out
npm run lint             # ESLint
npm test                 # Jest tests
npm run test:watch       # Jest watch mode
npm test -- --testPathPattern=__tests__/components/ColorCell  # Run single test file

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

# Quality Gates
npm run security:check   # Credential leak detection
npm run test:build       # Verify build succeeds without deploying
npx tsc --noEmit         # TypeScript type checking

# Database
npm run migrate          # Run pending migrations locally
scripts/update-db-via-aws.sh  # Run migrations on production RDS via EC2

# Deployment (auto via CI/CD on push to main, or manual)
scripts/deploy-api-update.sh  # Deploy API to EC2 via AWS SSM
scripts/deploy-frontend.sh    # Manual frontend deploy to S3/CloudFront
```

## Architecture

### Frontend (Next.js App Router)
- `/app/page.tsx` — Public filament inventory table (home page)
- `/app/upadaj/` — Admin panel: login, `/dashboard` (filament CRUD), `/colors` (color management), `/requests` (customer color requests)
- `/src/services/api.ts` — Axios instance with auth interceptors (auto token injection, 401/403 redirect)
- `/src/data/bambuLabColors.ts` — Primary color-to-hex mapping with gradient support (used by `ColorCell` component)
- `/src/data/bambuLabColorsComplete.ts` — Extended color database grouped by finish type (used by filters)

### API (`/api/server.js`)
Single-file Express server running on EC2 (port 80). All routes inline.
- Endpoints: `/api/login`, `/api/filaments`, `/api/colors`, `/api/sale/bulk`, `/api/color-requests`
- Auth: JWT tokens with 24h expiry, single admin user (password from `ADMIN_PASSWORD` env var)

### Database (PostgreSQL on RDS)
Key schemas and constraints:

```
filaments: id, tip (material), finish, boja (color), refill, spulna, kolicina, cena, sale_*
colors: id, name, hex, cena_refill (default 3499), cena_spulna (default 3999)
color_requests: id, color_name, message, contact_name, contact_phone, status
```

**Critical constraints:**
- `filaments.boja` → FK to `colors.name` (ON UPDATE CASCADE) — colors must exist before filaments reference them
- `kolicina = refill + spulna` — enforced by check constraint
- Migrations in `/database/migrations/` with sequential numbering (currently up to `020_`)

## Key Patterns

### Color Management (two-layer system)
1. **Database `colors` table**: Defines valid color names + pricing. Must be populated first due to FK constraint.
2. **Frontend `bambuLabColors.ts`**: Maps color names → hex codes for UI display. Supports solid (`hex: '#FF0000'`) and gradient (`hex: ['#HEX1', '#HEX2'], isGradient: true`).
3. Color names must match exactly between `colors.name`, `filaments.boja`, and `bambuLabColors.ts` keys.
4. The `ColorCell` component renders table row backgrounds from these mappings.

### Adding New Colors
1. Add to database `colors` table (via admin panel at `/upadaj/colors` or migration)
2. Add hex mapping to `src/data/bambuLabColors.ts`
3. Optionally add to `src/data/bambuLabColorsComplete.ts` finish groups

### API Communication
- Service modules in `src/services/api.ts`: `authService`, `colorService`, `filamentService`, `colorRequestService`
- Auth token stored in localStorage with 24h expiry
- Cache busting on filament fetches via timestamp query param

## CI/CD (Gitea Actions)

`.gitea/workflows/deploy.yml` triggers on push to `main`. Auto-detects changes via `git diff HEAD~1`:
- **Frontend changes** (anything outside `api/`): security check → tests → build → S3 deploy (3-tier cache: HTML no-cache, `_next/` immutable, rest 24h) → CloudFront invalidation
- **API changes** (`api/` files): SSM command to EC2 to pull `server.js` from Gitea and restart `node-api` service
- Both run if both changed in a single push

## Deployment Details

| Component | Target | Method |
|-----------|--------|--------|
| Frontend | S3 `filamenteka-frontend` → CloudFront | Static export, OAC-protected |
| API | EC2 `i-03956ecf32292d7d9` | SSM, systemd `node-api` service |
| Database | RDS `filamenteka.ci7fsdlbzmag.eu-central-1.rds.amazonaws.com` | Migrations via `scripts/update-db-via-aws.sh` |
| DNS | Cloudflare | `api.filamenteka.rs` → EC2 |
| IaC | `/terraform/` | VPC, EC2, RDS, ALB, CloudFront, Cloudflare |

## Environment Variables

```bash
# Frontend (.env.local)
NEXT_PUBLIC_API_URL=https://api.filamenteka.rs/api
NEXT_PUBLIC_MATOMO_URL=https://analytics.demirix.dev
NEXT_PUBLIC_MATOMO_SITE_ID=7

# API Server (.env in /api)
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
```

## Pre-commit Hooks (Husky)

`scripts/pre-commit.sh` runs automatically and blocks commits that fail:
1. Author mention check (blocks attribution)
2. Security check (credential leaks)
3. Build test (ensures compilation)
4. Unit tests (`jest --passWithNoTests`)
