capture.ts (2034B)
1 import { EntityLocked } from "#core/application/repository_error.ts"; 2 3 import { IDDocumentRepository } from "#core/application/id_document/id_document_repository.ts"; 4 import { 5 IDDocumentMRZScan, 6 MRZInfo, 7 } from "#core/application/id_document/mrzscan.ts"; 8 import { IDDocumentOutOfState } from "#core/domain/id_document.ts"; 9 import { Picture } from "#core/domain/picture.ts"; 10 import { InvalidUUID, UUID } from "#core/domain/uuid.ts"; 11 12 export type IDDocumentCaptureRequest = { 13 uuid: string; 14 side: "doc-front" | "doc-back" | "face-left" | "face-front" | "face-right"; 15 picture: string; 16 }; 17 18 export type IDDocumentCaptureResponse = { 19 status: "invalid" | "scanned" | "scan-failure" | "captured"; 20 } & MRZInfo; 21 22 export class IDDocumentCaptureUseCase { 23 constructor( 24 private readonly idDocumentRepo: IDDocumentRepository, 25 private readonly scanner: IDDocumentMRZScan, 26 ) { 27 } 28 29 async execute( 30 request: IDDocumentCaptureRequest, 31 ): Promise<IDDocumentCaptureResponse> { 32 let info: MRZInfo = { 33 firstName: null, 34 lastName: null, 35 birthDate: null, 36 sex: null, 37 nationality: null, 38 country: null, 39 }; 40 try { 41 const uuid = new UUID(request.uuid); 42 const picture = new Picture(request.picture); 43 const idDocument = await this.idDocumentRepo.findOrCreate(uuid); 44 45 try { 46 if (request.side === "doc-back") { 47 info = await this.scanner.scan(picture.toString()); 48 } 49 } catch { 50 return { 51 status: "scan-failure", 52 ...info, 53 }; 54 } 55 56 idDocument.capture(request.side, picture, info); 57 58 await this.idDocumentRepo.store(idDocument); 59 return { 60 status: request.side === "doc-back" ? "scanned" : "captured", 61 ...info, 62 }; 63 } catch (error) { 64 if ( 65 error instanceof InvalidUUID || 66 error instanceof IDDocumentOutOfState || 67 error instanceof EntityLocked 68 ) { 69 return { status: "invalid", ...info }; 70 } 71 throw error; 72 } 73 } 74 }