Customer Measurements
Customer Measurements is a reusable body-measurement card per customer — eight measurement fields in inches plus a free-form list of size preferences by brand or category — so returning customers do not need to be re-measured for every new stitching order.
Overview
Each record stores a customer (name and optional phone, with the same live customer search/autocomplete used on Tailoring Orders), eight body measurements — Chest, Waist, Hip, Shoulder, Sleeve, Length, Inseam, Neck, all in inches — free-text Notes, and a list of Size Preferences, each a Brand/Category plus a Size (e.g. "Levis — 32" or "Kurta — M").
Measurement cards only display the specific fields that have a value — an unset field is simply omitted from the card rather than showing a blank or zero, keeping the grid compact for customers who only have a couple of measurements on file.
Size Preferences are added one at a time in the form (type a brand/category and a size, or press Enter, then click + Add) and appear as removable chips before saving; on the saved card they render the same way as read-only tags.
Saving is an upsert keyed on phone number, tenant and store — entering the same phone number again updates that customer's existing record rather than creating a duplicate.
Before You Start
- Only Customer Name is required — every measurement field, notes, and size preferences are optional and can be added over multiple visits.
- The upsert-by-phone behaviour only applies when a Phone number is entered; saving with no phone number always inserts a new row and can silently create a second unrelated record for someone with the same name.
- All measurement inputs accept quarter-inch increments (step 0.25) and are stored in inches only — there is no metric (cm) toggle.
Step-by-Step Guide
1 Save a new customer's measurements
- Click + Add Measurement.
- Start typing in Customer Name * — pick a match from the dropdown (auto-fills Phone) or type a new name.
- Enter Phone if not auto-filled.
- Fill in any of the eight Body Measurements (inches) fields — Chest, Waist, Hip, Shoulder, Sleeve, Length, Inseam, Neck — leaving any you do not have blank.
- Under Size Preferences, type a Brand / Category (e.g. "Levis") and a Size (e.g. "32"), then press Enter or click + Add to add it as a chip; repeat for as many brands as needed.
- Add any Notes (e.g. "prefers loose fit") and click Save Measurements.
2 Update an existing customer's measurements
- Find the customer's card (search by name or phone) and click Edit.
- Adjust any measurement, add or remove Size Preference chips, or update Notes.
- Click Save Measurements — this re-saves against the same phone number, updating the existing record in place rather than creating a new one.
3 Remove a measurement record
- Click Del on a customer's card and confirm — this permanently deletes that measurement record.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
+ Add Measurement | Opens the blank measurement form. |
Customer Name * / Phone | Required name with live-search autocomplete against /customers; phone is optional but is also the key used to update an existing record instead of creating a duplicate. |
Chest / Waist / Hip / Shoulder / Sleeve / Length / Inseam / Neck | Eight optional body measurements, all in inches, quarter-inch increments; only fields with a saved value are shown on the card. |
Size Preferences | A free-form list of Brand/Category + Size pairs (e.g. "Levis — 32"), added and removed as chips; stored as a JSON array in the sizePrefs column. |
Notes | Free-text notes, e.g. fit preferences or special cutting instructions. |
Search box | Filters saved measurement cards by customer name or phone. |
Edit / Del | Edit opens the form pre-filled with every saved field and size preference; Del permanently deletes the record after a confirmation prompt. |
"Updated" timestamp | Shown at the bottom of each card, formatted via storeFmt.date from the record's updatedAt value. |
Tips & Best Practices
- Always capture the phone number when saving measurements — it is what lets you safely re-save updated numbers for the same customer later without creating a duplicate card.
- Use Size Preferences for customers who shop specific brands regularly (e.g. always a size 32 in Levis but Large in a local kurta brand) — it saves re-asking every visit and helps staff recommend the right size fast.
- Only fill in the measurements you actually need for your typical orders — the card layout is designed to stay compact when some fields are left blank, so there is no downside to a partial record.
Troubleshooting & FAQ
I saved measurements for a returning customer and now see two cards for them.
A measurement field I entered isn't showing on the card.
Size Preferences chip won't add when I click + Add.
The measurements are showing in the wrong unit.
🧑💻 Developer Notes
Source component(s):
frontend-app/pos-app-garment/src/pages/garment/MeasurementPage.jsx
Backend endpoints used:
GET /garment/measurementsPOST /garment/measurements (upsert)DELETE /garment/measurements/:idGET /customers (typeahead)
Related tables (db-core repositories):
GarmentMeasurement
Redux slices:
None — local component state only
Feature flag key: billing
There is no PUT/update endpoint for measurements — both create and edit go through the same POST /garment/measurements, which the pos-core upsertMeasurement() function resolves into an insert-or-update by looking up an existing row matching customerPhone plus tenant/store scoping (guarded with and()/or() so chained .where() calls do not silently overwrite each other, per an explicit code comment warning about that Drizzle pitfall). The base "CREATE TABLE IF NOT EXISTS GarmentMeasurement" in backend/src/lib/db.js does not include a sizePrefs or stylePrefs column at all — both were added afterward via idempotent ALTER TABLE ... ADD COLUMN IF NOT EXISTS statements, and a stylePrefs column exists in the schema but is not read or written anywhere in MeasurementPage.jsx (only sizePrefs is used), so it currently looks unused from this screen.