feat(ocr): add filtering by registration status to provider list

Add optional query parameter to filter OCR providers by registration status
Prevent modification and deletion of built-in OCR providers
This commit is contained in:
icarus 2025-10-20 07:54:50 +08:00
parent 7ea7e7134d
commit 389dfc08f6
3 changed files with 16 additions and 12 deletions

View File

@ -360,6 +360,7 @@ export interface ApiSchemas {
'/ocr/providers': { '/ocr/providers': {
GET: { GET: {
query: { registered?: boolean }
response: ListOcrProvidersResponse response: ListOcrProvidersResponse
} }
POST: { POST: {

View File

@ -212,8 +212,8 @@ export const apiHandlers: ApiImplementation = {
}, },
'/ocr/providers': { '/ocr/providers': {
GET: async () => { GET: async ({ query }) => {
return ocrService.listProviders() return ocrService.listProviders(query.registered)
}, },
POST: async ({ body }) => { POST: async ({ body }) => {
return ocrService.createProvider(body) return ocrService.createProvider(body)

View File

@ -13,7 +13,7 @@ import type {
PutOcrProviderResponse, PutOcrProviderResponse,
SupportedOcrFile SupportedOcrFile
} from '@types' } from '@types'
import { BuiltinOcrProviderIdMap } from '@types' import { BuiltinOcrProviderIdMap, BuiltinOcrProviderIds } from '@types'
import { eq } from 'drizzle-orm' import { eq } from 'drizzle-orm'
import { merge } from 'lodash' import { merge } from 'lodash'
@ -56,17 +56,17 @@ export class OcrService {
this.registry.delete(providerId) this.registry.delete(providerId)
} }
public async listProviders(): Promise<ListOcrProvidersResponse> { public async listProviders(registered?: boolean): Promise<ListOcrProvidersResponse> {
const registeredKeys = Array.from(this.registry.keys())
const providers = await dbService.getDb().select().from(ocrProviderTable) const providers = await dbService.getDb().select().from(ocrProviderTable)
if (registered) {
return { data: providers.filter((p) => registeredKeys.includes(p.id)) } const registeredKeys = Array.from(this.registry.keys())
return { data: providers.filter((p) => registeredKeys.includes(p.id)) }
} else {
return { data: providers }
}
} }
public async getProvider(providerId: string) { public async getProvider(providerId: string) {
if (!this.registry.has(providerId)) {
throw new Error(`OCR provider ${providerId} is not registered`)
}
const providers = await dbService const providers = await dbService
.getDb() .getDb()
.select() .select()
@ -121,6 +121,9 @@ export class OcrService {
} }
public async putProvider(update: PutOcrProviderRequest): Promise<PutOcrProviderResponse> { public async putProvider(update: PutOcrProviderRequest): Promise<PutOcrProviderResponse> {
if (BuiltinOcrProviderIds.some((pid) => pid === update.id)) {
throw new Error('Builtin OCR providers cannot be modified with PUT method.')
}
const providers = await dbService const providers = await dbService
.getDb() .getDb()
.select() .select()
@ -144,8 +147,8 @@ export class OcrService {
} }
public async deleteProvider(providerId: string): Promise<void> { public async deleteProvider(providerId: string): Promise<void> {
if (!this.registry.has(providerId)) { if (BuiltinOcrProviderIds.some((pid) => pid === providerId)) {
throw new Error(`OCR provider ${providerId} is not registered`) throw new Error('Builtin OCR providers cannot be deleted.')
} }
const providers = await dbService const providers = await dbService
.getDb() .getDb()