feat: implement getWeekBounds function for calculating ISO week boundaries and integrate it into weather session sharing logic
This commit is contained in:
@@ -19,3 +19,17 @@ export function getWeekYearLabel(date: Date = new Date()): string {
|
|||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
return `S${week.toString().padStart(2, '0')}-${year}`;
|
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 };
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { prisma } from '@/services/database';
|
import { prisma } from '@/services/database';
|
||||||
import { getTeamMemberIdsForAdminTeams } from '@/services/teams';
|
import { getTeamMemberIdsForAdminTeams } from '@/services/teams';
|
||||||
|
import { getWeekBounds } from '@/lib/date-utils';
|
||||||
import type { ShareRole } from '@prisma/client';
|
import type { ShareRole } from '@prisma/client';
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -301,21 +302,43 @@ export async function shareWeatherSessionToTeam(
|
|||||||
throw new Error('Session not found or not owned');
|
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({
|
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 },
|
where: { teamId },
|
||||||
include: {
|
include: {
|
||||||
user: { select: { id: true, name: true, email: true } },
|
user: { select: { id: true, name: true, email: true } },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (teamMembers.length === 0) {
|
if (teamMembersFull.length === 0) {
|
||||||
throw new Error('Team has no members');
|
throw new Error('Team has no members');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Share with all team members (except owner)
|
// Share with all team members (except owner)
|
||||||
const shares = await Promise.all(
|
const shares = await Promise.all(
|
||||||
teamMembers
|
teamMembersFull
|
||||||
.filter((tm) => tm.userId !== ownerId) // Don't share with yourself
|
.filter((tm) => tm.userId !== ownerId) // Don't share with yourself
|
||||||
.map((tm) =>
|
.map((tm) =>
|
||||||
prisma.weatherSessionShare.upsert({
|
prisma.weatherSessionShare.upsert({
|
||||||
|
|||||||
Reference in New Issue
Block a user