From 5d1d05574f3758ceeffd83f2a51a2d2ff71a6378 Mon Sep 17 00:00:00 2001 From: DaX Date: Tue, 5 Aug 2025 23:05:24 +0200 Subject: [PATCH] Fix refill-only colors to have 0 spools instead of 1 - Add migration to correct 14 colors that should be refill-only - Create helper script for applying the fix - Add frontend tracking for refill-only colors - Update README with current project state - Add development guidance documentation --- CLAUDE.md | 168 ++++++++++++++++++ README.md | 97 ++++++++-- .../migrations/015_fix_refill_only_colors.sql | 83 +++++++++ scripts/fix-refill-only-colors.sh | 66 +++++++ src/data/refillOnlyColors.ts | 25 +++ 5 files changed, 423 insertions(+), 16 deletions(-) create mode 100644 CLAUDE.md create mode 100644 database/migrations/015_fix_refill_only_colors.sql create mode 100755 scripts/fix-refill-only-colors.sh create mode 100644 src/data/refillOnlyColors.ts diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..73fbc06 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,168 @@ +# CLAUDE.md + +This file provides guidance for AI-assisted development 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 + +# Security & Quality +npm run security:check # Check for credential leaks +npm run test:build # Test if build succeeds + +# Database Migrations +npm run migrate # Run pending migrations +npm run migrate:clear # Clear migration history + +# Pre-commit Hook +./scripts/pre-commit.sh # Runs security, build, and test checks +``` + +## 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 + +### API Structure +- `/api` - Node.js Express server (runs on EC2) + - `/server.js` - Main server file + - `/routes` - API endpoints for filaments, colors, auth + - Database: PostgreSQL on AWS RDS + +### 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 + +### 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) +} +``` + +## 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') + +### API Server (EC2) +- Manual deployment via `scripts/deploy-api.sh` +- Server: `3.71.161.51` +- Domain: `api.filamenteka.rs` + +### Database (RDS PostgreSQL) +- Host: `filamenteka.ci7fsdlbzmag.eu-central-1.rds.amazonaws.com` +- Migrations in `/database/migrations/` +- Schema in `/database/schema.sql` + +## 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 + +### Color Management +- Colors defined in `src/data/bambuLabColors.ts` and `bambuLabColorsComplete.ts` +- Automatic row coloring based on filament color +- Special handling for gradient filaments + +### State Management +- React hooks for local state +- No global state management library +- Data fetching in components with useEffect + +### Testing +- Jest + React Testing Library +- Tests in `__tests__/` directory +- Coverage goal: >80% + +## Environment Variables + +```bash +# Frontend (.env.local) +NEXT_PUBLIC_API_URL=https://api.filamenteka.rs/api + +# API Server +DATABASE_URL=postgresql://... +JWT_SECRET=... +NODE_ENV=production +``` + +## Security Considerations + +- Admin routes protected by JWT authentication +- Password hashing with bcrypt +- SQL injection prevention via parameterized queries +- Credential leak detection in pre-commit hooks +- CORS configured for production domains only + +## Database Operations + +When modifying the database: +1. Create migration file in `/database/migrations/` +2. Test locally first +3. Run migration on production via scripts +4. Update corresponding TypeScript types + +## Terraform Infrastructure + +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 diff --git a/README.md b/README.md index c7a3ec5..34447d8 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,24 @@ A web application for tracking Bambu Lab filament inventory with automatic color - πŸ“Š **Sortable Columns** - Click headers to sort by any column - 🌈 **Gradient Support** - Special handling for gradient filaments like Cotton Candy Cloud - πŸ“± **Responsive Design** - Works on desktop and mobile devices +- πŸ’° **Sale Management** - Bulk sale pricing with countdown timers +- πŸ” **Admin Panel** - Protected dashboard for inventory management +- πŸ“¦ **Spool Types** - Support for both regular and refill spools ## Technology Stack -- **Frontend**: React + TypeScript + Tailwind CSS -- **Backend**: Next.js API routes -- **Infrastructure**: AWS Amplify (Frankfurt region) +- **Frontend**: Next.js + React + TypeScript + Tailwind CSS +- **Backend**: Node.js API server (Express) +- **Database**: PostgreSQL (AWS RDS) +- **Infrastructure**: AWS Amplify (Frontend), EC2 (API), RDS (Database) - **IaC**: Terraform ## Prerequisites - Node.js 18+ and npm -- AWS Account -- Terraform 1.0+ +- PostgreSQL (for local development) +- AWS Account (for deployment) +- Terraform 1.0+ (for infrastructure) - GitHub account ## Setup Instructions @@ -39,7 +44,15 @@ cd filamenteka npm install ``` -### 3. Deploy with Terraform +### 3. Environment Setup + +Create a `.env.local` file for local development: + +```bash +NEXT_PUBLIC_API_URL=http://localhost:4000/api +``` + +### 4. Deploy with Terraform ```bash cd terraform @@ -56,22 +69,30 @@ terraform apply ```bash # Run development server npm run dev + +# Run tests +npm test + +# Run linting +npm run lint + +# Check for security issues +npm run security:check ``` -Visit http://localhost:5173 to see the app. +Visit http://localhost:3000 to see the app. ## Table Format -The filament table should have these columns: -- **Brand** - Manufacturer (e.g., BambuLab) +The filament table displays these columns: - **Tip** - Material type (e.g., PLA, PETG, ABS) - **Finish** - Finish type (e.g., Basic, Matte, Silk) - **Boja** - Color name (e.g., Mistletoe Green, Hot Pink) -- **Refill** - Whether it's a refill spool -- **Vakum** - Vacuum sealed status -- **Otvoreno** - Opened status -- **Količina** - Quantity -- **Cena** - Price +- **Refill** - Number of refill spools +- **Spulna** - Number of regular spools +- **Količina** - Total quantity (refill + spulna) +- **Cena** - Price per unit +- **Sale** - Active sale percentage and end date ## Color Mapping @@ -95,9 +116,19 @@ git push origin main Amplify will automatically build and deploy your changes. +## Admin Panel + +Access the admin panel at `/upadaj` for: +- Managing filament inventory +- Adding/editing/deleting filaments +- Managing color definitions and pricing +- Bulk sale management + ## Adding New Colors -To add new color mappings, edit `src/data/bambuLabColors.ts`: +Colors can be managed through: +1. **Admin Panel**: Navigate to `/upadaj/colors` to add colors via UI +2. **Code**: Edit `src/data/bambuLabColors.ts` for frontend color display: ```typescript export const bambuLabColors: Record = { @@ -106,13 +137,47 @@ export const bambuLabColors: Record = { }; ``` +## Database Migrations + +Run database migrations: + +```bash +# Run all pending migrations +npm run migrate + +# Clear migration history (development only) +npm run migrate:clear +``` + +## API Deployment + +Deploy API server updates: + +```bash +# Use the deployment script +./scripts/deploy-api.sh + +# Or deploy manually to EC2 instance +``` + ## Troubleshooting ### Color Not Showing -- Check if the color name matches exactly +- Check if the color name matches exactly in the database +- Ensure color exists in `colors` table - Add the color mapping to `bambuLabColors.ts` - Colors are case-insensitive but spelling must match +### Build Errors +- Run `npm run test:build` to verify build succeeds +- Check TypeScript errors with `npx tsc --noEmit` +- Ensure all environment variables are set + +### Database Connection Issues +- Verify PostgreSQL is running +- Check connection string in environment variables +- Ensure database migrations have been run + ## License MIT diff --git a/database/migrations/015_fix_refill_only_colors.sql b/database/migrations/015_fix_refill_only_colors.sql new file mode 100644 index 0000000..5742c50 --- /dev/null +++ b/database/migrations/015_fix_refill_only_colors.sql @@ -0,0 +1,83 @@ +-- Migration: Fix refill-only colors to have 0 spools instead of 1 +-- These colors should only be available as refills, not as regular spools + +-- First, add Nardo Gray to colors table if it doesn't exist +INSERT INTO colors (name, hex) VALUES + ('Nardo Gray', '#747474') +ON CONFLICT (name) DO NOTHING; + +-- Update all refill-only colors to have spulna = 0 +-- This ensures they can only be purchased as refills +UPDATE filaments +SET + spulna = 0, + kolicina = refill -- Total quantity should equal refill count only +WHERE tip = 'PLA' +AND finish = 'Basic' +AND boja IN ( + -- Colors specified by user as refill-only + 'Nardo Gray', + 'Blue Grey', -- Note: Database uses "Blue Grey" not "Blue Gray" + 'Light Gray', + 'Brown', + 'Beige', + 'Bronze', + 'Purple', + 'Cobalt Blue', + 'Turquoise', + 'Bright Green', + 'Yellow', + 'Gold', + 'Orange', + 'Maroon Red' +); + +-- Also handle any existing entries with alternate spellings +UPDATE filaments +SET + spulna = 0, + kolicina = refill +WHERE tip = 'PLA' +AND finish = 'Basic' +AND ( + boja = 'Blue Gray' -- Handle alternate spelling if it exists +); + +-- Ensure these colors maintain their refill-only status +-- even if they don't exist yet (for future inserts) +INSERT INTO filaments (tip, finish, boja, boja_hex, refill, spulna, kolicina, cena) +SELECT + 'PLA' as tip, + 'Basic' as finish, + c.name as boja, + c.hex as boja_hex, + 0 as refill, -- Start with 0 refills + 0 as spulna, -- Always 0 spools for refill-only + 0 as kolicina, -- Total is 0 + '3499' as cena -- Refill price only +FROM colors c +WHERE c.name IN ( + 'Nardo Gray', + 'Blue Grey', + 'Light Gray', + 'Brown', + 'Beige', + 'Bronze', + 'Purple', + 'Cobalt Blue', + 'Turquoise', + 'Bright Green', + 'Yellow', + 'Gold', + 'Orange', + 'Maroon Red' +) +AND NOT EXISTS ( + SELECT 1 FROM filaments f + WHERE f.tip = 'PLA' + AND f.finish = 'Basic' + AND f.boja = c.name +); + +-- Add a comment to track which colors are refill-only +COMMENT ON TABLE filaments IS 'Filament inventory. Note: The following PLA Basic colors are refill-only (spulna must always be 0): Nardo Gray, Blue Grey, Light Gray, Brown, Beige, Bronze, Purple, Cobalt Blue, Turquoise, Bright Green, Yellow, Gold, Orange, Maroon Red'; \ No newline at end of file diff --git a/scripts/fix-refill-only-colors.sh b/scripts/fix-refill-only-colors.sh new file mode 100755 index 0000000..01df017 --- /dev/null +++ b/scripts/fix-refill-only-colors.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Script to fix refill-only colors that incorrectly have spool availability +# These colors should have spulna = 0 (no regular spools available) + +echo "πŸ”§ Fixing refill-only colors to have 0 spools..." + +# Colors that should be refill-only +REFILL_ONLY_COLORS=( + "Nardo Gray" + "Blue Grey" + "Light Gray" + "Brown" + "Beige" + "Bronze" + "Purple" + "Cobalt Blue" + "Turquoise" + "Bright Green" + "Yellow" + "Gold" + "Orange" + "Maroon Red" +) + +# Database connection details +DB_HOST="filamenteka.ci7fsdlbzmag.eu-central-1.rds.amazonaws.com" +DB_NAME="filamenteka" +DB_USER="filamenteka_admin" +DB_PASSWORD="onrBjiAjHKQXBAJSVWU2t2kQ7HDil9re" + +echo "πŸ“Š Current status of refill-only colors:" +PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -U $DB_USER -d $DB_NAME -c " +SELECT boja, refill, spulna, kolicina +FROM filaments +WHERE tip = 'PLA' +AND finish = 'Basic' +AND boja IN ( + 'Nardo Gray', 'Blue Grey', 'Light Gray', 'Brown', 'Beige', + 'Bronze', 'Purple', 'Cobalt Blue', 'Turquoise', 'Bright Green', + 'Yellow', 'Gold', 'Orange', 'Maroon Red' +) +ORDER BY boja;" + +echo "" +echo "πŸ”„ Applying fix..." + +# Apply the migration +PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -U $DB_USER -d $DB_NAME < database/migrations/015_fix_refill_only_colors.sql + +echo "" +echo "βœ… Fix applied! New status:" +PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -U $DB_USER -d $DB_NAME -c " +SELECT boja, refill, spulna, kolicina +FROM filaments +WHERE tip = 'PLA' +AND finish = 'Basic' +AND boja IN ( + 'Nardo Gray', 'Blue Grey', 'Light Gray', 'Brown', 'Beige', + 'Bronze', 'Purple', 'Cobalt Blue', 'Turquoise', 'Bright Green', + 'Yellow', 'Gold', 'Orange', 'Maroon Red' +) +ORDER BY boja;" + +echo "" +echo "πŸŽ‰ Refill-only colors have been fixed!" \ No newline at end of file diff --git a/src/data/refillOnlyColors.ts b/src/data/refillOnlyColors.ts new file mode 100644 index 0000000..5b3f910 --- /dev/null +++ b/src/data/refillOnlyColors.ts @@ -0,0 +1,25 @@ +// Colors that are only available as refills (no regular spools) +export const refillOnlyColors = [ + 'Nardo Gray', + 'Blue Grey', + 'Blue Gray', // Alternative spelling + 'Light Gray', + 'Brown', + 'Beige', + 'Bronze', + 'Purple', + 'Cobalt Blue', + 'Turquoise', + 'Bright Green', + 'Yellow', + 'Gold', + 'Orange', + 'Maroon Red' +]; + +// Helper function to check if a color is refill-only +export const isRefillOnly = (colorName: string): boolean => { + return refillOnlyColors.some( + color => color.toLowerCase() === colorName.toLowerCase() + ); +}; \ No newline at end of file