fix: Short VIN Storage - Issue #1
All checks were successful
Deploy to Staging / Build Images (push) Successful in 4m31s
Deploy to Staging / Deploy to Staging (push) Successful in 36s
Deploy to Staging / Verify Staging (push) Successful in 5s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped

This commit is contained in:
Eric Gullickson
2026-01-01 10:05:56 -06:00
parent 7631d961c5
commit f79fda79b9
9 changed files with 109 additions and 29 deletions

View File

@@ -16,7 +16,7 @@ import { cacheService } from '../../../core/config/redis';
import { getStorageService } from '../../../core/storage/storage.service';
import * as fs from 'fs/promises';
import * as path from 'path';
import { isValidVIN } from '../../../shared-minimal/utils/validators';
import { isValidVIN, isValidPreModernVIN } from '../../../shared-minimal/utils/validators';
import { normalizeMakeName, normalizeModelName } from './name-normalizer';
import { getVehicleDataService, getPool } from '../../platform';
@@ -31,12 +31,16 @@ export class VehiclesService {
async createVehicle(data: CreateVehicleRequest, userId: string): Promise<VehicleResponse> {
logger.info('Creating vehicle', { userId, vin: data.vin, licensePlate: data.licensePlate });
// Pre-1981 vehicles have no VIN format requirement
// Pre-1981 vehicles have relaxed VIN format requirements
const isPreModern = data.year && data.year < 1981;
if (data.vin) {
// Validate VIN format only for modern vehicles (1981+)
if (!isPreModern && !isValidVIN(data.vin)) {
// Validate VIN format based on vehicle year
if (isPreModern) {
if (!isValidPreModernVIN(data.vin)) {
throw new Error('Invalid VIN format for pre-1981 vehicle');
}
} else if (!isValidVIN(data.vin)) {
throw new Error('Invalid VIN format');
}
// Duplicate check only when VIN is present
@@ -95,8 +99,8 @@ export class VehiclesService {
}
async updateVehicle(
id: string,
data: UpdateVehicleRequest,
id: string,
data: UpdateVehicleRequest,
userId: string
): Promise<VehicleResponse> {
// Verify ownership
@@ -107,7 +111,31 @@ export class VehiclesService {
if (existing.userId !== userId) {
throw new Error('Unauthorized');
}
// Determine the effective year for validation (use new year if provided, else existing)
const effectiveYear = data.year !== undefined ? data.year : existing.year;
const isPreModern = effectiveYear && effectiveYear < 1981;
// Validate VIN if provided
if (data.vin !== undefined && data.vin.trim().length > 0) {
const trimmedVin = data.vin.trim();
// Validate VIN format based on vehicle year
if (isPreModern) {
if (!isValidPreModernVIN(trimmedVin)) {
throw new Error('Invalid VIN format for pre-1981 vehicle');
}
} else if (!isValidVIN(trimmedVin)) {
throw new Error('Invalid VIN format');
}
// Check for duplicate VIN (only if VIN is changing)
if (trimmedVin !== existing.vin) {
const duplicate = await this.repository.findByUserAndVIN(userId, trimmedVin);
if (duplicate && duplicate.id !== id) {
throw new Error('Vehicle with this VIN already exists');
}
}
}
// Normalize any provided name fields
const normalized: UpdateVehicleRequest = { ...data } as any;
if (data.make !== undefined) {
@@ -122,10 +150,10 @@ export class VehiclesService {
if (!updated) {
throw new Error('Update failed');
}
// Invalidate cache
await this.invalidateUserCache(userId);
return this.toResponse(updated);
}