feat: update analytics services for improved task handling
- Removed unused `parseDate` import from `analytics.ts`. - Refactored `ManagerSummaryService` to handle standalone todos with a new priority rule, ensuring todos without tasks default to low priority. - Updated logic in `MetricsService` to calculate total tasks by including in-progress tasks, enhancing completion rate accuracy. - Adjusted comments for clarity on new functionality and priority determination.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Task, TaskStatus, TaskPriority, TaskSource } from '@/lib/types';
|
||||
import { prisma } from '@/services/core/database';
|
||||
import { getToday, parseDate, subtractDays } from '@/lib/date-utils';
|
||||
import { getToday, subtractDays } from '@/lib/date-utils';
|
||||
|
||||
export interface ProductivityMetrics {
|
||||
completionTrend: Array<{
|
||||
|
||||
@@ -257,20 +257,24 @@ export class ManagerSummaryService {
|
||||
});
|
||||
});
|
||||
|
||||
// AJOUTER SEULEMENT les meetings importants standalone (non liés à une tâche)
|
||||
const standaloneMeetings = checkboxes.filter(checkbox =>
|
||||
checkbox.type === 'meeting' && !checkbox.task // Meetings non liés à une tâche
|
||||
// AJOUTER les todos standalone avec la nouvelle règle de priorité
|
||||
const standaloneTodos = checkboxes.filter(checkbox =>
|
||||
!checkbox.task // Todos non liés à une tâche
|
||||
);
|
||||
|
||||
standaloneMeetings.forEach(meeting => {
|
||||
standaloneTodos.forEach(todo => {
|
||||
// Appliquer la nouvelle règle de priorité :
|
||||
// Si pas de tâche associée, priorité faible (même pour les meetings)
|
||||
const impact: 'high' | 'medium' | 'low' = 'low';
|
||||
|
||||
accomplishments.push({
|
||||
id: `meeting-${meeting.id}`,
|
||||
title: `📅 ${meeting.text}`,
|
||||
tags: [], // Meetings n'ont pas de tags par défaut
|
||||
impact: 'medium', // Meetings sont importants
|
||||
completedAt: meeting.date,
|
||||
relatedItems: [meeting.id],
|
||||
todosCount: 1 // Un meeting = 1 todo
|
||||
id: `todo-${todo.id}`,
|
||||
title: todo.type === 'meeting' ? `📅 ${todo.text}` : todo.text,
|
||||
tags: [], // Todos standalone n'ont pas de tags par défaut
|
||||
impact,
|
||||
completedAt: todo.date,
|
||||
relatedItems: [todo.id],
|
||||
todosCount: 1 // Un todo = 1 todo
|
||||
});
|
||||
});
|
||||
|
||||
@@ -403,20 +407,39 @@ export class ManagerSummaryService {
|
||||
});
|
||||
});
|
||||
|
||||
// Ajouter les meetings importants comme challenges
|
||||
// Ajouter les todos importants comme challenges
|
||||
upcomingCheckboxes.forEach(checkbox => {
|
||||
if (checkbox.type === 'meeting') {
|
||||
challenges.push({
|
||||
id: `checkbox-${checkbox.id}`,
|
||||
title: checkbox.text,
|
||||
tags: checkbox.task?.taskTags?.map(tt => tt.tag.name) || [],
|
||||
priority: 'medium', // Meetings sont medium par défaut
|
||||
estimatedEffort: 'hours',
|
||||
blockers: [],
|
||||
relatedItems: [checkbox.id],
|
||||
todosCount: 1 // Une checkbox = 1 todo
|
||||
});
|
||||
// Déterminer la priorité selon la nouvelle règle :
|
||||
// Si le todo est associé à une tâche, prendre la priorité de la tâche
|
||||
// Sinon, priorité faible par défaut (même pour les meetings)
|
||||
let priority: 'high' | 'medium' | 'low';
|
||||
|
||||
if (checkbox.task?.priority) {
|
||||
const taskPriority = checkbox.task.priority.toLowerCase();
|
||||
if (taskPriority === 'high') {
|
||||
priority = 'high';
|
||||
} else if (taskPriority === 'medium') {
|
||||
priority = 'medium';
|
||||
} else {
|
||||
priority = 'low';
|
||||
}
|
||||
} else {
|
||||
// Pas de tâche associée = priorité faible (même pour les meetings)
|
||||
priority = 'low';
|
||||
}
|
||||
|
||||
// Inclure tous les todos (toutes priorités, y compris faible, sont maintenant visibles)
|
||||
// La priorité est déterminée par la nouvelle règle et affichée visuellement
|
||||
challenges.push({
|
||||
id: `checkbox-${checkbox.id}`,
|
||||
title: checkbox.text,
|
||||
tags: checkbox.task?.taskTags?.map(tt => tt.tag.name) || [],
|
||||
priority,
|
||||
estimatedEffort: 'hours',
|
||||
blockers: [],
|
||||
relatedItems: [checkbox.id],
|
||||
todosCount: 1 // Une checkbox = 1 todo
|
||||
});
|
||||
});
|
||||
|
||||
return challenges
|
||||
|
||||
@@ -282,7 +282,8 @@ export class MetricsService {
|
||||
|
||||
const priorityData = await Promise.all(
|
||||
priorities.map(async (priority) => {
|
||||
const [completed, total] = await Promise.all([
|
||||
const [completed] = await Promise.all([
|
||||
// Tâches complétées dans la période
|
||||
prisma.task.count({
|
||||
where: {
|
||||
priority,
|
||||
@@ -291,18 +292,22 @@ export class MetricsService {
|
||||
lte: end
|
||||
}
|
||||
}
|
||||
}),
|
||||
prisma.task.count({
|
||||
where: {
|
||||
priority,
|
||||
createdAt: {
|
||||
gte: start,
|
||||
lte: end
|
||||
}
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
||||
// Calculer les tâches en cours de cette priorité
|
||||
const inProgress = await prisma.task.count({
|
||||
where: {
|
||||
priority,
|
||||
status: {
|
||||
notIn: ['done', 'cancelled', 'archived']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Le total pour le calcul de completion = complétées + en cours
|
||||
const total = completed + inProgress;
|
||||
|
||||
const pending = total - completed;
|
||||
const completionRate = total > 0 ? (completed / total) * 100 : 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user