MeetUp/src/app/api/calendar/validation.ts
Dominik Stahl b5a07b7bed
Some checks failed
container-scan / Container Scan (pull_request) Failing after 1m20s
docker-build / docker (pull_request) Failing after 3m5s
tests / Tests (pull_request) Failing after 2m35s
feat(blocked_slots): add blocked slots
2025-06-30 20:40:03 +02:00

112 lines
3 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'),
id: zod.string(),
users: zod.string().array(),
user_id: zod.string().optional(),
})
.openapi('BlockedSlotSchema', {
description: 'Blocked time slot in the user calendar',
});
export const OwnedBlockedSlotSchema = zod
.object({
start_time: eventStartTimeSchema,
end_time: eventEndTimeSchema,
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'),
users: zod.string().array(),
user_id: zod.string().optional(),
})
.openapi('OwnedBlockedSlotSchema', {
description: 'Blocked slot owned by the user',
});
export const VisibleSlotSchema = EventSchema.omit({
participants: true,
organizer: true,
})
.extend({
type: zod.literal('event'),
users: zod.string().array(),
user_id: zod.string().optional(),
organizer_id: zod.string().optional(),
})
.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;
}),
userIds: zod.string().array(),
})
.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',
},
},
});