From 4e7a67df5934389be2695df6c132e31fef0791cb Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 20 Oct 2025 07:19:08 +0800 Subject: [PATCH] feat(ocr): implement PATCH endpoint for OCR provider updates Add PATCH handler for OCR provider updates with request/response schemas Implement patchProvider method in OcrService to update provider data --- packages/shared/data/api/apiSchemas.ts | 10 ++++++++-- src/main/data/api/handlers/index.ts | 4 ++-- src/main/data/db/schemas/index.ts | 3 +++ src/main/services/ocr/OcrService.ts | 23 ++++++++++++++++++++++- src/renderer/src/types/ocr.ts | 21 +++++++++++++++++++-- 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 src/main/data/db/schemas/index.ts diff --git a/packages/shared/data/api/apiSchemas.ts b/packages/shared/data/api/apiSchemas.ts index d54e73fb5a..f6d94be9cd 100644 --- a/packages/shared/data/api/apiSchemas.ts +++ b/packages/shared/data/api/apiSchemas.ts @@ -1,6 +1,11 @@ // NOTE: Types are defined inline in the schema for simplicity // If needed, specific types can be imported from './apiModels' -import type { GetOcrProviderResponse, ListOcrProvidersResponse } from '@types' +import type { + GetOcrProviderResponse, + ListOcrProvidersResponse, + PatchOcrProviderRequest, + PatchOcrProviderResponse +} from '@types' import type { BodyForPath, ConcreteApiPaths, QueryParamsForPath, ResponseForPath } from './apiPaths' import type { HttpMethod, PaginatedResponse, PaginationParams } from './apiTypes' @@ -364,7 +369,8 @@ export interface ApiSchemas { response: GetOcrProviderResponse } PATCH: { - // TODO + body: PatchOcrProviderRequest + response: PatchOcrProviderResponse } PUT: { // TODO diff --git a/src/main/data/api/handlers/index.ts b/src/main/data/api/handlers/index.ts index be046144d3..adf4dac27b 100644 --- a/src/main/data/api/handlers/index.ts +++ b/src/main/data/api/handlers/index.ts @@ -224,8 +224,8 @@ export const apiHandlers: ApiImplementation = { GET: async () => { throw new Error('Not implemented') }, - PATCH: async () => { - throw new Error('Not implemented') + PATCH: async ({ body }) => { + return ocrService.patchProvider(body) }, PUT: async () => { throw new Error('Not implemented') diff --git a/src/main/data/db/schemas/index.ts b/src/main/data/db/schemas/index.ts new file mode 100644 index 0000000000..60df6e59ad --- /dev/null +++ b/src/main/data/db/schemas/index.ts @@ -0,0 +1,3 @@ +export { appStateTable } from './appState' +export { ocrProviderTable } from './ocr/provider' +export { preferenceTable } from './preference' diff --git a/src/main/services/ocr/OcrService.ts b/src/main/services/ocr/OcrService.ts index 9f4f17c547..ad631f83d4 100644 --- a/src/main/services/ocr/OcrService.ts +++ b/src/main/services/ocr/OcrService.ts @@ -1,8 +1,16 @@ import { dbService } from '@data/db/DbService' import { ocrProviderTable } from '@data/db/schemas/ocr/provider' import { loggerService } from '@logger' -import type { ListOcrProvidersResponse, OcrParams, OcrResult, SupportedOcrFile } from '@types' +import type { + ListOcrProvidersResponse, + OcrParams, + OcrResult, + PatchOcrProviderRequest, + PatchOcrProviderResponse, + SupportedOcrFile +} from '@types' import { BuiltinOcrProviderIds } from '@types' +import { eq } from 'drizzle-orm' import type { OcrBaseService } from './builtin/OcrBaseService' import { ovOcrService } from './builtin/OvOcrService' @@ -50,6 +58,19 @@ export class OcrService { return { data: providers.filter((p) => registeredKeys.includes(p.id)) } } + public async patchProvider(update: PatchOcrProviderRequest): Promise { + const providers = await dbService + .getDb() + .select() + .from(ocrProviderTable) + .where(eq(ocrProviderTable.id, update.id)) + .limit(1) + if (providers.length == 0) { + throw new Error(`OCR provider ${update.id} not found`) + } + return { data: providers[0] } + } + public async ocr(file: SupportedOcrFile, params: OcrParams): Promise { const service = this.registry.get(params.providerId) if (!service) { diff --git a/src/renderer/src/types/ocr.ts b/src/renderer/src/types/ocr.ts index 8ee4fcc29b..6ce01dc3fb 100644 --- a/src/renderer/src/types/ocr.ts +++ b/src/renderer/src/types/ocr.ts @@ -81,9 +81,12 @@ export const OcrProviderConfigSchema = OcrProviderBaseConfigSchema.loose() export type OcrProviderConfig = z.infer +const OcrProviderIdSchema = z.string() +const OcrProviderNameSchema = z.string() + export const OcrProviderSchema = z.object({ - id: z.string(), - name: z.string(), + id: OcrProviderIdSchema, + name: OcrProviderNameSchema, capabilities: OcrProviderCapabilityRecordSchema, config: OcrProviderConfigSchema }) @@ -271,3 +274,17 @@ export const GetOcrProviderResponseSchema = z.object({ }) export type GetOcrProviderResponse = z.infer + +export const PatchOcrProviderRequestSchema = z.object({ + id: OcrProviderIdSchema, + name: OcrProviderNameSchema.optional(), + config: OcrProviderConfigSchema.partial().optional() +}) + +export type PatchOcrProviderRequest = z.infer + +export const PatchOcrProviderResponseSchema = z.object({ + data: DbOcrProviderSchema +}) + +export type PatchOcrProviderResponse = z.infer