feat: implement getWeekBounds function for calculating ISO week boundaries and integrate it into weather session sharing logic

This commit is contained in:
Julien Froidefond
2026-02-17 14:05:50 +01:00
parent 4e14112ffa
commit 5e9ae0936f
2 changed files with 40 additions and 3 deletions

View File

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

View File

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