Checkpoint: Ajout de la configuration des champs obligatoires pour le score LLM

Nouvelle fonctionnalité permettant de configurer quels champs sont obligatoires ou optionnels pour atteindre un score de reconnaissance de 100%.

Modifications:
- Nouvelle table llmFieldsConfig dans la base de données
- Routes tRPC pour gérer la configuration (getAll, updateField)
- Interface utilisateur dans la page Paramètres avec tableau et cases à cocher
- Modification du code d'extraction pour générer dynamiquement l'instruction de score
- Initialisation automatique des champs par défaut (supplierName, invoiceNumber, invoiceDate, totalAmount obligatoires)
- Tests unitaires pour valider la fonctionnalité

L'utilisateur peut maintenant personnaliser quels champs doivent être détectés pour qu'une facture atteigne 100% de score.
This commit is contained in:
Manus
2026-02-13 03:39:41 -05:00
parent 96f6367094
commit d32359fc10
14 changed files with 1903 additions and 30 deletions

View File

@@ -9,6 +9,70 @@ import { Switch } from "@/components/ui/switch";
import { trpc } from "@/lib/trpc";
import { Loader2, Save, CheckCircle } from "lucide-react";
import { toast } from "sonner";
import { Checkbox } from "@/components/ui/checkbox";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
function LlmFieldsConfigSection() {
const { data: fields, isLoading } = trpc.llmFieldsConfig.getAll.useQuery();
const utils = trpc.useUtils();
const updateFieldMutation = trpc.llmFieldsConfig.updateField.useMutation({
onSuccess: () => {
toast.success("Configuration mise à jour");
utils.llmFieldsConfig.getAll.invalidate();
},
onError: (error) => {
toast.error(error.message || "Erreur lors de la mise à jour");
},
});
const handleToggle = (fieldName: string, currentValue: number) => {
updateFieldMutation.mutate({
fieldName,
isRequired: currentValue === 1 ? 0 : 1,
});
};
if (isLoading) {
return (
<div className="flex items-center justify-center py-8">
<Loader2 className="w-6 h-6 animate-spin text-gray-400" />
</div>
);
}
return (
<div className="space-y-4">
<p className="text-sm text-muted-foreground">
Les champs marqués comme obligatoires doivent être détectés pour atteindre un score de 100%.
Les champs optionnels n'affectent pas le score.
</p>
<Table>
<TableHeader>
<TableRow>
<TableHead>Champ</TableHead>
<TableHead className="text-center">Obligatoire</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{fields?.map((field) => (
<TableRow key={field.id}>
<TableCell className="font-medium">{field.displayName}</TableCell>
<TableCell className="text-center">
<Checkbox
checked={field.isRequired === 1}
onCheckedChange={() => handleToggle(field.fieldName, field.isRequired)}
disabled={updateFieldMutation.isPending}
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
export default function Settings() {
const { data: settings, isLoading } = trpc.settings.get.useQuery();
@@ -145,6 +209,19 @@ export default function Settings() {
</CardContent>
</Card>
{/* LLM Fields Configuration */}
<Card>
<CardHeader>
<CardTitle>Champs de détection</CardTitle>
<CardDescription>
Configurez quels champs sont obligatoires pour atteindre un score de reconnaissance de 100%
</CardDescription>
</CardHeader>
<CardContent>
<LlmFieldsConfigSection />
</CardContent>
</Card>
{/* Keywords Configuration */}
<Card>
<CardHeader>