chore: prettier everywhere
This commit is contained in:
@@ -18,7 +18,7 @@ export interface DeadlineTask {
|
||||
export interface DeadlineMetrics {
|
||||
overdue: DeadlineTask[];
|
||||
critical: DeadlineTask[]; // 0-2 jours
|
||||
warning: DeadlineTask[]; // 3-7 jours
|
||||
warning: DeadlineTask[]; // 3-7 jours
|
||||
upcoming: DeadlineTask[]; // 8-14 jours
|
||||
summary: {
|
||||
overdueCount: number;
|
||||
@@ -33,7 +33,9 @@ export class DeadlineAnalyticsService {
|
||||
/**
|
||||
* Analyse les tâches selon leurs échéances
|
||||
*/
|
||||
static async getDeadlineMetrics(sources?: string[]): Promise<DeadlineMetrics> {
|
||||
static async getDeadlineMetrics(
|
||||
sources?: string[]
|
||||
): Promise<DeadlineMetrics> {
|
||||
try {
|
||||
const now = getToday();
|
||||
|
||||
@@ -41,29 +43,31 @@ export class DeadlineAnalyticsService {
|
||||
const dbTasks = await prisma.task.findMany({
|
||||
where: {
|
||||
dueDate: {
|
||||
not: null
|
||||
not: null,
|
||||
},
|
||||
status: {
|
||||
notIn: ['done', 'cancelled', 'archived']
|
||||
}
|
||||
notIn: ['done', 'cancelled', 'archived'],
|
||||
},
|
||||
},
|
||||
include: {
|
||||
taskTags: {
|
||||
include: {
|
||||
tag: true
|
||||
}
|
||||
}
|
||||
tag: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
dueDate: 'asc'
|
||||
}
|
||||
dueDate: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
// Convertir et analyser les tâches
|
||||
let deadlineTasks: DeadlineTask[] = dbTasks.map(task => {
|
||||
let deadlineTasks: DeadlineTask[] = dbTasks.map((task) => {
|
||||
const dueDate = task.dueDate!;
|
||||
const daysRemaining = Math.ceil((dueDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
||||
|
||||
const daysRemaining = Math.ceil(
|
||||
(dueDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)
|
||||
);
|
||||
|
||||
let urgencyLevel: DeadlineTask['urgencyLevel'];
|
||||
if (daysRemaining < 0) {
|
||||
urgencyLevel = 'overdue';
|
||||
@@ -84,25 +88,31 @@ export class DeadlineAnalyticsService {
|
||||
daysRemaining,
|
||||
urgencyLevel,
|
||||
source: task.source,
|
||||
tags: task.taskTags.map(tt => tt.tag.name),
|
||||
jiraKey: task.jiraKey || undefined
|
||||
tags: task.taskTags.map((tt) => tt.tag.name),
|
||||
jiraKey: task.jiraKey || undefined,
|
||||
};
|
||||
});
|
||||
|
||||
// Filtrer par sources si spécifié
|
||||
if (sources && sources.length > 0) {
|
||||
deadlineTasks = deadlineTasks.filter(task => sources.includes(task.source));
|
||||
deadlineTasks = deadlineTasks.filter((task) =>
|
||||
sources.includes(task.source)
|
||||
);
|
||||
}
|
||||
|
||||
// Filtrer les tâches dans les 2 prochaines semaines
|
||||
const relevantTasks = deadlineTasks.filter(task =>
|
||||
task.daysRemaining <= 14 || task.urgencyLevel === 'overdue'
|
||||
const relevantTasks = deadlineTasks.filter(
|
||||
(task) => task.daysRemaining <= 14 || task.urgencyLevel === 'overdue'
|
||||
);
|
||||
|
||||
const overdue = relevantTasks.filter(t => t.urgencyLevel === 'overdue');
|
||||
const critical = relevantTasks.filter(t => t.urgencyLevel === 'critical');
|
||||
const warning = relevantTasks.filter(t => t.urgencyLevel === 'warning');
|
||||
const upcoming = relevantTasks.filter(t => t.urgencyLevel === 'normal' && t.daysRemaining <= 14);
|
||||
const overdue = relevantTasks.filter((t) => t.urgencyLevel === 'overdue');
|
||||
const critical = relevantTasks.filter(
|
||||
(t) => t.urgencyLevel === 'critical'
|
||||
);
|
||||
const warning = relevantTasks.filter((t) => t.urgencyLevel === 'warning');
|
||||
const upcoming = relevantTasks.filter(
|
||||
(t) => t.urgencyLevel === 'normal' && t.daysRemaining <= 14
|
||||
);
|
||||
|
||||
return {
|
||||
overdue,
|
||||
@@ -114,24 +124,23 @@ export class DeadlineAnalyticsService {
|
||||
criticalCount: critical.length,
|
||||
warningCount: warning.length,
|
||||
upcomingCount: upcoming.length,
|
||||
totalWithDeadlines: deadlineTasks.length
|
||||
}
|
||||
totalWithDeadlines: deadlineTasks.length,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de l\'analyse des échéances:', error);
|
||||
throw new Error('Impossible d\'analyser les échéances');
|
||||
console.error("Erreur lors de l'analyse des échéances:", error);
|
||||
throw new Error("Impossible d'analyser les échéances");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne les tâches les plus critiques (en retard + échéance dans 48h)
|
||||
*/
|
||||
static async getCriticalDeadlines(sources?: string[]): Promise<DeadlineTask[]> {
|
||||
static async getCriticalDeadlines(
|
||||
sources?: string[]
|
||||
): Promise<DeadlineTask[]> {
|
||||
const metrics = await this.getDeadlineMetrics(sources);
|
||||
return [
|
||||
...metrics.overdue,
|
||||
...metrics.critical
|
||||
].slice(0, 10); // Limite à 10 tâches les plus critiques
|
||||
return [...metrics.overdue, ...metrics.critical].slice(0, 10); // Limite à 10 tâches les plus critiques
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,8 +153,8 @@ export class DeadlineAnalyticsService {
|
||||
criticalCount: number;
|
||||
}> {
|
||||
const priorityGroups = new Map<string, DeadlineTask[]>();
|
||||
|
||||
tasks.forEach(task => {
|
||||
|
||||
tasks.forEach((task) => {
|
||||
const priority = task.priority || 'medium';
|
||||
if (!priorityGroups.has(priority)) {
|
||||
priorityGroups.set(priority, []);
|
||||
@@ -153,20 +162,30 @@ export class DeadlineAnalyticsService {
|
||||
priorityGroups.get(priority)!.push(task);
|
||||
});
|
||||
|
||||
return Array.from(priorityGroups.entries()).map(([priority, tasks]) => ({
|
||||
priority,
|
||||
count: tasks.length,
|
||||
overdueCount: tasks.filter(t => t.urgencyLevel === 'overdue').length,
|
||||
criticalCount: tasks.filter(t => t.urgencyLevel === 'critical').length
|
||||
})).sort((a, b) => {
|
||||
// Trier par impact (retard + critique) puis par priorité
|
||||
const aImpact = a.overdueCount + a.criticalCount;
|
||||
const bImpact = b.overdueCount + b.criticalCount;
|
||||
if (aImpact !== bImpact) return bImpact - aImpact;
|
||||
|
||||
const priorityOrder: Record<string, number> = { urgent: 4, high: 3, medium: 2, low: 1 };
|
||||
return (priorityOrder[b.priority] || 2) - (priorityOrder[a.priority] || 2);
|
||||
});
|
||||
return Array.from(priorityGroups.entries())
|
||||
.map(([priority, tasks]) => ({
|
||||
priority,
|
||||
count: tasks.length,
|
||||
overdueCount: tasks.filter((t) => t.urgencyLevel === 'overdue').length,
|
||||
criticalCount: tasks.filter((t) => t.urgencyLevel === 'critical')
|
||||
.length,
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
// Trier par impact (retard + critique) puis par priorité
|
||||
const aImpact = a.overdueCount + a.criticalCount;
|
||||
const bImpact = b.overdueCount + b.criticalCount;
|
||||
if (aImpact !== bImpact) return bImpact - aImpact;
|
||||
|
||||
const priorityOrder: Record<string, number> = {
|
||||
urgent: 4,
|
||||
high: 3,
|
||||
medium: 2,
|
||||
low: 1,
|
||||
};
|
||||
return (
|
||||
(priorityOrder[b.priority] || 2) - (priorityOrder[a.priority] || 2)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,14 +197,14 @@ export class DeadlineAnalyticsService {
|
||||
recommendation: string;
|
||||
} {
|
||||
const { summary } = metrics;
|
||||
|
||||
|
||||
// Calcul du score de risque basé sur les échéances
|
||||
let riskScore = 0;
|
||||
riskScore += summary.overdueCount * 25; // Retard = très grave
|
||||
riskScore += summary.criticalCount * 15; // Critique = grave
|
||||
riskScore += summary.warningCount * 5; // Avertissement = attention
|
||||
riskScore += summary.upcomingCount * 1; // À venir = surveillance
|
||||
|
||||
riskScore += summary.warningCount * 5; // Avertissement = attention
|
||||
riskScore += summary.upcomingCount * 1; // À venir = surveillance
|
||||
|
||||
// Limiter à 100
|
||||
riskScore = Math.min(riskScore, 100);
|
||||
|
||||
@@ -194,13 +213,16 @@ export class DeadlineAnalyticsService {
|
||||
|
||||
if (riskScore >= 75) {
|
||||
riskLevel = 'critical';
|
||||
recommendation = 'Action immédiate requise ! Plusieurs tâches en retard ou critiques.';
|
||||
recommendation =
|
||||
'Action immédiate requise ! Plusieurs tâches en retard ou critiques.';
|
||||
} else if (riskScore >= 50) {
|
||||
riskLevel = 'high';
|
||||
recommendation = 'Attention : échéances critiques approchent, planifier les priorités.';
|
||||
recommendation =
|
||||
'Attention : échéances critiques approchent, planifier les priorités.';
|
||||
} else if (riskScore >= 25) {
|
||||
riskLevel = 'medium';
|
||||
recommendation = 'Surveillance nécessaire, quelques échéances à surveiller.';
|
||||
recommendation =
|
||||
'Surveillance nécessaire, quelques échéances à surveiller.';
|
||||
} else {
|
||||
riskLevel = 'low';
|
||||
recommendation = 'Situation stable, échéances sous contrôle.';
|
||||
|
||||
Reference in New Issue
Block a user