feat(api,shared): métadonnées multi-providers et automatisation des scans/enrichissements

Chaîne de résolution metadata (local, Open Library, Google Books, BNF)
avec activation/priorité/clé API par provider, colonnes isbn13 et
identifiers sur les livres, et intégration au scanner pour compléter
métadonnées et jaquettes manquantes. Module automation: réglages
persistés, planifications scan/enrichissement et déclenchement manuel,
exposés via des endpoints admin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Git Agent
2026-08-23 13:10:45 +02:00
parent 1ac4144d0e
commit 48e9459cf3
23 changed files with 1029 additions and 24 deletions

View File

@ -91,6 +91,7 @@ export const BookSchema = z.object({
author: z.string().nullable(),
description: z.string().nullable(),
isbn: z.string().nullable(),
isbn13: z.string().nullable(),
language: z.string().nullable(),
publisher: z.string().nullable(),
publishedDate: z.string().nullable(),
@ -137,3 +138,55 @@ export const JobSchema = z.object({
updatedAt: z.string()
});
export type JobDto = z.infer<typeof JobSchema>;
export const MetadataProviderIdSchema = z.enum(["local", "openlibrary", "googlebooks", "bnf"]);
export type MetadataProviderId = z.infer<typeof MetadataProviderIdSchema>;
export const MetadataSourceConfigSchema = z.object({
provider: MetadataProviderIdSchema,
enabled: z.boolean(),
priority: z.number().int().min(0),
hasApiKey: z.boolean().default(false)
});
export type MetadataSourceConfigDto = z.infer<typeof MetadataSourceConfigSchema>;
export const MetadataSourcesConfigSchema = z.object({
isbnPriorityEnabled: z.boolean(),
sources: z.array(MetadataSourceConfigSchema)
});
export type MetadataSourcesConfigDto = z.infer<typeof MetadataSourcesConfigSchema>;
export const UpdateMetadataSourceConfigSchema = z.object({
provider: MetadataProviderIdSchema.exclude(["local"]),
enabled: z.boolean(),
priority: z.number().int().min(1).max(100),
apiKey: z.string().min(1).nullable().optional()
});
export type UpdateMetadataSourceConfigDto = z.infer<typeof UpdateMetadataSourceConfigSchema>;
export const UpdateMetadataSourcesConfigSchema = z.object({
isbnPriorityEnabled: z.boolean().optional(),
sources: z.array(UpdateMetadataSourceConfigSchema).optional()
});
export type UpdateMetadataSourcesConfigDto = z.infer<typeof UpdateMetadataSourcesConfigSchema>;
export const AutomationFrequencySchema = z.enum(["disabled", "daily", "weekly"]);
export type AutomationFrequency = z.infer<typeof AutomationFrequencySchema>;
export const AutomationScheduleSchema = z.object({
frequency: AutomationFrequencySchema,
time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/).default("03:00"),
dayOfWeek: z.number().int().min(0).max(6).default(1)
});
export type AutomationScheduleDto = z.infer<typeof AutomationScheduleSchema>;
export const AutomationSettingsSchema = z.object({
watchLibraries: z.boolean(),
autoEnrichNewBooks: z.boolean(),
scanSchedule: AutomationScheduleSchema,
enrichSchedule: AutomationScheduleSchema
});
export type AutomationSettingsDto = z.infer<typeof AutomationSettingsSchema>;
export const UpdateAutomationSettingsSchema = AutomationSettingsSchema.partial();
export type UpdateAutomationSettingsDto = z.infer<typeof UpdateAutomationSettingsSchema>;