# Improved Data Structure Proposal ## Current Issues 1. Mixed languages (English/Serbian) 2. String fields for numeric/boolean values 3. Inconsistent status representation 4. No proper inventory tracking 5. Missing important metadata ## Proposed Structure ```typescript interface Filament { // Identifiers id: string; sku?: string; // For internal tracking // Product Info brand: string; type: 'PLA' | 'PETG' | 'ABS' | 'TPU' | 'SILK' | 'CF' | 'WOOD'; material: { base: 'PLA' | 'PETG' | 'ABS' | 'TPU'; modifier?: 'Silk' | 'Matte' | 'Glow' | 'Wood' | 'CF'; }; color: { name: string; hex?: string; // Color code for UI display pantone?: string; // For color matching }; // Physical Properties weight: { value: number; // 1000 for 1kg, 500 for 0.5kg unit: 'g' | 'kg'; }; diameter: number; // 1.75 or 2.85 // Inventory Status inventory: { total: number; // Total spools available: number; // Available for use inUse: number; // Currently being used locations: { vacuum: number; // In vacuum storage opened: number; // Opened but usable printer: number; // Loaded in printer }; }; // Purchase Info pricing: { purchasePrice?: number; currency: 'RSD' | 'EUR' | 'USD'; supplier?: string; purchaseDate?: string; }; // Condition condition: { isRefill: boolean; openedDate?: string; expiryDate?: string; storageCondition: 'vacuum' | 'sealed' | 'opened' | 'desiccant'; humidity?: number; // Last measured }; // Metadata tags: string[]; // ['premium', 'engineering', 'easy-print'] notes?: string; // Special handling instructions images?: string[]; // S3 URLs for photos // Timestamps createdAt: string; updatedAt: string; lastUsed?: string; } ``` ## Benefits ### 1. **Better Filtering** ```typescript // Find all sealed PLA under 1kg filaments.filter(f => f.material.base === 'PLA' && f.weight.value <= 1000 && f.condition.storageCondition === 'vacuum' ) ``` ### 2. **Inventory Management** ```typescript // Get total available filament weight const totalWeight = filaments.reduce((sum, f) => sum + (f.inventory.available * f.weight.value), 0 ); // Find low stock items const lowStock = filaments.filter(f => f.inventory.available <= 1 && f.inventory.total > 0 ); ``` ### 3. **Color Management** ```typescript // Group by color for visualization const colorGroups = filaments.reduce((groups, f) => { const color = f.color.name; groups[color] = groups[color] || []; groups[color].push(f); return groups; }, {}); ``` ### 4. **Usage Tracking** ```typescript // Find most used filaments const mostUsed = filaments .filter(f => f.lastUsed) .sort((a, b) => new Date(b.lastUsed) - new Date(a.lastUsed)) .slice(0, 10); ``` ## Migration Strategy ### Phase 1: Add New Fields (Non-breaking) ```javascript // Update Lambda to handle both old and new structure const migrateFilament = (old) => ({ ...old, material: { base: old.tip || 'PLA', modifier: old.finish !== 'Basic' ? old.finish : undefined }, color: { name: old.boja }, weight: { value: 1000, // Default 1kg unit: 'g' }, inventory: { total: parseInt(old.kolicina) || 1, available: old.otvoreno ? 0 : 1, inUse: 0, locations: { vacuum: old.vakum ? 1 : 0, opened: old.otvoreno ? 1 : 0, printer: 0 } }, condition: { isRefill: old.refill === 'Da', storageCondition: old.vakum ? 'vacuum' : (old.otvoreno ? 'opened' : 'sealed') } }); ``` ### Phase 2: Update UI Components - Create new filter components for material type - Add inventory status indicators - Color preview badges - Storage condition icons ### Phase 3: Enhanced Features 1. **Barcode/QR Integration**: Generate QR codes for each spool 2. **Usage History**: Track which prints used which filament 3. **Alerts**: Low stock, expiry warnings 4. **Analytics**: Cost per print, filament usage trends ## DynamoDB Optimization ### Current Indexes - brand-index - tip-index - status-index ### Proposed Indexes ```terraform global_secondary_index { name = "material-color-index" hash_key = "material.base" range_key = "color.name" } global_secondary_index { name = "inventory-status-index" hash_key = "condition.storageCondition" range_key = "inventory.available" } global_secondary_index { name = "brand-type-index" hash_key = "brand" range_key = "material.base" } ``` ## Example Queries ### Find all available green filaments ```javascript const greenFilaments = await dynamodb.query({ IndexName: 'material-color-index', FilterExpression: 'contains(color.name, :green) AND inventory.available > :zero', ExpressionAttributeValues: { ':green': 'Green', ':zero': 0 } }).promise(); ``` ### Get inventory summary ```javascript const summary = await dynamodb.scan({ TableName: TABLE_NAME, ProjectionExpression: 'brand, material.base, inventory' }).promise(); const report = summary.Items.reduce((acc, item) => { const key = `${item.brand}-${item.material.base}`; acc[key] = (acc[key] || 0) + item.inventory.total; return acc; }, {}); ``` ## UI Improvements ### 1. **Visual Inventory Status** ```tsx
{filament.inventory.locations.vacuum > 0 && ( )} {filament.inventory.locations.opened > 0 && ( )}
``` ### 2. **Color Swatches** ```tsx
``` ### 3. **Smart Filters** - Quick filters: "Ready to use", "Low stock", "Refills only" - Material groups: "Standard PLA", "Engineering", "Specialty" - Storage status: "Vacuum sealed", "Open spools", "In printer" Would you like me to implement this improved structure?