Initial commit
This commit is contained in:
105
server/models/Product.js
Normal file
105
server/models/Product.js
Normal file
@@ -0,0 +1,105 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user