new
This commit is contained in:
@@ -46,24 +46,20 @@ export function UsageAnalytics() {
|
||||
|
||||
setLoading(true);
|
||||
|
||||
// Console log pour débugger les données balances
|
||||
console.log("=== DONNÉES BALANCES RÉCUPÉRÉES ===");
|
||||
console.log("Nombre total d'entrées balances:", balances.length);
|
||||
console.log("Toutes les entrées balances:", balances);
|
||||
|
||||
// NOUVEAU : Console log pour débugger les utilisateurs
|
||||
console.log("=== DONNÉES UTILISATEURS ===");
|
||||
console.log("Nombre total d'utilisateurs:", users.length);
|
||||
console.log("Premiers 5 utilisateurs:", users.slice(0, 5));
|
||||
|
||||
// Analyser les doublons
|
||||
console.log("=== CALCUL DES STATISTIQUES ===");
|
||||
console.log("Utilisateurs:", users.length);
|
||||
console.log("Conversations:", conversations.length);
|
||||
console.log("Transactions:", transactions.length);
|
||||
console.log("Balances:", balances.length);
|
||||
|
||||
// Analyser les doublons dans les balances
|
||||
const userCounts = new Map<string, number>();
|
||||
balances.forEach(balance => {
|
||||
balances.forEach((balance) => {
|
||||
const userId = balance.user;
|
||||
userCounts.set(userId, (userCounts.get(userId) || 0) + 1);
|
||||
});
|
||||
|
||||
const duplicateUsers = Array.from(userCounts.entries()).filter(([_, count]) => count > 1);
|
||||
|
||||
const duplicateUsers = Array.from(userCounts.entries()).filter(([, count]) => count > 1);
|
||||
console.log("Utilisateurs avec plusieurs entrées:", duplicateUsers);
|
||||
|
||||
// Afficher quelques exemples d'entrées
|
||||
@@ -73,6 +69,29 @@ export function UsageAnalytics() {
|
||||
const totalBrut = balances.reduce((sum, balance) => sum + (balance.tokenCredits || 0), 0);
|
||||
console.log("Total brut (avec doublons potentiels):", totalBrut);
|
||||
|
||||
// Ajouter des logs détaillés pour comprendre le problème
|
||||
console.log("=== DIAGNOSTIC DÉTAILLÉ ===");
|
||||
|
||||
// Analyser les doublons
|
||||
const duplicateDetails = Array.from(userCounts.entries())
|
||||
.filter(([, count]) => count > 1)
|
||||
.map(([userId, count]) => {
|
||||
const userBalances = balances.filter(b => b.user === userId);
|
||||
const totalCredits = userBalances.reduce((sum, b) => sum + (b.tokenCredits || 0), 0);
|
||||
return {
|
||||
userId,
|
||||
count,
|
||||
totalCredits,
|
||||
balances: userBalances.map(b => ({
|
||||
credits: b.tokenCredits,
|
||||
createdAt: b.createdAt,
|
||||
updatedAt: b.updatedAt
|
||||
}))
|
||||
};
|
||||
});
|
||||
|
||||
console.log("Détails des doublons:", duplicateDetails);
|
||||
|
||||
// NOUVEAU : Identifier les utilisateurs fantômes
|
||||
console.log("=== ANALYSE DES UTILISATEURS FANTÔMES ===");
|
||||
const userIds = new Set(users.map(user => user._id));
|
||||
@@ -90,41 +109,58 @@ export function UsageAnalytics() {
|
||||
|
||||
console.log("Crédits des utilisateurs fantômes:", phantomCredits);
|
||||
console.log("Crédits des vrais utilisateurs:", totalBrut - phantomCredits);
|
||||
|
||||
// Analyser les utilisateurs fantômes
|
||||
const phantomDetails = uniquePhantomUsers.map(userId => {
|
||||
const userBalances = balances.filter(b => b.user === userId);
|
||||
const totalCredits = userBalances.reduce((sum, b) => sum + (b.tokenCredits || 0), 0);
|
||||
return { userId, totalCredits, count: userBalances.length };
|
||||
});
|
||||
|
||||
console.log("Détails des utilisateurs fantômes:", phantomDetails);
|
||||
|
||||
// Calculer les utilisateurs actifs (5 dernières minutes)
|
||||
const fiveMinutesAgo = new Date();
|
||||
fiveMinutesAgo.setMinutes(fiveMinutesAgo.getMinutes() - 5);
|
||||
// Calculer les utilisateurs actifs (30 derniers jours)
|
||||
const thirtyDaysAgo = new Date();
|
||||
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
||||
const activeUsers = users.filter((user) => {
|
||||
const lastActivity = new Date(user.updatedAt || user.createdAt);
|
||||
return lastActivity >= fiveMinutesAgo;
|
||||
return lastActivity >= thirtyDaysAgo;
|
||||
}).length;
|
||||
|
||||
// CORRECTION : Créer une map des crédits par utilisateur en évitant les doublons
|
||||
// CORRECTION AMÉLIORÉE : Créer une map des crédits par utilisateur
|
||||
const creditsMap = new Map<string, number>();
|
||||
|
||||
// Grouper les balances par utilisateur
|
||||
const balancesByUser = new Map<string, LibreChatBalance[]>();
|
||||
balances.forEach((balance) => {
|
||||
const userId = balance.user;
|
||||
if (!balancesByUser.has(userId)) {
|
||||
balancesByUser.set(userId, []);
|
||||
// Ignorer les utilisateurs fantômes (qui n'existent plus)
|
||||
if (users.some(user => user._id === userId)) {
|
||||
if (!balancesByUser.has(userId)) {
|
||||
balancesByUser.set(userId, []);
|
||||
}
|
||||
balancesByUser.get(userId)!.push(balance);
|
||||
}
|
||||
balancesByUser.get(userId)!.push(balance);
|
||||
});
|
||||
|
||||
// Pour chaque utilisateur, prendre seulement la dernière entrée
|
||||
// Pour chaque utilisateur, calculer les crédits selon votre logique métier
|
||||
balancesByUser.forEach((userBalances, userId) => {
|
||||
if (userBalances.length > 0) {
|
||||
// Trier par date de mise à jour (plus récent en premier)
|
||||
// OPTION A: Prendre la balance la plus récente
|
||||
const sortedBalances = userBalances.sort((a, b) => {
|
||||
const aDate = new Date((a.updatedAt as string) || (a.createdAt as string) || 0);
|
||||
const bDate = new Date((b.updatedAt as string) || (b.createdAt as string) || 0);
|
||||
return bDate.getTime() - aDate.getTime();
|
||||
});
|
||||
creditsMap.set(userId, sortedBalances[0].tokenCredits || 0);
|
||||
|
||||
// Prendre la plus récente
|
||||
const latestBalance = sortedBalances[0];
|
||||
creditsMap.set(userId, latestBalance.tokenCredits || 0);
|
||||
// OPTION B: Sommer toutes les balances (si c'est votre logique)
|
||||
// const totalCredits = userBalances.reduce((sum, balance) => sum + (balance.tokenCredits || 0), 0);
|
||||
// creditsMap.set(userId, totalCredits);
|
||||
|
||||
// OPTION C: Prendre la balance avec le plus de crédits
|
||||
// const maxCredits = Math.max(...userBalances.map(b => b.tokenCredits || 0));
|
||||
// creditsMap.set(userId, maxCredits);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -167,12 +203,16 @@ export function UsageAnalytics() {
|
||||
}
|
||||
});
|
||||
|
||||
// CORRECTION : Calculer le total des crédits depuis la map corrigée
|
||||
// Calculer le total des crédits depuis la map corrigée (sans doublons ni fantômes)
|
||||
const totalCreditsUsed = Array.from(creditsMap.values()).reduce(
|
||||
(sum, credits) => sum + credits,
|
||||
0
|
||||
);
|
||||
|
||||
console.log("=== RÉSULTATS CORRIGÉS ===");
|
||||
console.log("Crédits totaux (sans doublons ni fantômes):", totalCreditsUsed);
|
||||
console.log("Utilisateurs avec crédits:", creditsMap.size);
|
||||
|
||||
// Tous les utilisateurs triés par tokens puis conversations
|
||||
const allUsers = Array.from(userStats.entries())
|
||||
.map(([userId, stats]) => ({
|
||||
@@ -242,7 +282,7 @@ export function UsageAnalytics() {
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{stats.totalUsers}</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{stats.activeUsers} actifs cette semaine
|
||||
{stats.activeUsers} actifs ce mois
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user