mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 14:31:12 -05:00
98 lines
2.4 KiB
TypeScript
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
|
|
};
|
|
}
|