diff --git a/functions/api/events-team/events/[id].ts b/functions/api/events-team/events/[id].ts index 66189b5..c107ee2 100644 --- a/functions/api/events-team/events/[id].ts +++ b/functions/api/events-team/events/[id].ts @@ -47,12 +47,13 @@ export async function onRequestDelete(context: RequestContext) { export async function onRequestPatch(context: RequestContext) { const eventId = context.params.id as string; const { body } = context.data; - const eventData: Record | null = - await context.env.D1.prepare( - "SELECT answer, created_by, day, details, month, year FROM events WHERE id = ?;", - ) - .bind(eventId) - .first(); + const eventData: + | ({ [k: string]: number } & { created_by: string; type: string }) + | null = await context.env.D1.prepare( + "SELECT created_by, day, month, type, year FROM events WHERE id = ?;", + ) + .bind(eventId) + .first(); if (!eventData) return jsonError("No event exists with that ID", 404); @@ -64,22 +65,78 @@ export async function onRequestPatch(context: RequestContext) { ) return jsonError("You are not authorized to modify this event", 403); - eventData.answer &&= body.answer; - eventData.details &&= body.details; + const date = new Date(); + const currentDay = date.getUTCDate(); - await context.env.D1.prepare( - "UPDATE events SET answer = ?, approved = 0, day = ?, details = ?, pending = 1 WHERE id = ?;", + date.setUTCDate(0); + + if ( + typeof body.day !== "number" || + body.day > date.getUTCDate() || + body.day < 1 || + // Check for non-integers + Math.floor(body.day) !== body.day || + currentDay >= body.day ) - .bind(eventData.answer, eventData.day, eventData.details, eventId) + return jsonError("Invalid day", 400); + + if ( + date.getUTCFullYear() !== eventData.year || + date.getUTCMonth() !== eventData.month + ) + return jsonError( + "Only events in the current month period can be rescheduled", + 400, + ); + + if (eventData.type === "rotw") { + const weekRanges: { [k: number]: number } = { + 0: 7, + 1: 14, + 2: 21, + 3: 28, + 4: 35, + }; + const weekRange = Math.floor(body.day / 7); + + const matchingROTW = await context.env.D1.prepare( + "SELECT id FROM events WHERE (approved = 1 OR pending = 1) AND day BETWEEN ? AND ? AND month = ? AND type = 'rotw' AND year = ?;", + ) + .bind( + weekRanges[weekRange] - 7, + weekRanges[weekRange], + eventData.month, + eventData.year, + ) + .first(); + + if (matchingROTW) + return jsonError("There is already an ROTW scheduled for that week", 400); + } else { + const matchingEvent = await context.env.D1.prepare( + "SELECT id FROM events WHERE (approved = 1 OR pending = 1) AND day = ? AND month = ? AND type = ? AND year = ?;", + ) + .bind(body.day, eventData.month, eventData.type, eventData.year) + .first(); + + if (matchingEvent) + return jsonError( + "There is already an event of that type scheduled for that day", + 400, + ); + } + + await context.env.D1.prepare("UPDATE events SET day = ? WHERE id = ?;") + .bind(body.day, eventId) .run(); await fetch(context.env.EVENTS_WEBHOOK, { body: JSON.stringify({ embeds: [ { - title: "Event Modified", + title: "Event Rescheduled", color: 3756250, - description: `${context.data.current_user.username} updated their ${(eventData.type as string).toUpperCase()} for ${eventData.year}-${eventData.month.toString().padStart(2, "0")}-${eventData.day.toString().padStart(2, "0")}`, + description: `${context.data.current_user.username} rescheduled their event for ${eventData.year}-${eventData.month.toString().padStart(2, "0")}-${eventData.day.toString().padStart(2, "0")} to ${eventData.year}-${eventData.month.toString().padStart(2, "0")}-${body.day}`, }, ], }),