Cart Data Management
Overview
The cart system now separates reference data from snapshot data to prevent duplication while maintaining historical accuracy for paid orders.
Structure
Cart (Reference Only)
Used for unpaid commands. Contains only references to products and quantities:
{
products: [
{
product_id: ObjectId,
quantity: number
}
]
}
CartSnapshot (Historical Data)
Automatically created when a command is marked as paid. Stores immutable pricing data:
{
products: [
{
product_id: ObjectId,
title: string,
price: number,
quantity: number
}
],
totalPrice: number
}
Usage
Creating a Command
When creating a command, only store product IDs and quantities:
const command = await Command.create({
// ... other fields
cart: {
products: [
{ product_id: "...", quantity: 2 },
{ product_id: "...", quantity: 1 }
]
},
paid: false
});
Marking as Paid
Use the service to automatically create a snapshot:
import commandService from '../services/command.service';
// This creates the snapshot and marks as paid
const paidCommand = await commandService.markAsPaid(commandId);
Displaying Cart Data
The service handles both paid and unpaid commands:
import commandService from '../services/command.service';
// Returns current pricing for unpaid, snapshot for paid
const cartData = await commandService.getCartWithPricing(command);
// cartData will have { products: [...], totalPrice: number }
Example: Payment Webhook
app.post('/webhook/stripe', async (req, res) => {
const { commandId } = req.body;
// Mark as paid - automatically creates snapshot
await commandService.markAsPaid(commandId);
res.status(200).send('OK');
});
Benefits
✅ No duplication for unpaid carts - prices always reflect current product data ✅ Historical accuracy for paid orders - prices frozen at payment time ✅ Automatic snapshots - service handles snapshot creation ✅ Consistent API - same method for both paid/unpaid display logic
Migration Note
Existing commands with old cart structure will need migration. The cartSnapshot field is optional, so the system remains backward compatible.