Aller au contenu principal

Product Measurement System

This document describes the comprehensive measurement system implemented for products in BaldrTs.

Overview

The measurement system replaces the simple weight field with a structured measurements object that includes:

  • Weight with unit specification
  • Dimensions (length, width, height) with unit specification
  • Volume with unit specification

Structure

Weight

{
value: number,
unit: "g" | "kg" | "mg"
}

Dimensions

{
length: { value: number, unit: LengthUnit },
width: { value: number, unit: LengthUnit },
height: { value: number, unit: LengthUnit }
}
// LengthUnit: "mm" | "cm" | "m"

Volume

{
value: number,
unit: "ml" | "cl" | "l"
}

Usage Examples

Creating a Product with Measurements

import Product from "./models/product.model";

// Example 1: Small item (jewelry)
const ring = await Product.create({
module_id: moduleId,
title: "Gold Ring",
slug: "gold-ring-18k",
active: true,
translation: { /* ... */ },
availability: { /* ... */ },
measurements: {
weight: {
value: 5.2,
unit: "g"
},
dimensions: {
length: { value: 20, unit: "mm" },
width: { value: 18, unit: "mm" },
height: { value: 5, unit: "mm" }
}
}
});

// Example 2: Packaged product (wine)
const wine = await Product.create({
module_id: moduleId,
title: "Champagne Brut 2018",
slug: "champagne-brut-2018",
active: true,
translation: { /* ... */ },
availability: { /* ... */ },
measurements: {
weight: {
value: 1.5,
unit: "kg"
},
dimensions: {
length: { value: 8, unit: "cm" },
width: { value: 8, unit: "cm" },
height: { value: 30, unit: "cm" }
},
volume: {
value: 750,
unit: "ml"
}
}
});

// Example 3: Large item (furniture)
const table = await Product.create({
module_id: moduleId,
title: "Dining Table",
slug: "dining-table-oak",
active: true,
translation: { /* ... */ },
availability: { /* ... */ },
measurements: {
weight: {
value: 45,
unit: "kg"
},
dimensions: {
length: { value: 180, unit: "cm" },
width: { value: 90, unit: "cm" },
height: { value: 75, unit: "cm" }
}
}
});

Using Conversion Utilities

import {
convertWeight,
convertDimensions,
convertVolume,
calculateVolumeFromDimensions,
formatWeight,
formatDimensions,
formatVolume
} from "./utils/measurement.utils";

// Convert weight from kg to g
const weightInKg = { value: 1.5, unit: "kg" };
const weightInG = convertWeight(weightInKg, "g");
// Result: { value: 1500, unit: "g" }

// Convert dimensions from cm to mm
const dimensionsInCm = {
length: { value: 30, unit: "cm" },
width: { value: 20, unit: "cm" },
height: { value: 10, unit: "cm" }
};
const dimensionsInMm = convertDimensions(dimensionsInCm, "mm");
// Result: { length: { value: 300, unit: "mm" }, ... }

// Calculate volume from dimensions
const volume = calculateVolumeFromDimensions(dimensionsInCm);
// Result: { value: 6000, unit: "ml" } (30*20*10 = 6000 cm³ = 6000 ml)

// Format for display
const displayWeight = formatWeight(weightInKg);
// Result: "1.5 kg"

const displayDimensions = formatDimensions(dimensionsInCm);
// Result: "30 × 20 × 10 cm"

const displayVolume = formatVolume({ value: 750, unit: "ml" });
// Result: "750 ml"

Using Validation

import { productMeasurementsSchema } from "./validations/measurement.validation";

// Validate measurements before saving
const measurementData = {
weight: {
value: 1.5,
unit: "kg"
},
dimensions: {
length: { value: 30, unit: "cm" },
width: { value: 20, unit: "cm" },
height: { value: 10, unit: "cm" }
}
};

try {
const validatedMeasurements = productMeasurementsSchema.parse(measurementData);
// Data is valid, proceed with saving
} catch (error) {
// Handle validation errors
console.error("Invalid measurement data:", error);
}

Shipping Calculations

The measurement system is designed to integrate with shipping providers:

// Calculate shipping costs based on weight and dimensions
function calculateShipping(product) {
const { weight, dimensions } = product.measurements;

// Convert to standard units for shipping calculation
const weightInKg = convertWeight(weight, "kg");
const dimsInCm = convertDimensions(dimensions, "cm");

// Calculate volumetric weight (for air shipping)
const volumetricWeight =
(dimsInCm.length.value * dimsInCm.width.value * dimsInCm.height.value) / 5000;

// Use the greater of actual weight or volumetric weight
const chargeableWeight = Math.max(weightInKg.value, volumetricWeight);

return calculateShippingCost(chargeableWeight);
}

Migration from Old Weight Field

If you have existing products with the old weight field, here's a migration script:

// Migration script
async function migrateProductWeights() {
const products = await Product.find({ weight: { $exists: true } });

for (const product of products) {
if (product.weight && !product.measurements) {
product.measurements = {
weight: {
value: product.weight,
unit: "kg" // Assuming old weight was in kg
}
};

// Remove old weight field
product.weight = undefined;

await product.save();
}
}

console.log(`Migrated ${products.length} products`);
}

Benefits

  1. Metric System: All measurements use French/European metric units
  2. Accurate Shipping: Calculate shipping costs based on actual dimensions
  3. Consistent Standards: Standardized measurements across the platform
  4. Warehouse Integration: Better inventory management with precise dimensions
  5. Type Safety: Full TypeScript support with type checking
  6. Validation: Built-in validation with Zod schemas

API Response Examples

{
"_id": "507f1f77bcf86cd799439011",
"title": "Gold Ring",
"measurements": {
"weight": {
"value": 5.2,
"unit": "g"
},
"dimensions": {
"length": { "value": 20, "unit": "mm" },
"width": { "value": 18, "unit": "mm" },
"height": { "value": 5, "unit": "mm" }
}
}
}