From e9d25d9270627438283be5bcc68954cb16ef2407 Mon Sep 17 00:00:00 2001 From: Manus Date: Wed, 30 Sep 2026 16:18:00 +0000 Subject: [PATCH] feat: route invoice analysis through referentiel ia --- client/src/pages/Settings.tsx | 102 +- docker-compose.yml | 3 + drizzle/0036_broken_rattler.sql | 2 +- drizzle/0041_acoustic_microchip.sql | 2 + drizzle/meta/0041_snapshot.json | 2517 ++++++++++++++++++++++ drizzle/meta/_journal.json | 7 + drizzle/schema.ts | 4 +- server/_core/env.ts | 2 + server/_core/llm.ts | 15 +- server/deploymentRouting.test.ts | 7 + server/drizzleMigrationHistory.test.ts | 14 + server/referentialIa.test.ts | 79 + server/referentialIa.ts | 128 ++ server/routers.ts | 9 +- server/webImportSourcesMigration.test.ts | 5 +- todo.md | 37 + 16 files changed, 2907 insertions(+), 26 deletions(-) create mode 100644 drizzle/0041_acoustic_microchip.sql create mode 100644 drizzle/meta/0041_snapshot.json create mode 100644 server/drizzleMigrationHistory.test.ts create mode 100644 server/referentialIa.test.ts create mode 100644 server/referentialIa.ts diff --git a/client/src/pages/Settings.tsx b/client/src/pages/Settings.tsx index 667e1c4..3332c8f 100644 --- a/client/src/pages/Settings.tsx +++ b/client/src/pages/Settings.tsx @@ -677,7 +677,7 @@ export default function Settings() { const [sftpAutoExport, setSftpAutoExport] = useState(false); const [sftpRecipientFilter, setSftpRecipientFilter] = useState(""); const [llmLogsRetentionMonths, setLlmLogsRetentionMonths] = useState(3); - const [aiProvider, setAiProvider] = useState<"mistral" | "manus" | "gemini">("mistral"); + const [aiProvider, setAiProvider] = useState<"mistral" | "manus" | "gemini" | "referentiel">("mistral"); const [mistralApiKey, setMistralApiKey] = useState(""); const [manusForgeApiKey, setManusForgeApiKey] = useState(""); const [manusForgeApiUrl, setManusForgeApiUrl] = useState(""); @@ -722,6 +722,17 @@ export default function Settings() { }, }); + const testReferentielIaMutation = trpc.settings.testReferentielIa.useMutation({ + onSuccess: (data) => { + const engine = data.engineName ? ` Moteur sélectionné : ${data.engineName}.` : ""; + const model = data.model ? ` Modèle : ${data.model}.` : ""; + toast.success(`Connexion au Référentiel IA réussie.${engine}${model}`); + }, + onError: (error) => { + toast.error(error.message || "Connexion au Référentiel IA impossible"); + }, + }); + const testSftpMutation = trpc.sftp.testConnection.useMutation({ onSuccess: (data) => { if (data.success) { @@ -857,7 +868,7 @@ export default function Settings() { {/* Provider selector */} -
+
+ +
{/* Mistral config */} @@ -1055,6 +1092,32 @@ export default function Settings() {
)} + {aiProvider === "referentiel" && ( +
+
+
+

Configuration centralisée

+

+ L’analyse est envoyée à la passerelle du Référentiel IA. Le moteur, le modèle, les droits et les limites d’usage sont ceux sélectionnés pour Démat. Facturation DSI dans le Référentiel. +

+

+ Aucune clé du Référentiel n’est affichée ni enregistrée dans ces paramètres. +

+
+ +
+
+ )} +
@@ -1073,20 +1136,27 @@ export default function Settings() { -
- - setLlmModel(e.target.value)} - placeholder="mistral-large-latest" - className="h-11" - /> -

- - Nom du modèle Mistral à utiliser pour l'extraction -

-
+ {aiProvider === "referentiel" ? ( +
+

Modèle décidé par le Référentiel IA

+

La surcharge locale est volontairement désactivée pour garantir un moteur unique, piloté et tracé au niveau Santinova.

+
+ ) : ( +
+ + setLlmModel(e.target.value)} + placeholder="mistral-large-latest" + className="h-11" + /> +

+ + Nom du modèle à utiliser pour l'extraction directe +

+
+ )}