feat: add backend OCR client method for VIN decode (refs #225)
Add VinDecodeResponse type and OcrClient.decodeVin() method that sends JSON POST to the new /decode/vin OCR endpoint. Unlike other OCR methods, this uses JSON body instead of multipart since there is no file upload. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -131,3 +131,21 @@ export interface ManualJobResponse {
|
|||||||
result?: ManualExtractionResult;
|
result?: ManualExtractionResult;
|
||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Response from VIN decode via Gemini (OCR service) */
|
||||||
|
export interface VinDecodeResponse {
|
||||||
|
success: boolean;
|
||||||
|
vin: string;
|
||||||
|
year: number | null;
|
||||||
|
make: string | null;
|
||||||
|
model: string | null;
|
||||||
|
trimLevel: string | null;
|
||||||
|
bodyType: string | null;
|
||||||
|
driveType: string | null;
|
||||||
|
fuelType: string | null;
|
||||||
|
engine: string | null;
|
||||||
|
transmission: string | null;
|
||||||
|
confidence: number;
|
||||||
|
processingTimeMs: number;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
|||||||
51
backend/src/features/ocr/external/ocr-client.ts
vendored
51
backend/src/features/ocr/external/ocr-client.ts
vendored
@@ -2,7 +2,7 @@
|
|||||||
* @ai-summary HTTP client for OCR service communication
|
* @ai-summary HTTP client for OCR service communication
|
||||||
*/
|
*/
|
||||||
import { logger } from '../../../core/logging/logger';
|
import { logger } from '../../../core/logging/logger';
|
||||||
import type { JobResponse, ManualJobResponse, OcrResponse, ReceiptExtractionResponse, VinExtractionResponse } from '../domain/ocr.types';
|
import type { JobResponse, ManualJobResponse, OcrResponse, ReceiptExtractionResponse, VinDecodeResponse, VinExtractionResponse } from '../domain/ocr.types';
|
||||||
|
|
||||||
/** OCR service configuration */
|
/** OCR service configuration */
|
||||||
const OCR_SERVICE_URL = process.env.OCR_SERVICE_URL || 'http://mvp-ocr:8000';
|
const OCR_SERVICE_URL = process.env.OCR_SERVICE_URL || 'http://mvp-ocr:8000';
|
||||||
@@ -373,6 +373,55 @@ export class OcrClient {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a VIN string into structured vehicle data via Gemini.
|
||||||
|
*
|
||||||
|
* Unlike other OCR methods, this sends JSON (not multipart) because
|
||||||
|
* VIN decode has no file upload.
|
||||||
|
*
|
||||||
|
* @param vin - 17-character Vehicle Identification Number
|
||||||
|
* @returns Structured vehicle data from Gemini decode
|
||||||
|
*/
|
||||||
|
async decodeVin(vin: string): Promise<VinDecodeResponse> {
|
||||||
|
const url = `${this.baseUrl}/decode/vin`;
|
||||||
|
|
||||||
|
logger.info('OCR VIN decode request', {
|
||||||
|
operation: 'ocr.client.decodeVin',
|
||||||
|
url,
|
||||||
|
vin,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.fetchWithTimeout(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ vin }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
logger.error('OCR VIN decode failed', {
|
||||||
|
operation: 'ocr.client.decodeVin.error',
|
||||||
|
status: response.status,
|
||||||
|
error: errorText,
|
||||||
|
});
|
||||||
|
const err: any = new Error(`OCR service error: ${response.status} - ${errorText}`);
|
||||||
|
err.statusCode = response.status;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = (await response.json()) as VinDecodeResponse;
|
||||||
|
|
||||||
|
logger.info('OCR VIN decode completed', {
|
||||||
|
operation: 'ocr.client.decodeVin.success',
|
||||||
|
success: result.success,
|
||||||
|
vin: result.vin,
|
||||||
|
confidence: result.confidence,
|
||||||
|
processingTimeMs: result.processingTimeMs,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the OCR service is healthy.
|
* Check if the OCR service is healthy.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user