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:
63
server/db.ts
63
server/db.ts
@@ -29,7 +29,10 @@ import {
|
||||
AccountingAllocation,
|
||||
automationRules,
|
||||
InsertAutomationRule,
|
||||
AutomationRule
|
||||
AutomationRule,
|
||||
llmFieldsConfig,
|
||||
InsertLlmFieldConfig,
|
||||
LlmFieldConfig
|
||||
} from "../drizzle/schema";
|
||||
import { ENV } from './_core/env';
|
||||
|
||||
@@ -606,3 +609,61 @@ export async function initializeDefaultLists(userId: number): Promise<void> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============= LLM FIELDS CONFIG OPERATIONS =============
|
||||
|
||||
export async function getLlmFieldsConfigByUser(userId: number): Promise<LlmFieldConfig[]> {
|
||||
const db = await getDb();
|
||||
if (!db) return [];
|
||||
return db.select().from(llmFieldsConfig).where(eq(llmFieldsConfig.userId, userId)).orderBy(llmFieldsConfig.displayOrder);
|
||||
}
|
||||
|
||||
export async function upsertLlmFieldConfig(data: InsertLlmFieldConfig): Promise<LlmFieldConfig> {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Database not available");
|
||||
|
||||
const existing = await db.select().from(llmFieldsConfig)
|
||||
.where(and(
|
||||
eq(llmFieldsConfig.userId, data.userId),
|
||||
eq(llmFieldsConfig.fieldName, data.fieldName)
|
||||
))
|
||||
.limit(1);
|
||||
|
||||
if (existing.length > 0) {
|
||||
await db.update(llmFieldsConfig)
|
||||
.set({ ...data, updatedAt: new Date() })
|
||||
.where(eq(llmFieldsConfig.id, existing[0].id));
|
||||
return (await db.select().from(llmFieldsConfig).where(eq(llmFieldsConfig.id, existing[0].id)))[0];
|
||||
} else {
|
||||
const result = await db.insert(llmFieldsConfig).values(data);
|
||||
const insertedId = (result as any).insertId;
|
||||
return (await db.select().from(llmFieldsConfig).where(eq(llmFieldsConfig.id, Number(insertedId))))[0];
|
||||
}
|
||||
}
|
||||
|
||||
export async function initializeDefaultLlmFields(userId: number): Promise<void> {
|
||||
const db = await getDb();
|
||||
if (!db) return;
|
||||
|
||||
const defaultFields = [
|
||||
{ fieldName: "supplierName", displayName: "Nom du fournisseur", isRequired: 1, displayOrder: 1 },
|
||||
{ fieldName: "invoiceNumber", displayName: "Numéro de facture", isRequired: 1, displayOrder: 2 },
|
||||
{ fieldName: "invoiceDate", displayName: "Date de facture", isRequired: 1, displayOrder: 3 },
|
||||
{ fieldName: "totalAmount", displayName: "Montant total TTC", isRequired: 1, displayOrder: 4 },
|
||||
{ fieldName: "deliveryNoteNumber", displayName: "Numéro de bon de livraison", isRequired: 0, displayOrder: 5 },
|
||||
{ fieldName: "orderNumber", displayName: "Numéro de commande", isRequired: 0, displayOrder: 6 },
|
||||
];
|
||||
|
||||
const existingFields = await db.select().from(llmFieldsConfig).where(eq(llmFieldsConfig.userId, userId));
|
||||
const existingFieldNames = new Set(existingFields.map(f => f.fieldName));
|
||||
|
||||
for (const field of defaultFields) {
|
||||
if (!existingFieldNames.has(field.fieldName)) {
|
||||
try {
|
||||
await db.insert(llmFieldsConfig).values({ userId, ...field });
|
||||
} catch (error) {
|
||||
// Ignore errors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user