const mongoose = require('mongoose'); const orderItemSchema = new mongoose.Schema( { menuItem: { type: mongoose.Schema.Types.ObjectId, ref: 'MenuItem', required: true }, menuItemName: { type: String, required: true }, // denormalised snapshot for reporting variantId: { type: mongoose.Schema.Types.ObjectId, required: true }, variantLabel: { type: String, required: true }, // snapshot qty: { type: Number, required: true, min: 1 }, priceAtSale: { type: Number, required: true, min: 0 }, // snapshot — never recalculate from live menu }, { _id: false } ); const orderSchema = new mongoose.Schema( { // Client-generated UUID — used as idempotency key during offline sync localId: { type: String, required: true, unique: true, index: true }, orderType: { type: String, enum: ['dine-in', 'takeaway', 'delivery'], required: true }, items: { type: [orderItemSchema], required: true }, subtotal: { type: Number, required: true }, discount: { amount: { type: Number, default: 0 }, reason: { type: String, default: '' }, }, netTotal: { type: Number, required: true }, deliveryFee: { type: Number, default: 0 }, cashReceived: { type: Number, default: 0 }, change: { type: Number, default: 0 }, status: { type: String, enum: ['held', 'completed', 'voided'], default: 'completed' }, voidedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', default: null }, voidedAt: { type: Date, default: null }, cashier: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, // synced is a client-side-only concept; all server records are considered synced createdAt: { type: Date, default: Date.now }, }, { timestamps: false } // we manage createdAt manually to preserve offline timestamps ); orderSchema.index({ createdAt: -1 }); orderSchema.index({ status: 1, createdAt: -1 }); module.exports = mongoose.model('Order', orderSchema);