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:
Julien Froidefond
2025-09-23 21:54:55 +02:00
parent 7ac961f6c7
commit 8a227aec36
3 changed files with 62 additions and 34 deletions

View File

@@ -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<{

View File

@@ -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

View File

@@ -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;