#!/bin/zsh echo "📦 Creating RC Compatibility Data Layer + Engine..." BASE="src/lib" ############################################# # CREATE DIRECTORY STRUCTURE ############################################# mkdir -p "$BASE/data" mkdir -p "$BASE/compatibility" mkdir -p "$BASE/search" ############################################# # CREATE DATA FILES ############################################# # categories.js cat > "$BASE/data/categories.js" << 'EOF' export const CATEGORIES = [ "drivetrain", "suspension", "chassis", "shocks", "electronics", "steering", "wheels", "tires", "body" ]; EOF # models.js cat > "$BASE/data/models.js" << 'EOF' export const MODELS = [ { id: "tamiya-hotshot", brand: "Tamiya", name: "Hotshot", scale: "1/10", year: 1985, categories: ["drivetrain", "suspension", "chassis", "shocks"], generation: 1, }, { id: "tamiya-supershot", brand: "Tamiya", name: "Super Shot", scale: "1/10", year: 1986, categories: ["drivetrain", "suspension", "chassis", "shocks"], generation: 1, }, { id: "traxxas-rustler-4x4", brand: "Traxxas", name: "Rustler 4x4", scale: "1/10", year: 2018, categories: ["drivetrain", "suspension", "electronics", "steering"], generation: 2, } ]; EOF # parts.js cat > "$BASE/data/parts.js" << 'EOF' export const PARTS = [ { id: "TAM-198055", name: "Hotshot Front Gearbox", category: "drivetrain", fitsModels: ["tamiya-hotshot", "tamiya-supershot"], notes: "Original vintage fit.", }, { id: "TAM-430512", name: "Super Shot Steering Knuckle", category: "steering", fitsModels: ["tamiya-supershot"], }, { id: "TRA-6755X", name: "Traxxas Steel Driveshaft Upgrade", category: "drivetrain", fitsModels: ["traxxas-rustler-4x4"], upgrade: true, }, { id: "GEN-UNIV-55MM", name: "Generic 55mm Shock Set", category: "shocks", fitsModels: ["tamiya-hotshot", "tamiya-supershot"], universalFit: true, } ]; EOF ############################################# # COMPATIBILITY UTILITIES ############################################# cat > "$BASE/compatibility/utils.js" << 'EOF' export function getModel(modelId, models) { return models.find(m => m.id === modelId) || null; } export function getPart(partId, parts) { return parts.find(p => p.id === partId) || null; } EOF ############################################# # COMPATIBILITY SCORING SYSTEM ############################################# cat > "$BASE/compatibility/scoring.js" << 'EOF' export function scoreCompatibility({ directFit, sameBrand, sameCategory, universal, generationMatch }) { let score = 0; if (directFit) score += 100; if (sameBrand) score += 20; if (sameCategory) score += 15; if (generationMatch) score += 10; if (universal) score += 5; return Math.min(score, 100); } EOF ############################################# # MAIN COMPATIBILITY ENGINE ############################################# cat > "$BASE/compatibility/engine.js" << 'EOF' import { MODELS } from "../data/models"; import { PARTS } from "../data/parts"; import { getModel, getPart } from "./utils"; import { scoreCompatibility } from "./scoring"; // Check model-to-part compatibility export function isCompatible(modelId, partId) { const model = getModel(modelId, MODELS); const part = getPart(partId, PARTS); if (!model || !part) { return { compatible: false, reason: "Unknown model or part" }; } const directFit = part.fitsModels.includes(modelId); const sameBrand = model.brand && part.brand && part.brand === model.brand; const sameCategory = model.categories.includes(part.category); const universal = !!part.universalFit; const generationMatch = part.generation ? part.generation === model.generation : false; const score = scoreCompatibility({ directFit, sameBrand, sameCategory, universal, generationMatch }); return { compatible: score > 0, score, details: { directFit, sameBrand, sameCategory, universal, generationMatch } }; } // Get all compatible parts for a model export function getCompatibleParts(modelId) { return PARTS .map(part => ({ part, result: isCompatible(modelId, part.id) })) .filter(item => item.result.compatible) .sort((a, b) => b.result.score - a.result.score); } // Get models that fit a part export function getCrossCompatibleModels(partId) { return MODELS .map(model => ({ model, result: isCompatible(model.id, partId) })) .filter(item => item.result.compatible) .sort((a, b) => b.result.score - a.result.score); } // Suggest alternative parts in same category export function suggestAlternatives(partId) { const part = getPart(partId, PARTS); if (!part) return []; return PARTS.filter(p => p.category === part.category && p.id !== partId ); } EOF ############################################# # SEARCH ENGINE ############################################# cat > "$BASE/search/search.js" << 'EOF' import { MODELS } from "../data/models"; import { PARTS } from "../data/parts"; export function searchModels(query) { const q = query.toLowerCase(); return MODELS.filter(m => m.name.toLowerCase().includes(q) || m.brand.toLowerCase().includes(q) ); } export function searchParts(query) { const q = query.toLowerCase(); return PARTS.filter(p => p.name.toLowerCase().includes(q) || p.id.toLowerCase().includes(q) ); } EOF echo "🎉 Data layer + compatibility engine generated successfully!"