mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-23 23:18:10 +02:00
feat: Implement bulk AI product analysis, including prompt generation, insight processing, and a dedicated UI component.
This commit is contained in:
1 parent
f824476e0b
commit
0226585d4e
2 files changed
+22
-2
No files matched your search
@@ -19,7 +19,9 @@ Le score (0 à 100) est une mesure de performance RELATIVE au sein du rayon.
|
|||||||
4. CONCISE : 2 phrases maximum. Pas de blabla technique sur les percentiles, parle de "performance relative".
|
4. CONCISE : 2 phrases maximum. Pas de blabla technique sur les percentiles, parle de "performance relative".
|
||||||
|
|
||||||
--- FORMAT ATTENDU ---
|
--- FORMAT ATTENDU ---
|
||||||
"[Recommandation] : [Justification factuelle incluant le Score et les axes clés]"`;
|
"[Recommandation] : [Justification factuelle incluant le Score et les axes clés]"
|
||||||
|
Exemple : "[A] : Score de 85/100 porté par une marge excellente de 45% et une forte croissance volume."
|
||||||
|
Exemple : "[Z] : Score faible (12/100) en raison d'une baisse drastique du CA et d'une inactivité de 3 mois."`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static generateUserMessage(p: ProductAnalysisInput): string {
|
static generateUserMessage(p: ProductAnalysisInput): string {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import React, { useState, useRef } from "react";
|
import React, { useState, useRef } from "react";
|
||||||
import { useGridStore } from "@/features/grid/store/use-grid-store";
|
import { useGridStore } from "@/features/grid/store/use-grid-store";
|
||||||
import { useAiCopilotStore } from "@/features/ai-copilot/store/use-ai-copilot-store";
|
import { useAiCopilotStore } from "@/features/ai-copilot/store/use-ai-copilot-store";
|
||||||
|
import { ScoringEngine } from "@/features/ai-copilot/business/scoring-engine";
|
||||||
import { Sparkles, Loader2, CheckCircle2, XCircle } from "lucide-react";
|
import { Sparkles, Loader2, CheckCircle2, XCircle } from "lucide-react";
|
||||||
import { ProductRow, GammeCode } from "@/types/grid";
|
import { ProductRow, GammeCode } from "@/types/grid";
|
||||||
import { ProductAnalysisInput } from "@/features/ai-copilot/models/ai-analysis.types";
|
import { ProductAnalysisInput } from "@/features/ai-copilot/models/ai-analysis.types";
|
||||||
@@ -55,7 +56,7 @@ export function BulkAiAnalyzer() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const productPayloads: ProductAnalysisInput[] = rows.map((r) => {
|
const initialPayloads: ProductAnalysisInput[] = rows.map((r) => {
|
||||||
const sc = r.workingStores?.length || 1;
|
const sc = r.workingStores?.length || 1;
|
||||||
const weight = sc === 1 ? 2 : 1;
|
const weight = sc === 1 ? 2 : 1;
|
||||||
const rb = rayonBenchmarks.get(r.libelleNiveau2 || "Général");
|
const rb = rayonBenchmarks.get(r.libelleNiveau2 || "Général");
|
||||||
@@ -105,6 +106,23 @@ export function BulkAiAnalyzer() {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 2. Calculer le scoring algorithmique pour chaque produit
|
||||||
|
const productPayloads = initialPayloads.map(p => {
|
||||||
|
const scoringRes = ScoringEngine.analyzeRayon(p, initialPayloads);
|
||||||
|
return {
|
||||||
|
...p,
|
||||||
|
scoring: {
|
||||||
|
compositeScore: scoringRes.compositeScore,
|
||||||
|
decision: scoringRes.decision.recommendation,
|
||||||
|
labelProfil: scoringRes.decision.labelProfil,
|
||||||
|
isTop30Supplier: scoringRes.decision.isTop30Supplier,
|
||||||
|
isRecent: scoringRes.decision.isRecent,
|
||||||
|
isLastProduct: scoringRes.decision.isLastProduct,
|
||||||
|
threshold: scoringRes.decision.threshold,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
setIsAnalyzing(true);
|
setIsAnalyzing(true);
|
||||||
let completed = 0;
|
let completed = 0;
|
||||||
let errorsCount = 0;
|
let errorsCount = 0;
|
||||||
|
|||||||
Reference in new issue
Block a user