From b1dfa2352a66e1dc26e6e31c8b37a27ac6d114c9 Mon Sep 17 00:00:00 2001 From: DaX Date: Thu, 13 Nov 2025 07:02:06 +0100 Subject: [PATCH] Add 76 missing Bambu Lab colors and expand filament type support - Added comprehensive color migration with 76 new Bambu Lab colors - Includes glow, metallic, sparkle, gradient, ABS, and translucent variants - Added PAHT material type with CF and Bez Finisha finish support - Added Tough+ finish option for PLA filaments - Fixed refill/spulna restrictions for specific combinations: - ABS GF Yellow/Orange now refill-only - TPU 95A HF now refill-only - Removed spool restrictions for Galaxy and Basic finishes - Updated frontend color mappings with all new colors - All colors now available in admin panel for inventory management --- CLAUDE.md | 117 +++++++++++++----- app/upadaj/dashboard/page.tsx | 14 ++- .../020_add_missing_colors_2025.sql | 102 +++++++++++++++ src/data/bambuLabColors.ts | 27 ++++ 4 files changed, 226 insertions(+), 34 deletions(-) create mode 100644 database/migrations/020_add_missing_colors_2025.sql diff --git a/CLAUDE.md b/CLAUDE.md index 592c9e0..eba40d1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,13 +28,18 @@ npm test # Run Jest tests npm run test:watch # Run Jest in watch mode # Security & Quality -npm run security:check # Check for credential leaks -npm run test:build # Test if build succeeds -./scripts/pre-commit.sh # Runs security, build, and test checks (use before commits) +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 -npm run migrate:clear # Clear migration history +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 @@ -119,10 +124,12 @@ color_requests: { - Security check runs during build (amplify.yml preBuild phase) ### API Server (EC2) -- Manual deployment via `scripts/deploy-api.sh` or `scripts/deploy-api-update.sh` -- Server: `3.71.161.51` +- 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) @@ -136,19 +143,26 @@ color_requests: { ## Important Patterns ### API Communication -- All API calls use axios interceptors for auth (`src/services/api.ts`) -- Auth token stored in localStorage -- Automatic redirect on 401/403 in admin routes +- 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 -- Colors defined in `src/data/bambuLabColors.ts` and `bambuLabColorsComplete.ts` -- Automatic row coloring based on filament color -- Special handling for gradient filaments +- 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 state +- 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 @@ -174,22 +188,36 @@ PORT=80 ## Security Considerations -- Admin routes protected by JWT authentication (24h expiry) -- Password hashing with bcrypt (for future multi-user support) -- SQL injection prevention via parameterized queries -- Credential leak detection in pre-commit hooks (`scripts/security/security-check.js`) -- CORS configured to allow all origins (update for production hardening) -- Auth token interceptors handle 401/403 automatically -- Pre-commit hook runs security checks, build tests, and unit tests +- **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) -## Database Operations +## 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 -2. Test locally first +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 - - Or use `npm run migrate` for local/scripted execution + - 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: @@ -197,12 +225,35 @@ Important database constraints: - `filaments.kolicina` has check constraint: `kolicina = refill + spulna` - Always update `colors` table first before adding filaments with new colors -## Terraform Infrastructure +### 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 and networking setup -- EC2 instance for API -- RDS PostgreSQL database -- Application Load Balancer -- ECR for Docker images -- Cloudflare DNS integration \ No newline at end of file +- **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 \ No newline at end of file diff --git a/app/upadaj/dashboard/page.tsx b/app/upadaj/dashboard/page.tsx index 9122890..776b438 100644 --- a/app/upadaj/dashboard/page.tsx +++ b/app/upadaj/dashboard/page.tsx @@ -45,10 +45,21 @@ const isRefillOnly = (color: string, finish?: string, type?: string): boolean => if (finish === 'Translucent') { return false; } + // Specific type/finish/color combinations that are refill-only + if (type === 'ABS' && finish === 'GF' && (color === 'Yellow' || color === 'Orange')) { + return true; + } + if (type === 'TPU' && finish === '95A HF') { + return true; + } // All colors starting with "Matte " prefix are refill-only if (color.startsWith('Matte ')) { return true; } + // Galaxy and Basic colors have spools available (not refill-only) + if (finish === 'Galaxy' || finish === 'Basic') { + return false; + } return REFILL_ONLY_COLORS.includes(color); }; @@ -71,13 +82,14 @@ interface FilamentWithId extends Filament { // Finish options by filament type const FINISH_OPTIONS_BY_TYPE: Record = { 'ABS': ['GF', 'Bez Finisha'], - 'PLA': ['85A', '90A', '95A HF', 'Aero', 'Basic', 'Basic Gradient', 'CF', 'FR', 'Galaxy', 'GF', 'Glow', 'HF', 'Marble', 'Matte', 'Metal', 'Silk Multi-Color', 'Silk+', 'Sparkle', 'Translucent', 'Wood'], + 'PLA': ['85A', '90A', '95A HF', 'Aero', 'Basic', 'Basic Gradient', 'CF', 'FR', 'Galaxy', 'GF', 'Glow', 'HF', 'Marble', 'Matte', 'Metal', 'Silk Multi-Color', 'Silk+', 'Sparkle', 'Tough+', 'Translucent', 'Wood'], 'TPU': ['85A', '90A', '95A HF'], 'PETG': ['Basic', 'CF', 'FR', 'HF', 'Translucent'], 'PC': ['CF', 'FR', 'Bez Finisha'], 'ASA': ['Bez Finisha'], 'PA': ['CF', 'GF', 'Bez Finisha'], 'PA6': ['CF', 'GF'], + 'PAHT': ['CF', 'Bez Finisha'], 'PPA': ['CF'], 'PVA': ['Bez Finisha'], 'HIPS': ['Bez Finisha'] diff --git a/database/migrations/020_add_missing_colors_2025.sql b/database/migrations/020_add_missing_colors_2025.sql new file mode 100644 index 0000000..9d1d954 --- /dev/null +++ b/database/migrations/020_add_missing_colors_2025.sql @@ -0,0 +1,102 @@ +-- Migration: Add missing Bambu Lab colors (2025) +-- Created: 2025-11-13 +-- Description: Adds missing color definitions from Bambu Lab catalog + +INSERT INTO colors (name, hex, cena_refill, cena_spulna) VALUES +-- Basic/Matte Colors +('Clear Black', '#1a1a1a', 3499, 3999), +('Transparent', '#f0f0f0', 3499, 3999), +('Brick Red', '#8b2e2e', 3499, 3999), +('Titan Gray', '#5c6670', 3499, 3999), +('Indigo Blue', '#4b0082', 3499, 3999), +('Malachite Green', '#0bda51', 3499, 3999), +('Violet Purple', '#8f00ff', 3499, 3999), +('Iris Purple', '#5d3fd3', 3499, 3999), +('Royal Blue', '#4169e1', 3499, 3999), +('Lava Gray', '#4a4a4a', 3499, 3999), +('Burgundy Red', '#800020', 3499, 3999), +('Matcha Green', '#8db255', 3499, 3999), +('Light Cyan', '#e0ffff', 3499, 3999), + +-- Glow Colors +('Blaze', '#ff6347', 3499, 3999), +('Glow Blue', '#00d4ff', 3499, 3999), +('Glow Pink', '#ff69b4', 3499, 3999), +('Glow Yellow', '#ffff00', 3499, 3999), +('Glow Orange', '#ff8c00', 3499, 3999), +('Nebulane', '#9b59b6', 3499, 3999), + +-- Metallic Colors +('IronGray Metallic', '#71797e', 3499, 3999), +('Copper Brown Metallic', '#b87333', 3499, 3999), +('Iridium Gold Metallic', '#d4af37', 3499, 3999), +('Oxide Green Metallic', '#6b8e23', 3499, 3999), +('Cobalt Blue Metallic', '#0047ab', 3499, 3999), + +-- Marble Colors +('White Marble', '#f5f5f5', 3499, 3999), +('Red Granite', '#8b4513', 3499, 3999), + +-- Sparkle Colors +('Classic Gold Sparkle', '#ffd700', 3499, 3999), +('Onyx Black Sparkle', '#0f0f0f', 3499, 3999), +('Crimson Red Sparkle', '#dc143c', 3499, 3999), +('Royal Purple Sparkle', '#7851a9', 3499, 3999), +('Slate Gray Sparkle', '#708090', 3499, 3999), +('Alpine Green Sparkle', '#2e8b57', 3499, 3999), + +-- Gradient Colors +('South Beach', '#ff69b4', 3499, 3999), +('Dawn Radiance', '#ff7f50', 3499, 3999), +('Blue Hawaii', '#1e90ff', 3499, 3999), +('Gilded Rose', '#ff1493', 3499, 3999), +('Midnight Blaze', '#191970', 3499, 3999), +('Neon City', '#00ffff', 3499, 3999), +('Velvet Eclipse', '#8b008b', 3499, 3999), +('Solar Breeze', '#ffb347', 3499, 3999), +('Arctic Whisper', '#b0e0e6', 3499, 3999), +('Ocean to Meadow', '#40e0d0', 3499, 3999), +('Dusk Glare', '#ff6347', 3499, 3999), +('Mint Lime', '#98fb98', 3499, 3999), +('Pink Citrus', '#ff69b4', 3499, 3999), +('Blueberry Bubblegum', '#7b68ee', 3499, 3999), +('Cotton Candy Cloud', '#ffb6c1', 3499, 3999), + +-- Pastel/Light Colors +('Lavender', '#e6e6fa', 3499, 3999), +('Ice Blue', '#d0e7ff', 3499, 3999), +('Mellow Yellow', '#fff44f', 3499, 3999), +('Teal', '#008080', 3499, 3999), + +-- ABS Colors +('ABS Azure', '#007fff', 3499, 3999), +('ABS Olive', '#808000', 3499, 3999), +('ABS Blue', '#0000ff', 3499, 3999), +('ABS Tangerine Yellow', '#ffcc00', 3499, 3999), +('ABS Navy Blue', '#000080', 3499, 3999), +('ABS Orange', '#ff8800', 3499, 3999), +('ABS Bambu Green', '#00c853', 3499, 3999), +('ABS Red', '#ff0000', 3499, 3999), +('ABS White', '#ffffff', 3499, 3999), +('ABS Black', '#000000', 3499, 3999), +('ABS Silver', '#c0c0c0', 3499, 3999), + +-- Translucent Colors +('Translucent Gray', '#9e9e9e', 3499, 3999), +('Translucent Brown', '#8b4513', 3499, 3999), +('Translucent Purple', '#9370db', 3499, 3999), +('Translucent Orange', '#ffa500', 3499, 3999), +('Translucent Olive', '#6b8e23', 3499, 3999), +('Translucent Pink', '#ffb6c1', 3499, 3999), +('Translucent Light Blue', '#add8e6', 3499, 3999), +('Translucent Tea', '#d2b48c', 3499, 3999), + +-- Additional Colors +('Mint', '#98ff98', 3499, 3999), +('Champagne', '#f7e7ce', 3499, 3999), +('Baby Blue', '#89cff0', 3499, 3999), +('Cream', '#fffdd0', 3499, 3999), +('Peanut Brown', '#b86f52', 3499, 3999), +('Matte Ivory', '#fffff0', 3499, 3999) + +ON CONFLICT (name) DO NOTHING; diff --git a/src/data/bambuLabColors.ts b/src/data/bambuLabColors.ts index b041aab..84e5c16 100644 --- a/src/data/bambuLabColors.ts +++ b/src/data/bambuLabColors.ts @@ -34,6 +34,7 @@ export const bambuLabColors: Record = { 'Cherry Pink': { hex: '#E9B6CC' }, 'Chocolate': { hex: '#4A3729' }, 'Classic Birch': { hex: '#E8D5B7' }, + 'Classic Gold Sparkle': { hex: '#E4BD68' }, 'Clay Brown': { hex: '#8E621A' }, 'Clear': { hex: '#FAFAFA' }, 'Clear Black': { hex: '#5A5161' }, @@ -71,6 +72,7 @@ export const bambuLabColors: Record = { 'Indigo Purple': { hex: '#482A60' }, 'Iridium Gold Metallic': { hex: '#B39B84' }, 'Iris Purple': { hex: '#69398E' }, + 'IronGray Metallic': { hex: '#6B6C6F' }, 'Ivory White': { hex: '#FFFFFF' }, 'Jade White': { hex: '#FFFFFF' }, 'Jeans Blue': { hex: '#6E88BC' }, @@ -100,6 +102,7 @@ export const bambuLabColors: Record = { 'Nardo Gray': { hex: '#747474' }, 'Navy Blue': { hex: '#0C2340' }, 'Nebulae': { hex: '#424379' }, + 'Nebulane': { hex: '#424379' }, 'Neon City': { hex: '#0047BB' }, 'Neon Green': { hex: '#ABFF1E' }, 'Neon Orange': { hex: '#F68A1B' }, @@ -142,6 +145,29 @@ export const bambuLabColors: Record = { 'White Oak': { hex: '#D2CCA2' }, 'Yellow': { hex: '#F4EE2A' }, + // ABS Colors + 'ABS Azure': { hex: '#489FDF' }, + 'ABS Olive': { hex: '#748C45' }, + 'ABS Blue': { hex: '#0A2989' }, + 'ABS Tangerine Yellow': { hex: '#FFC72C' }, + 'ABS Navy Blue': { hex: '#0C2340' }, + 'ABS Orange': { hex: '#FF6A13' }, + 'ABS Bambu Green': { hex: '#00AE42' }, + 'ABS Red': { hex: '#C12E1F' }, + 'ABS White': { hex: '#FFFFFF' }, + 'ABS Black': { hex: '#000000' }, + 'ABS Silver': { hex: '#A6A9AA' }, + + // Translucent Colors + 'Translucent Gray': { hex: '#B8B8B8' }, + 'Translucent Brown': { hex: '#C89A74' }, + 'Translucent Purple': { hex: '#C5A8D8' }, + 'Translucent Orange': { hex: '#FFB380' }, + 'Translucent Olive': { hex: '#A4B885' }, + 'Translucent Pink': { hex: '#F9B8D0' }, + 'Translucent Light Blue': { hex: '#A8D8F0' }, + 'Translucent Tea': { hex: '#D9C7A8' }, + // PLA Matte - New Colors (2025) 'Matte Apple Green': { hex: '#C6E188' }, 'Matte Bone White': { hex: '#C8C5B6' }, @@ -153,6 +179,7 @@ export const bambuLabColors: Record = { 'Matte Dark Red': { hex: '#BB3D43' }, 'Matte Grass Green': { hex: '#7CB342' }, 'Matte Ice Blue': { hex: '#A3D8E1' }, + 'Matte Ivory': { hex: '#FFFFF0' }, 'Matte Lemon Yellow': { hex: '#F7D959' }, 'Matte Lilac Purple': { hex: '#AE96D4' }, 'Matte Plum': { hex: '#851A52' },