diff --git a/src/__tests__/plan.test.ts b/src/__tests__/plan.test.ts index 72c4ab0..66b2a5e 100644 --- a/src/__tests__/plan.test.ts +++ b/src/__tests__/plan.test.ts @@ -909,6 +909,20 @@ describe("plan.service.bulkCreateEntries", () => { ); expect("error" in empty && empty.status).toBe(400); + const tooLong = await bulkCreateEntries( + { + user_ids: [adminUserId], + date_from: "2096-01-01", + date_to: "2096-12-31", // > 92 days + include_weekends: true, + project_id: null, + category: "work", + note: `${N}x`, + }, + adminUserId, + ); + expect("error" in tooLong && tooLong.status).toBe(400); + const past = await bulkCreateEntries( { user_ids: [adminUserId], diff --git a/src/schemas/plan.schema.ts b/src/schemas/plan.schema.ts index 600655a..8f6239a 100644 --- a/src/schemas/plan.schema.ts +++ b/src/schemas/plan.schema.ts @@ -88,7 +88,8 @@ export const BulkPlanEntrySchema = z .object({ user_ids: z .array(intFromForm) - .min(1, "Vyberte alespoň jednoho zaměstnance"), + .min(1, "Vyberte alespoň jednoho zaměstnance") + .transform((ids) => [...new Set(ids)]), date_from: isoDate, date_to: isoDate, include_weekends: z diff --git a/src/services/plan.service.ts b/src/services/plan.service.ts index 2d7b21d..29fc426 100644 --- a/src/services/plan.service.ts +++ b/src/services/plan.service.ts @@ -811,6 +811,13 @@ export async function bulkCreateEntries( const from = toDateOnly(input.date_from); const to = toDateOnly(input.date_to); + // Bound the work (users × days). Mirror the 92-day cap on GET /plan/grid so + // one bulk call can't fan out into thousands of inserts. + const rangeDays = Math.round((to.getTime() - from.getTime()) / 86400000) + 1; + if (rangeDays > 92) { + return { error: "Maximální rozsah je 92 dní", status: 400 }; + } + // The day list for the whole range (UTC midnights), built once. const days: Date[] = []; for (let d = new Date(from); d <= to; d.setUTCDate(d.getUTCDate() + 1)) {