MeetUp/src/app/api/user/[user]/calendar/validation.ts

99 lines
2.6 KiB
TypeScript

import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
import zod from 'zod/v4';
import {
eventEndTimeSchema,
EventSchema,
eventStartTimeSchema,
} from '@/app/api/event/validation';
extendZodWithOpenApi(zod);
export const BlockedSlotSchema = zod
.object({
start_time: eventStartTimeSchema,
end_time: eventEndTimeSchema,
type: zod.literal('blocked_private'),
})
.openapi('BlockedSlotSchema', {
description: 'Blocked time slot in the user calendar',
});
export const OwnedBlockedSlotSchema = BlockedSlotSchema.extend({
id: zod.string(),
reason: zod.string().nullish(),
is_recurring: zod.boolean().default(false),
recurrence_end_date: zod.date().nullish(),
rrule: zod.string().nullish(),
created_at: zod.date().nullish(),
updated_at: zod.date().nullish(),
type: zod.literal('blocked_owned'),
}).openapi('OwnedBlockedSlotSchema', {
description: 'Blocked slot owned by the user',
});
export const VisibleSlotSchema = EventSchema.omit({
organizer: true,
participants: true,
})
.extend({
type: zod.literal('event'),
})
.openapi('VisibleSlotSchema', {
description: 'Visible time slot in the user calendar',
});
export const UserCalendarSchema = zod
.array(VisibleSlotSchema.or(BlockedSlotSchema).or(OwnedBlockedSlotSchema))
.openapi('UserCalendarSchema', {
description: 'Array of events in the user calendar',
});
export const UserCalendarResponseSchema = zod.object({
success: zod.boolean().default(true),
calendar: UserCalendarSchema,
});
export const userCalendarQuerySchema = zod
.object({
start: zod.iso
.datetime()
.optional()
.transform((val) => {
if (val) return new Date(val);
const now = new Date();
const startOfWeek = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate() - now.getDay(),
);
return startOfWeek;
}),
end: zod.iso
.datetime()
.optional()
.transform((val) => {
if (val) return new Date(val);
const now = new Date();
const endOfWeek = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate() + (6 - now.getDay()),
);
return endOfWeek;
}),
})
.openapi('UserCalendarQuerySchema', {
description: 'Query parameters for filtering the user calendar',
properties: {
start: {
type: 'string',
format: 'date-time',
description: 'Start date for filtering the calendar events',
},
end: {
type: 'string',
format: 'date-time',
description: 'End date for filtering the calendar events',
},
},
});