diff --git a/src/lib/date-utils.ts b/src/lib/date-utils.ts index f4fa324..ab8076e 100644 --- a/src/lib/date-utils.ts +++ b/src/lib/date-utils.ts @@ -19,3 +19,17 @@ export function getWeekYearLabel(date: Date = new Date()): string { const year = date.getFullYear(); return `S${week.toString().padStart(2, '0')}-${year}`; } + +/** ISO week bounds (Monday 00:00:00 to Sunday 23:59:59.999) */ +export function getWeekBounds(date: Date): { start: Date; end: Date } { + const d = new Date(date); + const dayNum = d.getDay() || 7; // Sunday = 7 + const diff = d.getDate() - dayNum + (dayNum === 7 ? -6 : 1); // Monday + const monday = new Date(d); + monday.setDate(diff); + monday.setHours(0, 0, 0, 0); + const sunday = new Date(monday); + sunday.setDate(monday.getDate() + 6); + sunday.setHours(23, 59, 59, 999); + return { start: monday, end: sunday }; +} diff --git a/src/services/weather.ts b/src/services/weather.ts index 72e10d4..a95e73a 100644 --- a/src/services/weather.ts +++ b/src/services/weather.ts @@ -1,5 +1,6 @@ import { prisma } from '@/services/database'; import { getTeamMemberIdsForAdminTeams } from '@/services/teams'; +import { getWeekBounds } from '@/lib/date-utils'; import type { ShareRole } from '@prisma/client'; // ============================================ @@ -301,21 +302,43 @@ export async function shareWeatherSessionToTeam( throw new Error('Session not found or not owned'); } - // Get team members + // Max 1 météo par équipe par semaine const teamMembers = await prisma.teamMember.findMany({ + where: { teamId }, + select: { userId: true }, + }); + const teamMemberIds = teamMembers.map((tm) => tm.userId); + if (teamMemberIds.length > 0) { + const { start: weekStart, end: weekEnd } = getWeekBounds(session.date); + const existingCount = await prisma.weatherSession.count({ + where: { + id: { not: sessionId }, + date: { gte: weekStart, lte: weekEnd }, + shares: { + some: { userId: { in: teamMemberIds } }, + }, + }, + }); + if (existingCount > 0) { + throw new Error("Cette équipe a déjà une météo pour cette semaine"); + } + } + + // Get team members (full) + const teamMembersFull = await prisma.teamMember.findMany({ where: { teamId }, include: { user: { select: { id: true, name: true, email: true } }, }, }); - if (teamMembers.length === 0) { + if (teamMembersFull.length === 0) { throw new Error('Team has no members'); } // Share with all team members (except owner) const shares = await Promise.all( - teamMembers + teamMembersFull .filter((tm) => tm.userId !== ownerId) // Don't share with yourself .map((tm) => prisma.weatherSessionShare.upsert({