All files / src/platform/ocr ocr.service.ts

0% Statements 0/36
0% Branches 0/18
0% Functions 0/5
0% Lines 0/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83                                                                                                                                                                     
import { Injectable, Logger } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { OcrJob } from './schemas/ocr.schema';
import { StorageHubService } from '../storage/storage-hub.service';
import { AiGatewayService } from '../ai/services/ai-gateway.service';
 
@Injectable()
export class OcrService {
  private readonly logger = new Logger(OcrService.name);
 
  constructor(
    @InjectModel(OcrJob.name) private ocrJobModel: Model<OcrJob>,
    private readonly storageService: StorageHubService,
    private readonly aiGateway: AiGatewayService,
  ) {}
 
  async processDocument(
    tenantId: string,
    storageKey: string,
    documentType: string,
    performedBy?: string,
  ): Promise<OcrJob> {
    const job = await this.ocrJobModel.create({
      tenantId,
      storageKey,
      documentType,
      status: 'pending',
      performedBy,
    });
 
    this.executeOcr(job).catch((err) => {
      this.logger.error(`OCR processing failed: ${err.message}`);
    });
 
    return job;
  }
 
  private async executeOcr(job: any) {
    job.status = 'processing';
    await job.save();
 
    try {
      // 1. Fetch file from storage
      const fileBuffer = await this.storageService.downloadFile(
        job.tenantId,
        job.storageKey,
      );
 
      // 2. Use AI Gateway for Vision/OCR processing
      const prompt = `Extract data from this ${job.documentType} image. Return JSON with the key fields.`;
      const aiResponse = await this.aiGateway.executeVisionTask({
        tenantId: job.tenantId,
        imageBuffer: fileBuffer,
        prompt,
      });
 
      // 3. Store results
      job.rawText = aiResponse.rawContent || '';
      try {
        job.extractedData = JSON.parse(aiResponse.content);
      } catch {
        job.extractedData = { text: aiResponse.content };
      }
      job.confidenceScore = aiResponse.confidence || 0.9;
      job.status = 'completed';
    } catch (error: any) {
      job.status = 'failed';
      job.errorMessage = error.message;
    } finally {
      await job.save();
    }
  }
 
  async getJobStatus(tenantId: string, jobId: string): Promise<OcrJob> {
    const job = await this.ocrJobModel.findOne({ _id: jobId, tenantId }).exec();
    if (!job) {
      throw new Error('OCR job not found');
    }
    return job;
  }
}