106 lines
4.0 KiB
JavaScript
106 lines
4.0 KiB
JavaScript
const mongoose = require('mongoose');
|
|
|
|
const variantSchema = new mongoose.Schema({
|
|
color: { type: String, required: true },
|
|
colorHex: { type: String, default: '#000000' },
|
|
finish: { type: String, default: 'Gloss' },
|
|
sku: { type: String, default: '' },
|
|
price: { type: Number, required: true },
|
|
salePrice: { type: Number, default: 0 },
|
|
stock: { type: Number, required: true, default: 0 },
|
|
image: { type: String, default: '' }
|
|
});
|
|
|
|
const customSpecSchema = new mongoose.Schema({
|
|
key: { type: String, required: true },
|
|
value: { type: String, required: true }
|
|
});
|
|
|
|
const guitarSpecSchema = new mongoose.Schema({
|
|
guitarType: { type: String, default: 'Electric' }, // Electric, Acoustic, Bass, Classical, Accessories
|
|
bodyShape: { type: String, default: 'Stratocaster' },
|
|
bodyMaterial: { type: String, default: 'Alder' },
|
|
topMaterial: { type: String, default: '' },
|
|
backMaterial: { type: String, default: '' },
|
|
sideMaterial: { type: String, default: '' },
|
|
neckMaterial: { type: String, default: 'Maple' },
|
|
fingerboardMaterial: { type: String, default: 'Rosewood' },
|
|
scaleLength: { type: String, default: '25.5"' },
|
|
numberOfStrings: { type: Number, default: 6 },
|
|
frets: { type: Number, default: 22 },
|
|
pickupConfiguration: { type: String, default: 'SSS' }, // SSS, HSS, HH, Single, Acoustic Pickup
|
|
pickupType: { type: String, default: 'Passive Single-Coil' },
|
|
bridgeType: { type: String, default: 'Tremolo' },
|
|
tuningMachines: { type: String, default: 'Standard Die-Cast' },
|
|
handOrientation: { type: String, enum: ['Right-Handed', 'Left-Handed'], default: 'Right-Handed' },
|
|
color: { type: String, default: '' },
|
|
finish: { type: String, default: 'Gloss Polyurethane' },
|
|
includesCase: { type: Boolean, default: false },
|
|
customSpecs: [customSpecSchema]
|
|
});
|
|
|
|
const productSchema = new mongoose.Schema({
|
|
name: { type: String, required: true, trim: true },
|
|
slug: { type: String, required: true, unique: true, lowercase: true },
|
|
sku: { type: String, required: true, unique: true },
|
|
brand: { type: mongoose.Schema.Types.ObjectId, ref: 'Brand', required: true },
|
|
category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category', required: true },
|
|
description: { type: String, required: true },
|
|
shortDescription: { type: String, default: '' },
|
|
|
|
// Pricing & Discounts
|
|
price: { type: Number, required: true, min: 0 },
|
|
salePrice: { type: Number, default: 0, min: 0 },
|
|
discountType: { type: String, enum: ['percentage', 'fixed'], default: 'percentage' },
|
|
discountValue: { type: Number, default: 0, min: 0 },
|
|
costPrice: { type: Number, default: 0 },
|
|
|
|
// Inventory
|
|
stock: { type: Number, required: true, default: 10, min: 0 },
|
|
lowStockThreshold: { type: Number, default: 3 },
|
|
|
|
// Media
|
|
images: [{ type: String }],
|
|
primaryImage: { type: String, default: '' },
|
|
videoUrl: { type: String, default: '' },
|
|
audioDemoUrl: { type: String, default: '' },
|
|
|
|
// Specs & Variants
|
|
specs: guitarSpecSchema,
|
|
variants: [variantSchema],
|
|
tags: [{ type: String }],
|
|
weightKg: { type: Number, default: 4.5 },
|
|
dimensionsCm: { type: String, default: '105 x 38 x 10' },
|
|
|
|
// Rating & Sales Metrics
|
|
rating: { type: Number, default: 4.8 },
|
|
numReviews: { type: Number, default: 0 },
|
|
salesCount: { type: Number, default: 0 },
|
|
|
|
// Badges & Flags
|
|
isFeatured: { type: Boolean, default: false },
|
|
isNewArrival: { type: Boolean, default: false },
|
|
isBestSeller: { type: Boolean, default: false },
|
|
isActive: { type: Boolean, default: true },
|
|
|
|
// SEO
|
|
metaTitle: { type: String, default: '' },
|
|
metaDescription: { type: String, default: '' }
|
|
}, { timestamps: true });
|
|
|
|
// Auto-generate SKU before validation if missing
|
|
productSchema.pre('validate', function(next) {
|
|
if (!this.sku) {
|
|
const randomNum = Math.floor(10000 + Math.random() * 90000);
|
|
this.sku = `GTR-2026-${randomNum}`;
|
|
}
|
|
if (this.images && this.images.length > 0 && !this.primaryImage) {
|
|
this.primaryImage = this.images[0];
|
|
}
|
|
next();
|
|
});
|
|
|
|
productSchema.index({ name: 'text', description: 'text', tags: 'text' });
|
|
|
|
module.exports = mongoose.model('Product', productSchema);
|