240 lines
5.5 KiB
Bash
Executable File
240 lines
5.5 KiB
Bash
Executable File
#!/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!"
|