Clean up fake colors and add missing Bambu Lab colors
- Add migration 023: delete 67 fake colors, rename IronGray typo, add 16 missing real colors from spreadsheet - Fix frontend color mappings: remove typo duplicates, rename Silk prefixed colors to match catalog - Add Translucent Teal, Phantom Blue, Mystic Magenta mappings - Remove non-existent ABS GF, TPU 95A HF entries - Update tests for corrected color names
This commit is contained in:
10
CLAUDE.md
10
CLAUDE.md
@@ -48,14 +48,14 @@ scripts/deploy-frontend.sh # Manual frontend deploy to S3/CloudFront
|
||||
|
||||
### 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)
|
||||
- `/app/upadaj/` — Admin panel: login, `/dashboard` (filament CRUD), `/colors` (color management), `/customers` (customer management), `/sales` (sales recording), `/requests` (customer color requests), `/analytics` (revenue/inventory dashboards)
|
||||
- `/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`
|
||||
- Endpoints: `/api/login`, `/api/filaments`, `/api/colors`, `/api/customers`, `/api/sales`, `/api/color-requests`, `/api/analytics/*`
|
||||
- Auth: JWT tokens with 24h expiry, single admin user (password from `ADMIN_PASSWORD` env var)
|
||||
|
||||
### Database (PostgreSQL on RDS)
|
||||
@@ -64,13 +64,15 @@ 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)
|
||||
customers: id, name, phone (unique), city, notes, created_at
|
||||
sales: id, customer_id (FK→customers), total_amount, notes, created_at + sale_items join table
|
||||
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_`)
|
||||
- Migrations in `/database/migrations/` with sequential numbering (currently up to `023_`)
|
||||
|
||||
## Key Patterns
|
||||
|
||||
@@ -86,7 +88,7 @@ color_requests: id, color_name, message, contact_name, contact_phone, status
|
||||
3. Optionally add to `src/data/bambuLabColorsComplete.ts` finish groups
|
||||
|
||||
### API Communication
|
||||
- Service modules in `src/services/api.ts`: `authService`, `colorService`, `filamentService`, `colorRequestService`
|
||||
- Service modules in `src/services/api.ts`: `authService`, `colorService`, `filamentService`, `colorRequestService`, `customerService`, `saleService`, `analyticsService`
|
||||
- Auth token stored in localStorage with 24h expiry
|
||||
- Cache busting on filament fetches via timestamp query param
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ describe('Bambu Lab Colors Data', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should have Unknown fallback color', () => {
|
||||
expect(bambuLabColors).toHaveProperty('Unknown');
|
||||
expect(bambuLabColors.Unknown.hex).toBe('#CCCCCC');
|
||||
it('should return fallback for unknown colors', () => {
|
||||
const result = getFilamentColor('NonExistentColor');
|
||||
expect(result.hex).toBe('#CCCCCC');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ describe('Bambu Lab Colors Complete Data', () => {
|
||||
});
|
||||
|
||||
it('should have silk colors', () => {
|
||||
expect(bambuLabColors).toHaveProperty('Silk Aurora Purple');
|
||||
expect(bambuLabColors).toHaveProperty('Silk Phantom Blue');
|
||||
expect(bambuLabColors).toHaveProperty('Silk Mystic Magenta');
|
||||
expect(bambuLabColors).toHaveProperty('Aurora Purple');
|
||||
expect(bambuLabColors).toHaveProperty('Phantom Blue');
|
||||
expect(bambuLabColors).toHaveProperty('Mystic Magenta');
|
||||
});
|
||||
|
||||
it('should have valid hex colors', () => {
|
||||
|
||||
100
database/migrations/023_cleanup_fake_colors_add_missing.sql
Normal file
100
database/migrations/023_cleanup_fake_colors_add_missing.sql
Normal file
@@ -0,0 +1,100 @@
|
||||
-- Migration 023: Clean up fake colors and add missing real Bambu Lab colors
|
||||
-- Source of truth: bambu_lab_filaments.numbers spreadsheet
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- 1. Rename typo: IronGray Metallic → Iron Gray Metallic (FK cascades to filaments)
|
||||
UPDATE colors SET name = 'Iron Gray Metallic' WHERE name = 'IronGray Metallic';
|
||||
|
||||
-- 2. Delete 67 fake colors not used by any filament
|
||||
DELETE FROM colors WHERE name IN (
|
||||
'Coton Candy Cloud',
|
||||
'Glow in the Dark Blue',
|
||||
'Glow in the Dark Green',
|
||||
'Grey',
|
||||
'Indingo Purple',
|
||||
'Ivory',
|
||||
'Ivory White',
|
||||
'Light Blue',
|
||||
'Light Green',
|
||||
'Matte Black',
|
||||
'Matte Blue',
|
||||
'Matte Brown',
|
||||
'Matte Coral',
|
||||
'Matte Green',
|
||||
'Matte Grey',
|
||||
'Matte Lime',
|
||||
'Matte Mint',
|
||||
'Matte Navy',
|
||||
'Matte Orange',
|
||||
'Matte Pink',
|
||||
'Matte Purple',
|
||||
'Matte White',
|
||||
'Matte Yellow',
|
||||
'Metal Bronze',
|
||||
'Metal Copper',
|
||||
'Metal Gold',
|
||||
'Metal Grey',
|
||||
'Metal Silver',
|
||||
'Mint Green',
|
||||
'Natural',
|
||||
'Navy Blue',
|
||||
'Nebulane',
|
||||
'Silk Black',
|
||||
'Silk Blue',
|
||||
'Silk Bronze',
|
||||
'Silk Copper',
|
||||
'Silk Emerald',
|
||||
'Silk Gold',
|
||||
'Silk Green',
|
||||
'Silk Jade',
|
||||
'Silk Orange',
|
||||
'Silk Pearl',
|
||||
'Silk Pink',
|
||||
'Silk Purple',
|
||||
'Silk Red',
|
||||
'Silk Rose Gold',
|
||||
'Silk Ruby',
|
||||
'Silk Sapphire',
|
||||
'Silk Silver',
|
||||
'Silk White',
|
||||
'Sky Blue',
|
||||
'Sparkle Blue',
|
||||
'Sparkle Gold',
|
||||
'Sparkle Green',
|
||||
'Sparkle Purple',
|
||||
'Sparkle Red',
|
||||
'Sparkle Silver',
|
||||
'Support G',
|
||||
'Support White',
|
||||
'Translucent Tea',
|
||||
'Transparent Blue',
|
||||
'Transparent Green',
|
||||
'Transparent Orange',
|
||||
'Transparent Purple',
|
||||
'Transparent Red',
|
||||
'Transparent Yellow',
|
||||
'Violet'
|
||||
);
|
||||
|
||||
-- 3. Add 17 missing real Bambu Lab colors from spreadsheet
|
||||
INSERT INTO colors (name, hex) VALUES
|
||||
('Aurora Purple', '#285BB7'),
|
||||
('Candy Green', '#408619'),
|
||||
('Candy Red', '#BB3A2E'),
|
||||
('Crystal Blue', '#5BC0EB'),
|
||||
('Flesh', '#E8C4A2'),
|
||||
('Forest Green', '#415520'),
|
||||
('Grape Jelly', '#6B2D75'),
|
||||
('Lake Blue', '#4672E4'),
|
||||
('Lime', '#C5ED48'),
|
||||
('Mystic Magenta', '#720062'),
|
||||
('Nebulae', '#424379'),
|
||||
('Neon Green', '#ABFF1E'),
|
||||
('Phantom Blue', '#00629B'),
|
||||
('Quicksilver', '#A6A9AA'),
|
||||
('Rose Gold', '#B29593'),
|
||||
('Translucent Teal', '#008080')
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
COMMIT;
|
||||
@@ -115,9 +115,9 @@ export const BAMBU_LAB_CATALOG: BambuLabCatalog = {
|
||||
},
|
||||
'Silk Multi-Color': {
|
||||
colors: [
|
||||
{ name: 'Silk Aurora Purple', refill: false, spool: true },
|
||||
{ name: 'Silk Phantom Blue', refill: false, spool: true },
|
||||
{ name: 'Silk Mystic Magenta', refill: false, spool: true },
|
||||
{ name: 'Aurora Purple', refill: false, spool: true },
|
||||
{ name: 'Phantom Blue', refill: false, spool: true },
|
||||
{ name: 'Mystic Magenta', refill: false, spool: true },
|
||||
],
|
||||
},
|
||||
Metal: {
|
||||
|
||||
@@ -8,7 +8,7 @@ export const bambuLabColors: Record<string, ColorMapping> = {
|
||||
'Apple Green': { hex: '#C6E188' },
|
||||
'Arctic Whisper': { hex: '#ECF7F8' },
|
||||
'Ash Grey': { hex: '#9B9EA0' },
|
||||
'Aurora Purple': { hex: '#285BB7' },
|
||||
'Aurora Purple': { hex: ['#7F3696', '#006EC9'], isGradient: true },
|
||||
'Azure': { hex: '#489FDF' },
|
||||
'Baby Blue': { hex: '#AEC3ED' },
|
||||
'Bambu Green': { hex: '#00AE42' },
|
||||
@@ -73,8 +73,6 @@ export const bambuLabColors: Record<string, ColorMapping> = {
|
||||
'Iridium Gold Metallic': { hex: '#B39B84' },
|
||||
'Iris Purple': { hex: '#69398E' },
|
||||
'Iron Gray Metallic': { hex: '#6B6C6F' },
|
||||
'IronGray Metallic': { hex: '#6B6C6F' },
|
||||
'Ivory White': { hex: '#FFFFFF' },
|
||||
'Jade White': { hex: '#FFFFFF' },
|
||||
'Jeans Blue': { hex: '#6E88BC' },
|
||||
'Lake Blue': { hex: '#4672E4' },
|
||||
@@ -103,7 +101,6 @@ export const bambuLabColors: Record<string, ColorMapping> = {
|
||||
'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' },
|
||||
@@ -147,8 +144,6 @@ export const bambuLabColors: Record<string, ColorMapping> = {
|
||||
'Yellow': { hex: '#F4EE2A' },
|
||||
|
||||
// ABS Colors
|
||||
'ABS GF Yellow': { hex: '#FDD835' },
|
||||
'ABS GF Orange': { hex: '#F48438' },
|
||||
'ABS Azure': { hex: '#489FDF' },
|
||||
'ABS Olive': { hex: '#748C45' },
|
||||
'ABS Blue': { hex: '#0A2989' },
|
||||
@@ -169,7 +164,7 @@ export const bambuLabColors: Record<string, ColorMapping> = {
|
||||
'Translucent Olive': { hex: '#A4B885' },
|
||||
'Translucent Pink': { hex: '#F9B8D0' },
|
||||
'Translucent Light Blue': { hex: '#A8D8F0' },
|
||||
'Translucent Tea': { hex: '#D9C7A8' },
|
||||
'Translucent Teal': { hex: '#008080' },
|
||||
|
||||
// PLA Matte Colors
|
||||
'Matte Ivory White': { hex: '#FFFFF0' },
|
||||
@@ -199,19 +194,14 @@ export const bambuLabColors: Record<string, ColorMapping> = {
|
||||
'Matte Terracotta': { hex: '#A25A37' },
|
||||
|
||||
// PLA Silk Multi-Color
|
||||
'Silk Aurora Purple': { hex: ['#7F3696', '#006EC9'], isGradient: true },
|
||||
'Silk Phantom Blue': { hex: ['#00629B', '#000000'], isGradient: true },
|
||||
'Silk Mystic Magenta': { hex: ['#720062', '#3A913F'], isGradient: true },
|
||||
'Phantom Blue': { hex: ['#00629B', '#000000'], isGradient: true },
|
||||
'Mystic Magenta': { hex: ['#720062', '#3A913F'], isGradient: true },
|
||||
|
||||
// TPU Colors
|
||||
'Flesh': { hex: '#E8C4A2' },
|
||||
'Grape Jelly': { hex: '#6B2D75' },
|
||||
'Crystal Blue': { hex: '#5BC0EB' },
|
||||
'Quicksilver': { hex: '#A6A9AA' },
|
||||
'TPU 95A HF Yellow': { hex: '#F3E600' },
|
||||
|
||||
// Default fallback
|
||||
'Unknown': { hex: '#CCCCCC' }
|
||||
'Quicksilver': { hex: '#A6A9AA' }
|
||||
};
|
||||
|
||||
export function getFilamentColor(colorName: string): ColorMapping {
|
||||
@@ -240,7 +230,7 @@ export function getFilamentColor(colorName: string): ColorMapping {
|
||||
}
|
||||
|
||||
// Return default unknown color
|
||||
return bambuLabColors['Unknown'];
|
||||
return { hex: '#CCCCCC' };
|
||||
}
|
||||
|
||||
export function getColorStyle(colorMapping: ColorMapping): React.CSSProperties {
|
||||
|
||||
@@ -100,9 +100,9 @@ export const bambuLabColors: Record<string, string> = {
|
||||
"Baby Blue": "#AEC3ED",
|
||||
|
||||
// PLA Silk Multi-Color
|
||||
"Silk Aurora Purple": "#7F3696",
|
||||
"Silk Phantom Blue": "#00629B",
|
||||
"Silk Mystic Magenta": "#720062",
|
||||
"Aurora Purple": "#7F3696",
|
||||
"Phantom Blue": "#00629B",
|
||||
"Mystic Magenta": "#720062",
|
||||
|
||||
// PLA Metal
|
||||
"Iron Gray Metallic": "#6B6C6F",
|
||||
@@ -162,7 +162,7 @@ export const bambuLabColors: Record<string, string> = {
|
||||
"Translucent Olive": "#A4B885",
|
||||
"Translucent Pink": "#F9B8D0",
|
||||
"Translucent Light Blue": "#A8D8F0",
|
||||
"Translucent Tea": "#D9C7A8",
|
||||
"Translucent Teal": "#008080",
|
||||
|
||||
// PETG CF
|
||||
"Brick Red": "#9F332A",
|
||||
|
||||
Reference in New Issue
Block a user