Redesign
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user