feat(Task): implement user ownership for tasks and enhance related services
- Added ownerId field to Task model to associate tasks with users. - Updated TaskService methods to enforce user ownership in task operations. - Enhanced API routes to include user authentication and ownership checks. - Modified DailyService and analytics services to filter tasks by user. - Integrated user session handling in various components for personalized task management.
This commit is contained in:
@@ -44,6 +44,7 @@ export class AnalyticsService {
|
||||
* Calcule les métriques de productivité pour une période donnée
|
||||
*/
|
||||
static async getProductivityMetrics(
|
||||
userId: string,
|
||||
timeRange?: TimeRange,
|
||||
sources?: string[]
|
||||
): Promise<ProductivityMetrics> {
|
||||
@@ -56,6 +57,9 @@ export class AnalyticsService {
|
||||
|
||||
// Récupérer toutes les tâches depuis la base de données avec leurs tags
|
||||
const dbTasks = await prisma.task.findMany({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
},
|
||||
include: {
|
||||
taskTags: {
|
||||
include: {
|
||||
@@ -83,6 +87,7 @@ export class AnalyticsService {
|
||||
jiraKey: task.jiraKey || undefined,
|
||||
jiraType: task.jiraType || undefined,
|
||||
assignee: task.assignee || undefined,
|
||||
ownerId: task.ownerId,
|
||||
}));
|
||||
|
||||
// Filtrer par sources si spécifié
|
||||
|
||||
@@ -34,6 +34,7 @@ export class DeadlineAnalyticsService {
|
||||
* Analyse les tâches selon leurs échéances
|
||||
*/
|
||||
static async getDeadlineMetrics(
|
||||
userId: string,
|
||||
sources?: string[]
|
||||
): Promise<DeadlineMetrics> {
|
||||
try {
|
||||
@@ -42,6 +43,7 @@ export class DeadlineAnalyticsService {
|
||||
// Récupérer toutes les tâches non terminées avec échéance
|
||||
const dbTasks = await prisma.task.findMany({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
dueDate: {
|
||||
not: null,
|
||||
},
|
||||
@@ -137,9 +139,10 @@ export class DeadlineAnalyticsService {
|
||||
* Retourne les tâches les plus critiques (en retard + échéance dans 48h)
|
||||
*/
|
||||
static async getCriticalDeadlines(
|
||||
userId: string,
|
||||
sources?: string[]
|
||||
): Promise<DeadlineTask[]> {
|
||||
const metrics = await this.getDeadlineMetrics(sources);
|
||||
const metrics = await this.getDeadlineMetrics(userId, sources);
|
||||
return [...metrics.overdue, ...metrics.critical].slice(0, 10); // Limite à 10 tâches les plus critiques
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ export class ManagerSummaryService {
|
||||
* Génère un résumé orienté manager pour les 7 derniers jours
|
||||
*/
|
||||
static async getManagerSummary(
|
||||
userId: string,
|
||||
date: Date = getToday()
|
||||
): Promise<ManagerSummary> {
|
||||
// Fenêtre glissante de 7 jours au lieu de semaine calendaire
|
||||
@@ -96,8 +97,8 @@ export class ManagerSummaryService {
|
||||
|
||||
// Récupérer les données de base
|
||||
const [tasks, checkboxes] = await Promise.all([
|
||||
this.getCompletedTasks(weekStart, weekEnd),
|
||||
this.getCompletedCheckboxes(weekStart, weekEnd),
|
||||
this.getCompletedTasks(userId, weekStart, weekEnd),
|
||||
this.getCompletedCheckboxes(userId, weekStart, weekEnd),
|
||||
]);
|
||||
|
||||
// Analyser et extraire les accomplissements clés
|
||||
@@ -107,7 +108,7 @@ export class ManagerSummaryService {
|
||||
);
|
||||
|
||||
// Identifier les défis à venir
|
||||
const upcomingChallenges = await this.identifyUpcomingChallenges();
|
||||
const upcomingChallenges = await this.identifyUpcomingChallenges(userId);
|
||||
|
||||
// Calculer les métriques
|
||||
const metrics = this.calculateMetrics(tasks, checkboxes);
|
||||
@@ -130,9 +131,14 @@ export class ManagerSummaryService {
|
||||
/**
|
||||
* Récupère les tâches complétées de la semaine
|
||||
*/
|
||||
private static async getCompletedTasks(startDate: Date, endDate: Date) {
|
||||
private static async getCompletedTasks(
|
||||
userId: string,
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
) {
|
||||
const tasks = await prisma.task.findMany({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
OR: [
|
||||
// Tâches avec completedAt dans la période (priorité)
|
||||
{
|
||||
@@ -172,14 +178,24 @@ export class ManagerSummaryService {
|
||||
/**
|
||||
* Récupère les checkboxes complétées de la semaine
|
||||
*/
|
||||
private static async getCompletedCheckboxes(startDate: Date, endDate: Date) {
|
||||
private static async getCompletedCheckboxes(
|
||||
userId: string,
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
) {
|
||||
const checkboxes = await prisma.dailyCheckbox.findMany({
|
||||
where: {
|
||||
userId: userId,
|
||||
isChecked: true,
|
||||
date: {
|
||||
gte: startDate,
|
||||
lte: endDate,
|
||||
},
|
||||
// S'assurer que si le todo est lié à une tâche, cette tâche appartient bien à l'utilisateur
|
||||
OR: [
|
||||
{ task: null }, // Todos standalone (sans tâche associée)
|
||||
{ task: { ownerId: userId } }, // Todos liés à une tâche de l'utilisateur
|
||||
],
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
@@ -297,12 +313,13 @@ export class ManagerSummaryService {
|
||||
/**
|
||||
* Identifie les défis et enjeux à venir
|
||||
*/
|
||||
private static async identifyUpcomingChallenges(): Promise<
|
||||
UpcomingChallenge[]
|
||||
> {
|
||||
private static async identifyUpcomingChallenges(
|
||||
userId: string
|
||||
): Promise<UpcomingChallenge[]> {
|
||||
// Récupérer les tâches à venir (priorité high/medium en premier)
|
||||
const upcomingTasks = await prisma.task.findMany({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
completedAt: null,
|
||||
},
|
||||
orderBy: [
|
||||
@@ -331,18 +348,30 @@ export class ManagerSummaryService {
|
||||
// Récupérer les checkboxes récurrentes non complétées (meetings + tâches prioritaires)
|
||||
const upcomingCheckboxes = await prisma.dailyCheckbox.findMany({
|
||||
where: {
|
||||
userId: userId, // Filtrer par utilisateur
|
||||
isChecked: false,
|
||||
date: {
|
||||
gte: getToday(),
|
||||
},
|
||||
OR: [
|
||||
{ type: 'meeting' },
|
||||
// S'assurer que si le todo est lié à une tâche, cette tâche appartient bien à l'utilisateur
|
||||
AND: [
|
||||
{
|
||||
task: {
|
||||
priority: {
|
||||
in: ['high', 'medium'],
|
||||
OR: [
|
||||
{ task: null }, // Todos standalone (sans tâche associée)
|
||||
{ task: { ownerId: userId } }, // Todos liés à une tâche de l'utilisateur
|
||||
],
|
||||
},
|
||||
{
|
||||
OR: [
|
||||
{ type: 'meeting' },
|
||||
{
|
||||
task: {
|
||||
priority: {
|
||||
in: ['high', 'medium'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -72,6 +72,7 @@ export class MetricsService {
|
||||
* Récupère les métriques journalières des 7 derniers jours
|
||||
*/
|
||||
static async getWeeklyMetrics(
|
||||
userId: string,
|
||||
date: Date = getToday()
|
||||
): Promise<WeeklyMetricsOverview> {
|
||||
// Fenêtre glissante de 7 jours au lieu de semaine calendaire
|
||||
@@ -84,7 +85,7 @@ export class MetricsService {
|
||||
|
||||
// Récupérer les données pour chaque jour
|
||||
const dailyBreakdown = await Promise.all(
|
||||
daysOfWeek.map((day) => this.getDailyMetrics(day))
|
||||
daysOfWeek.map((day) => this.getDailyMetrics(userId, day))
|
||||
);
|
||||
|
||||
// Calculer les métriques de résumé
|
||||
@@ -114,7 +115,10 @@ export class MetricsService {
|
||||
/**
|
||||
* Récupère les métriques pour un jour donné
|
||||
*/
|
||||
private static async getDailyMetrics(date: Date): Promise<DailyMetrics> {
|
||||
private static async getDailyMetrics(
|
||||
userId: string,
|
||||
date: Date
|
||||
): Promise<DailyMetrics> {
|
||||
const dayStart = startOfDay(date);
|
||||
const dayEnd = endOfDay(date);
|
||||
|
||||
@@ -124,6 +128,7 @@ export class MetricsService {
|
||||
// Tâches complétées ce jour
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
OR: [
|
||||
{
|
||||
completedAt: {
|
||||
@@ -145,6 +150,7 @@ export class MetricsService {
|
||||
// Tâches en cours (status = in_progress à ce moment)
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
status: 'in_progress',
|
||||
createdAt: { lte: dayEnd },
|
||||
},
|
||||
@@ -153,6 +159,7 @@ export class MetricsService {
|
||||
// Tâches bloquées
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
status: 'blocked',
|
||||
createdAt: { lte: dayEnd },
|
||||
},
|
||||
@@ -161,6 +168,7 @@ export class MetricsService {
|
||||
// Tâches en attente
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
status: 'pending',
|
||||
createdAt: { lte: dayEnd },
|
||||
},
|
||||
@@ -169,6 +177,7 @@ export class MetricsService {
|
||||
// Nouvelles tâches créées ce jour
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
createdAt: {
|
||||
gte: dayStart,
|
||||
lte: dayEnd,
|
||||
@@ -179,6 +188,7 @@ export class MetricsService {
|
||||
// Total des tâches existantes ce jour
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
createdAt: { lte: dayEnd },
|
||||
},
|
||||
}),
|
||||
@@ -375,6 +385,7 @@ export class MetricsService {
|
||||
* Récupère les métriques de vélocité d'équipe (pour graphiques de tendance)
|
||||
*/
|
||||
static async getVelocityTrends(
|
||||
userId: string,
|
||||
weeksBack: number = 4
|
||||
): Promise<VelocityTrend[]> {
|
||||
const trends = [];
|
||||
@@ -388,6 +399,7 @@ export class MetricsService {
|
||||
const [completed, created] = await Promise.all([
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
completedAt: {
|
||||
gte: weekStart,
|
||||
lte: weekEnd,
|
||||
@@ -396,6 +408,7 @@ export class MetricsService {
|
||||
}),
|
||||
prisma.task.count({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
createdAt: {
|
||||
gte: weekStart,
|
||||
lte: weekEnd,
|
||||
|
||||
@@ -47,6 +47,7 @@ export class TagAnalyticsService {
|
||||
* Calcule les métriques de distribution par tags
|
||||
*/
|
||||
static async getTagDistributionMetrics(
|
||||
userId: string,
|
||||
timeRange?: TimeRange,
|
||||
sources?: string[]
|
||||
): Promise<TagDistributionMetrics> {
|
||||
@@ -60,6 +61,7 @@ export class TagAnalyticsService {
|
||||
// Récupérer toutes les tâches avec leurs tags
|
||||
const dbTasks = await prisma.task.findMany({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
createdAt: {
|
||||
gte: start,
|
||||
lte: end,
|
||||
@@ -102,6 +104,7 @@ export class TagAnalyticsService {
|
||||
jiraKey: task.jiraKey || undefined,
|
||||
jiraType: task.jiraType || undefined,
|
||||
assignee: task.assignee || undefined,
|
||||
ownerId: task.ownerId,
|
||||
}));
|
||||
|
||||
// Filtrer par sources si spécifié
|
||||
|
||||
Reference in New Issue
Block a user