fix: OCR API error
All checks were successful
Deploy to Staging / Build Images (push) Successful in 7m45s
Deploy to Staging / Deploy to Staging (push) Successful in 51s
Deploy to Staging / Verify Staging (push) Successful in 2m31s
Deploy to Staging / Notify Staging Ready (push) Successful in 8s
Deploy to Staging / Notify Staging Failure (push) Has been skipped

This commit is contained in:
Eric Gullickson
2026-02-06 13:01:32 -06:00
parent 88db803b6a
commit 66314a0493
6 changed files with 244 additions and 26 deletions

View File

@@ -1,9 +1,8 @@
/**
* @ai-summary HTTP client for OCR service communication
*/
import FormData from 'form-data';
import { logger } from '../../../core/logging/logger';
import type { JobResponse, OcrResponse } from '../domain/ocr.types';
import type { JobResponse, OcrResponse, VinExtractionResponse } from '../domain/ocr.types';
/** OCR service configuration */
const OCR_SERVICE_URL = process.env.OCR_SERVICE_URL || 'http://mvp-ocr:8000';
@@ -32,12 +31,7 @@ export class OcrClient {
contentType: string,
preprocess: boolean = true
): Promise<OcrResponse> {
const formData = new FormData();
formData.append('file', fileBuffer, {
filename: this.getFilenameFromContentType(contentType),
contentType,
});
const formData = this.buildFormData(fileBuffer, contentType);
const url = `${this.baseUrl}/extract?preprocess=${preprocess}`;
logger.info('OCR extract request', {
@@ -50,8 +44,7 @@ export class OcrClient {
const response = await this.fetchWithTimeout(url, {
method: 'POST',
body: formData as any,
headers: formData.getHeaders(),
body: formData,
});
if (!response.ok) {
@@ -77,6 +70,55 @@ export class OcrClient {
return result;
}
/**
* Extract VIN from an image using VIN-specific OCR.
*
* @param fileBuffer - Image file buffer
* @param contentType - MIME type of the file
* @returns VIN extraction result
*/
async extractVin(
fileBuffer: Buffer,
contentType: string
): Promise<VinExtractionResponse> {
const formData = this.buildFormData(fileBuffer, contentType);
const url = `${this.baseUrl}/extract/vin`;
logger.info('OCR VIN extract request', {
operation: 'ocr.client.extractVin',
url,
contentType,
fileSize: fileBuffer.length,
});
const response = await this.fetchWithTimeout(url, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const errorText = await response.text();
logger.error('OCR VIN extract failed', {
operation: 'ocr.client.extractVin.error',
status: response.status,
error: errorText,
});
throw new Error(`OCR service error: ${response.status} - ${errorText}`);
}
const result = (await response.json()) as VinExtractionResponse;
logger.info('OCR VIN extract completed', {
operation: 'ocr.client.extractVin.success',
success: result.success,
vin: result.vin,
confidence: result.confidence,
processingTimeMs: result.processingTimeMs,
});
return result;
}
/**
* Submit an async OCR job for large files.
*
@@ -90,11 +132,7 @@ export class OcrClient {
contentType: string,
callbackUrl?: string
): Promise<JobResponse> {
const formData = new FormData();
formData.append('file', fileBuffer, {
filename: this.getFilenameFromContentType(contentType),
contentType,
});
const formData = this.buildFormData(fileBuffer, contentType);
if (callbackUrl) {
formData.append('callback_url', callbackUrl);
}
@@ -111,8 +149,7 @@ export class OcrClient {
const response = await this.fetchWithTimeout(url, {
method: 'POST',
body: formData as any,
headers: formData.getHeaders(),
body: formData,
});
if (!response.ok) {
@@ -205,6 +242,14 @@ export class OcrClient {
}
}
private buildFormData(fileBuffer: Buffer, contentType: string): FormData {
const filename = this.getFilenameFromContentType(contentType);
const blob = new Blob([fileBuffer], { type: contentType });
const formData = new FormData();
formData.append('file', blob, filename);
return formData;
}
private getFilenameFromContentType(contentType: string): string {
const extensions: Record<string, string> = {
'image/jpeg': 'image.jpg',