From 2786cbdca7dd838e496bfd97c70d5d377f95c379 Mon Sep 17 00:00:00 2001 From: Tiny_Murky Date: Wed, 11 Sep 2024 14:11:35 +0800 Subject: [PATCH] ocr unify input check #2337 --- package.json | 2 +- src/constants/ocr.ts | 1 + src/constants/zod_schema.ts | 9 ++++- src/lib/utils/zod_schema/ocr.ts | 29 ++++++++++++++ .../[companyId]/ocr/[resultId]/index.test.ts | 20 ---------- .../[companyId]/ocr/[resultId]/index.ts | 40 +++++++++---------- 6 files changed, 59 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 33d863b5..b8727ee4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iSunFA", - "version": "0.8.1+11", + "version": "0.8.1+12", "private": false, "scripts": { "dev": "next dev", diff --git a/src/constants/ocr.ts b/src/constants/ocr.ts index 69eae261..c91e2503 100644 --- a/src/constants/ocr.ts +++ b/src/constants/ocr.ts @@ -4,4 +4,5 @@ export const AVERAGE_OCR_PROCESSING_TIME = 30 * ONE_MINUTE_IN_MS; export enum ocrTypes { INVOICE = 'invoice', + CONTRACT = 'contract', } diff --git a/src/constants/zod_schema.ts b/src/constants/zod_schema.ts index 456776cc..d9cf3d78 100644 --- a/src/constants/zod_schema.ts +++ b/src/constants/zod_schema.ts @@ -1,5 +1,10 @@ import { APIName } from '@/constants/api_connection'; -import { ocrListValidator, ocrUploadValidator } from '@/lib/utils/zod_schema/ocr'; +import { + ocrDeleteValidator, + ocrListValidator, + ocrResultGetByIdValidator, + ocrUploadValidator, +} from '@/lib/utils/zod_schema/ocr'; import { zodExampleValidator } from '@/lib/utils/zod_schema/zod_example'; /* @@ -17,4 +22,6 @@ export const API_ZOD_SCHEMA = { [APIName.ZOD_EXAMPLE]: zodExampleValidator, [APIName.OCR_LIST]: ocrListValidator, [APIName.OCR_UPLOAD]: ocrUploadValidator, + [APIName.OCR_RESULT_GET_BY_ID]: ocrResultGetByIdValidator, + [APIName.OCR_DELETE]: ocrDeleteValidator, }; diff --git a/src/lib/utils/zod_schema/ocr.ts b/src/lib/utils/zod_schema/ocr.ts index 44048988..cec11a58 100644 --- a/src/lib/utils/zod_schema/ocr.ts +++ b/src/lib/utils/zod_schema/ocr.ts @@ -31,3 +31,32 @@ export const ocrUploadValidator: IZodValidator< query: ocrUploadQueryValidator, body: ocrUploadBodyValidator, }; + +const ocrResultGetByIdQueryValidator = z.object({ + resultId: z.string(), + ocrType: z.nativeEnum(ocrTypes).or(z.undefined()), +}); + +const ocrResultGetByIdBodyValidator = z.object({}); + +export const ocrResultGetByIdValidator: IZodValidator< + (typeof ocrResultGetByIdQueryValidator)['shape'], + (typeof ocrResultGetByIdBodyValidator)['shape'] +> = { + query: ocrResultGetByIdQueryValidator, + body: ocrResultGetByIdBodyValidator, +}; + +const ocrDeleteQueryValidator = z.object({ + resultId: z.string(), +}); + +const ocrDeleteBodyValidator = z.object({}); + +export const ocrDeleteValidator: IZodValidator< + (typeof ocrDeleteQueryValidator)['shape'], + (typeof ocrDeleteBodyValidator)['shape'] +> = { + query: ocrDeleteQueryValidator, + body: ocrDeleteBodyValidator, +}; diff --git a/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.test.ts b/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.test.ts index 43ac4355..78875d87 100644 --- a/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.test.ts +++ b/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.test.ts @@ -27,26 +27,6 @@ afterEach(() => { jest.clearAllMocks(); }); -describe('isResultIdValid', () => { - it('should return true if resultId is valid', () => { - const resultId = 'validResultId'; - const result = module.isResultIdValid(resultId); - expect(result).toBe(true); - }); - - it('should return false if resultId is undefined', () => { - const resultId = undefined; - const result = module.isResultIdValid(resultId); - expect(result).toBe(false); - }); - - it('should return false if resultId is an array', () => { - const resultId = ['validResultId']; - const result = module.isResultIdValid(resultId); - expect(result).toBe(false); - }); -}); - describe('fetchOCRResult', () => { it('should fetch OCR result with GET', async () => { const resultId = 'validResultId'; diff --git a/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.ts b/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.ts index a6d278df..7967deee 100644 --- a/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.ts +++ b/src/pages/api/v1/company/[companyId]/ocr/[resultId]/index.ts @@ -19,16 +19,12 @@ import { AuthFunctionsKeys } from '@/interfaces/auth'; import { getAichUrl } from '@/lib/utils/aich'; import { AICH_APIS_TYPES } from '@/constants/aich'; import loggerBack, { loggerError } from '@/lib/utils/logger_back'; +import { ocrTypes } from '@/constants/ocr'; +import { validateRequest } from '@/lib/utils/request_validator'; +import { APIName } from '@/constants/api_connection'; // Info: (20240522 - Murky) This OCR now can only be used on Invoice -export function isResultIdValid(resultId: string | string[] | undefined): resultId is string { - if (Array.isArray(resultId) || !resultId || typeof resultId !== 'string') { - return false; - } - return true; -} - export async function fetchOCRResult(resultId: string) { let response: Response; @@ -99,19 +95,19 @@ export function formatOCRResultDate(ocrResult: IInvoice) { return newOcrResult; } -export async function handleGetRequest(resultId: string, type: string = 'invoice') { +export async function handleGetRequest(resultId: string, ocrType: ocrTypes = ocrTypes.INVOICE) { let ocrResult: IInvoice | IContract | null = null; const isResultIdError = resultId && resultId.slice(0, 5) === 'error'; if (resultId && resultId.length >= 0 && !isResultIdError) { const fetchResult = fetchOCRResult(resultId); - switch (type) { - case 'contract': { + switch (ocrType) { + case ocrTypes.CONTRACT: { ocrResult = {} as IContract; break; } - case 'invoice': { + case ocrTypes.INVOICE: { ocrResult = await getPayloadFromResponseJSON(fetchResult); if (ocrResult) { let newOcr: IInvoice | null = setOCRResultJournalId(ocrResult, null); @@ -169,22 +165,26 @@ export default async function handler( let payload: APIReturnType = null; let status: string = STATUS_MESSAGE.BAD_REQUEST; - const { resultId, type } = req.query; if (isAuth) { try { - if (!isResultIdValid(resultId)) { - throw new Error(STATUS_MESSAGE.INVALID_INPUT_PARAMETER); - } - switch (req.method) { case 'GET': { - payload = await handleGetRequest(resultId, type as string); - status = STATUS_MESSAGE.SUCCESS; + const { query } = validateRequest(APIName.OCR_RESULT_GET_BY_ID, req, userId); + if (query) { + const { resultId, ocrType } = query; + payload = await handleGetRequest(resultId, ocrType); + status = STATUS_MESSAGE.SUCCESS; + } break; } case 'DELETE': { - payload = await handleDeleteRequest(resultId); - status = STATUS_MESSAGE.SUCCESS_DELETE; + const { query } = validateRequest(APIName.OCR_DELETE, req, userId); + + if (query) { + const { resultId } = query; + payload = await handleDeleteRequest(resultId); + status = STATUS_MESSAGE.SUCCESS_DELETE; + } break; } default: {