fix: update todosCount checks and refactor key accomplishments extraction

- Changed todosCount checks in AchievementCard and ChallengeCard to ensure proper handling of undefined values.
- Updated extractKeyAccomplishments method to be asynchronous and count all related todos using Prisma, improving accuracy in task completion metrics.
- Refactored relatedItems and todosCount handling for better clarity and functionality in ManagerSummaryService.
This commit is contained in:
Julien Froidefond
2025-09-29 16:20:35 +02:00
parent d45a04d347
commit 3fcada65f6
3 changed files with 24 additions and 13 deletions

View File

@@ -76,7 +76,7 @@ export function AchievementCard({
)} )}
{/* Count de todos */} {/* Count de todos */}
{achievement.todosCount && achievement.todosCount > 0 && ( {achievement.todosCount !== undefined && achievement.todosCount > 0 && (
<div className="flex items-center gap-1 text-xs text-[var(--muted-foreground)]"> <div className="flex items-center gap-1 text-xs text-[var(--muted-foreground)]">
<span>📋</span> <span>📋</span>
<span>{achievement.todosCount} todo{achievement.todosCount > 1 ? 's' : ''}</span> <span>{achievement.todosCount} todo{achievement.todosCount > 1 ? 's' : ''}</span>

View File

@@ -79,7 +79,7 @@ export function ChallengeCard({
)} )}
{/* Count de todos */} {/* Count de todos */}
{challenge.todosCount && challenge.todosCount > 0 && ( {challenge.todosCount !== undefined && challenge.todosCount > 0 && (
<div className="flex items-center gap-1 text-xs text-[var(--muted-foreground)]"> <div className="flex items-center gap-1 text-xs text-[var(--muted-foreground)]">
<span>📋</span> <span>📋</span>
<span>{challenge.todosCount} todo{challenge.todosCount > 1 ? 's' : ''}</span> <span>{challenge.todosCount} todo{challenge.todosCount > 1 ? 's' : ''}</span>

View File

@@ -97,7 +97,7 @@ export class ManagerSummaryService {
]); ]);
// Analyser et extraire les accomplissements clés // Analyser et extraire les accomplissements clés
const keyAccomplishments = this.extractKeyAccomplishments(tasks, checkboxes); const keyAccomplishments = await this.extractKeyAccomplishments(tasks, checkboxes);
// Identifier les défis à venir // Identifier les défis à venir
const upcomingChallenges = await this.identifyUpcomingChallenges(); const upcomingChallenges = await this.identifyUpcomingChallenges();
@@ -221,11 +221,11 @@ export class ManagerSummaryService {
/** /**
* Extrait les accomplissements clés basés sur la priorité * Extrait les accomplissements clés basés sur la priorité
*/ */
private static extractKeyAccomplishments(tasks: TaskType[], checkboxes: CheckboxType[]): KeyAccomplishment[] { private static async extractKeyAccomplishments(tasks: TaskType[], checkboxes: CheckboxType[]): Promise<KeyAccomplishment[]> {
const accomplishments: KeyAccomplishment[] = []; const accomplishments: KeyAccomplishment[] = [];
// Tâches: prendre toutes les high/medium priority, et quelques low si significatives // Tâches: prendre toutes les high/medium priority, et quelques low si significatives
tasks.forEach(task => { for (const task of tasks) {
const priority = task.priority.toLowerCase(); const priority = task.priority.toLowerCase();
// Convertir priorité task en impact accomplissement // Convertir priorité task en impact accomplissement
@@ -237,13 +237,20 @@ export class ManagerSummaryService {
} else { } else {
// Pour les low priority, ne garder que si c'est vraiment significatif // Pour les low priority, ne garder que si c'est vraiment significatif
if (!this.isSignificantTask(task.title)) { if (!this.isSignificantTask(task.title)) {
return; continue;
} }
impact = 'low'; impact = 'low';
} }
// Compter les todos (checkboxes) associés à cette tâche // Compter TOUS les todos associés à cette tâche (pas seulement ceux de la période)
const relatedTodos = checkboxes.filter(cb => cb.task?.id === task.id); // car l'accomplissement c'est la tâche complétée, pas seulement les todos de la période
const allRelatedTodos = await prisma.dailyCheckbox.count({
where: {
task: {
id: task.id
}
}
});
accomplishments.push({ accomplishments.push({
id: `task-${task.id}`, id: `task-${task.id}`,
@@ -252,12 +259,13 @@ export class ManagerSummaryService {
tags: task.taskTags?.map(tt => tt.tag.name) || [], tags: task.taskTags?.map(tt => tt.tag.name) || [],
impact, impact,
completedAt: task.completedAt || getToday(), completedAt: task.completedAt || getToday(),
relatedItems: [task.id, ...relatedTodos.map(t => t.id)], relatedItems: [task.id],
todosCount: relatedTodos.length // Nombre réel de todos associés todosCount: allRelatedTodos // Nombre total de todos associés à cette tâche
});
}); });
}
// AJOUTER les todos standalone avec la nouvelle règle de priorité // AJOUTER les todos standalone avec la nouvelle règle de priorité
// Exclure les todos déjà comptés dans les tâches complétées
const standaloneTodos = checkboxes.filter(checkbox => const standaloneTodos = checkboxes.filter(checkbox =>
!checkbox.task // Todos non liés à une tâche !checkbox.task // Todos non liés à une tâche
); );
@@ -394,6 +402,9 @@ export class ManagerSummaryService {
const estimatedEffort = this.estimateEffort(task.title, task.description || undefined); const estimatedEffort = this.estimateEffort(task.title, task.description || undefined);
// Compter les todos associés à cette tâche
const relatedTodos = upcomingCheckboxes.filter(cb => cb.task?.id === task.id);
challenges.push({ challenges.push({
id: `task-${task.id}`, id: `task-${task.id}`,
title: task.title, title: task.title,
@@ -402,8 +413,8 @@ export class ManagerSummaryService {
priority, priority,
estimatedEffort, estimatedEffort,
blockers: this.identifyBlockers(task.title, task.description || undefined), blockers: this.identifyBlockers(task.title, task.description || undefined),
relatedItems: [task.id], relatedItems: [task.id, ...relatedTodos.map(t => t.id)],
todosCount: 0 // TODO: compter les todos associés à cette tâche todosCount: relatedTodos.length // Nombre réel de todos associés
}); });
}); });