This commit is contained in:
Eric Gullickson
2025-11-01 21:27:42 -05:00
parent 20953c6dee
commit 046c66fc7d
203 changed files with 5699 additions and 404943 deletions

View File

@@ -228,7 +228,7 @@ npm test -- features/vehicles --coverage
- Both features depend on vehicles as primary entity
### Potential Enhancements
- Vehicle image uploads (MinIO integration)
- Vehicle image uploads (filesystem storage integration)
- Enhanced platform service integration for real-time updates
- Vehicle value estimation via additional platform services
- Maintenance scheduling based on vehicle age/mileage

View File

@@ -11,7 +11,6 @@ import {
VehicleParams
} from '../domain/vehicles.types';
import { VehiclesController } from './vehicles.controller';
import { tenantMiddleware } from '../../../core/middleware/tenant';
export const vehiclesRoutes: FastifyPluginAsync = async (
fastify: FastifyInstance,
@@ -21,31 +20,31 @@ export const vehiclesRoutes: FastifyPluginAsync = async (
// GET /api/vehicles - Get user's vehicles
fastify.get('/vehicles', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getUserVehicles.bind(vehiclesController)
});
// POST /api/vehicles - Create new vehicle
fastify.post<{ Body: CreateVehicleBody }>('/vehicles', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.createVehicle.bind(vehiclesController)
});
// GET /api/vehicles/:id - Get specific vehicle
fastify.get<{ Params: VehicleParams }>('/vehicles/:id', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getVehicle.bind(vehiclesController)
});
// PUT /api/vehicles/:id - Update vehicle
fastify.put<{ Params: VehicleParams; Body: UpdateVehicleBody }>('/vehicles/:id', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.updateVehicle.bind(vehiclesController)
});
// DELETE /api/vehicles/:id - Delete vehicle
fastify.delete<{ Params: VehicleParams }>('/vehicles/:id', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.deleteVehicle.bind(vehiclesController)
});
@@ -53,43 +52,43 @@ export const vehiclesRoutes: FastifyPluginAsync = async (
// GET /api/vehicles/dropdown/years - Available model years
fastify.get('/vehicles/dropdown/years', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getDropdownYears.bind(vehiclesController)
});
// GET /api/vehicles/dropdown/makes?year=2024 - Get makes for year (Level 1)
fastify.get<{ Querystring: { year: number } }>('/vehicles/dropdown/makes', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getDropdownMakes.bind(vehiclesController)
});
// GET /api/vehicles/dropdown/models?year=2024&make_id=1 - Get models for year/make (Level 2)
fastify.get<{ Querystring: { year: number; make_id: number } }>('/vehicles/dropdown/models', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getDropdownModels.bind(vehiclesController)
});
// GET /api/vehicles/dropdown/trims?year=2024&make_id=1&model_id=1 - Get trims (Level 3)
fastify.get<{ Querystring: { year: number; make_id: number; model_id: number } }>('/vehicles/dropdown/trims', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getDropdownTrims.bind(vehiclesController)
});
// GET /api/vehicles/dropdown/engines?year=2024&make_id=1&model_id=1&trim_id=1 - Get engines (Level 4)
fastify.get<{ Querystring: { year: number; make_id: number; model_id: number; trim_id: number } }>('/vehicles/dropdown/engines', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getDropdownEngines.bind(vehiclesController)
});
// GET /api/vehicles/dropdown/transmissions?year=2024&make_id=1&model_id=1 - Get transmissions (Level 3)
fastify.get<{ Querystring: { year: number; make_id: number; model_id: number } }>('/vehicles/dropdown/transmissions', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.getDropdownTransmissions.bind(vehiclesController)
});
// POST /api/vehicles/decode-vin - Decode VIN and return vehicle information
fastify.post<{ Body: { vin: string } }>('/vehicles/decode-vin', {
preHandler: [fastify.authenticate, tenantMiddleware],
preHandler: [fastify.authenticate],
handler: vehiclesController.decodeVIN.bind(vehiclesController)
});
};

View File

@@ -26,11 +26,9 @@ export class VehiclesService {
constructor(private repository: VehiclesRepository) {
// Initialize platform vehicles client
const platformConfig = appConfig.getPlatformServiceConfig('vehicles');
const platformVehiclesUrl = appConfig.getPlatformVehiclesUrl();
const platformClient = new PlatformVehiclesClient({
baseURL: platformConfig.url,
apiKey: platformConfig.apiKey,
tenantId: appConfig.config.server.tenant_id,
baseURL: platformVehiclesUrl,
timeout: 3000,
logger
});

View File

@@ -44,8 +44,6 @@ export interface VINDecodeResponse {
export interface PlatformVehiclesClientConfig {
baseURL: string;
apiKey: string;
tenantId?: string;
timeout?: number;
logger?: Logger;
}
@@ -58,27 +56,19 @@ export class PlatformVehiclesClient {
private readonly httpClient: AxiosInstance;
private readonly logger: Logger | undefined;
private readonly circuitBreakers: Map<string, CircuitBreaker> = new Map();
private readonly tenantId: string | undefined;
constructor(config: PlatformVehiclesClientConfig) {
this.logger = config.logger;
this.tenantId = config.tenantId || process.env.TENANT_ID;
// Initialize HTTP client
this.httpClient = axios.create({
baseURL: config.baseURL,
timeout: config.timeout || 3000,
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json',
},
});
// Inject tenant header for all requests when available
if (this.tenantId) {
this.httpClient.defaults.headers.common['X-Tenant-ID'] = this.tenantId;
}
// Setup response interceptors for logging
this.httpClient.interceptors.response.use(
(response) => {