Files
thrilltrack-explorer/src-old/lib/unitValidation.ts

98 lines
2.4 KiB
TypeScript

/**
* Unit Validation Utilities
* Ensures all stored units comply with metric-only storage rule
*
* Custom Knowledge Requirement:
* "Unit Conversion Rules: Storage: Always metric in DB (km/h, m, cm, kg)"
*/
import { convertValueToMetric, getMetricUnit } from './units';
export const METRIC_UNITS = [
'km/h', // Speed
'm', // Distance (large)
'cm', // Distance (small)
'kg', // Weight
'g', // Weight (small)
'G', // G-force
'celsius', // Temperature
'seconds', // Time
'minutes', // Time
'hours', // Time
'count', // Dimensionless
'%', // Percentage
] as const;
export const IMPERIAL_UNITS = [
'mph', // Speed
'ft', // Distance
'in', // Distance
'lbs', // Weight
'fahrenheit', // Temperature
] as const;
export type MetricUnit = typeof METRIC_UNITS[number];
export type ImperialUnit = typeof IMPERIAL_UNITS[number];
/**
* Check if a unit is metric
*/
export function isMetricUnit(unit: string): unit is MetricUnit {
return METRIC_UNITS.includes(unit as MetricUnit);
}
/**
* Validate that a unit is metric (throws if not)
*/
export function validateMetricUnit(unit: string, fieldName: string = 'unit'): void {
if (!isMetricUnit(unit)) {
throw new Error(
`${fieldName} must be metric. Received "${unit}", expected one of: ${METRIC_UNITS.join(', ')}`
);
}
}
/**
* Ensure value is in metric units, converting if necessary
*
* @example
* ```typescript
* const { value, unit } = ensureMetricUnit(60, 'mph');
* // Returns: { value: 96.56, unit: 'km/h' }
* ```
*/
export function ensureMetricUnit(
value: number,
unit: string
): { value: number; unit: MetricUnit } {
if (isMetricUnit(unit)) {
return { value, unit };
}
// Convert imperial to metric
const metricValue = convertValueToMetric(value, unit);
const metricUnit = getMetricUnit(unit) as MetricUnit;
return { value: metricValue, unit: metricUnit };
}
/**
* Batch validate an array of measurements
*/
export function validateMetricUnits(
measurements: Array<{ value: number; unit: string; name: string }>
): { valid: boolean; errors: string[] } {
const errors: string[] = [];
measurements.forEach(({ unit, name }) => {
if (!isMetricUnit(unit)) {
errors.push(`${name}: "${unit}" is not a valid metric unit`);
}
});
return {
valid: errors.length === 0,
errors
};
}