Integrate LiveKit SFU and harden booking workflow
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
} from "@/lib/email/bookingTemplates";
|
||||
import { sendEmail } from "@/lib/email/sendBookingEmails";
|
||||
import type { Customer, Event, Offer } from "@/payload-types";
|
||||
import { berlinDateKey, berlinDayBounds, formatBerlinDate, formatBerlinTime } from "@/lib/calendar/timezone";
|
||||
|
||||
export const APPOINTMENT_TYPES = [
|
||||
{ label: "Vor Ort", value: "onsite" },
|
||||
@@ -26,15 +27,15 @@ export const BOOKING_STATUSES = [
|
||||
] as const;
|
||||
|
||||
function dateKey(iso: string): string {
|
||||
return new Date(iso).toISOString().slice(0, 10);
|
||||
return berlinDateKey(new Date(iso));
|
||||
}
|
||||
|
||||
function fmtDate(iso: string): string {
|
||||
return new Date(iso).toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric" });
|
||||
return formatBerlinDate(new Date(iso), { day: "2-digit", month: "long", year: "numeric" });
|
||||
}
|
||||
|
||||
function fmtTime(iso: string): string {
|
||||
return new Date(iso).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });
|
||||
return formatBerlinTime(new Date(iso), { hour: "2-digit", minute: "2-digit" });
|
||||
}
|
||||
|
||||
const appointmentTypeLabel = (value: string) =>
|
||||
@@ -70,8 +71,9 @@ const handleConfirmation: CollectionBeforeChangeHook = async ({ data, originalDo
|
||||
|
||||
await acquireBookingDayLock(req, dateKey(date));
|
||||
|
||||
const dayStart = new Date(new Date(date).setHours(0, 0, 0, 0)).toISOString();
|
||||
const dayEnd = new Date(new Date(date).setHours(23, 59, 59, 999)).toISOString();
|
||||
const dayBounds = berlinDayBounds(new Date(date));
|
||||
const dayStart = dayBounds.start.toISOString();
|
||||
const dayEnd = dayBounds.end.toISOString();
|
||||
const conflictClauses: Where[] = [
|
||||
{ status: { equals: "confirmed" } },
|
||||
{ date: { greater_than_equal: dayStart } },
|
||||
|
||||
@@ -14,8 +14,11 @@ export const EventRegistrations: CollectionConfig = {
|
||||
description: "Anmeldungen zu Terminen — wird beim öffentlichen Anmeldeformular befüllt.",
|
||||
},
|
||||
access: {
|
||||
// Visitors register themselves through the public event page.
|
||||
create: () => true,
|
||||
// Public registrations must go through /api/meetings/[slug]/register,
|
||||
// which verifies publication/registrationRequired, normalizes the email,
|
||||
// and enforces the capacity check. The Local API used by that route
|
||||
// intentionally overrides this access rule after those checks.
|
||||
create: () => false,
|
||||
read: isAdmin,
|
||||
update: isAdmin,
|
||||
delete: isAdmin,
|
||||
|
||||
Reference in New Issue
Block a user