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
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user