feat: initialize CalBook project with comprehensive scheduling, admin, and deployment infrastructure
This commit is contained in:
75
app/api/public/mitarbeiter/route.ts
Normal file
75
app/api/public/mitarbeiter/route.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { fail, ok } from "@/lib/api";
|
||||
import { getSettings } from "@/lib/settings";
|
||||
import { SETTING_KEYS } from "@/lib/constants";
|
||||
import { enforceRateLimit } from "@/lib/rate-limit";
|
||||
import { DEFAULT_TIMEZONE } from "@/lib/date";
|
||||
|
||||
export async function GET(req: Request) {
|
||||
const limit = enforceRateLimit({
|
||||
req,
|
||||
scope: "public-staff",
|
||||
limit: 120,
|
||||
windowMs: 60_000
|
||||
});
|
||||
|
||||
if (!limit.ok) {
|
||||
return fail("Zu viele Anfragen. Bitte kurz warten.", 429, {
|
||||
retryAfterSeconds: limit.retryAfterSeconds
|
||||
});
|
||||
}
|
||||
|
||||
const [mitarbeiter, settings] = await Promise.all([
|
||||
prisma.user.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
role: "STAFF",
|
||||
calendars: { some: {} }
|
||||
},
|
||||
orderBy: {
|
||||
name: "asc"
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
slug: true,
|
||||
bio: true,
|
||||
avatarUrl: true,
|
||||
timezone: true
|
||||
}
|
||||
}),
|
||||
getSettings([
|
||||
SETTING_KEYS.COMPANY_NAME,
|
||||
SETTING_KEYS.BOOKING_NOTICE_TEXT,
|
||||
SETTING_KEYS.DEFAULT_DURATION_MINUTES,
|
||||
SETTING_KEYS.FRONTEND_HEADER_TEXT,
|
||||
SETTING_KEYS.FRONTEND_HEADER_LOGO_URL,
|
||||
SETTING_KEYS.FOOTER_PRIVACY_LABEL,
|
||||
SETTING_KEYS.FOOTER_PRIVACY_URL,
|
||||
SETTING_KEYS.FOOTER_IMPRINT_LABEL,
|
||||
SETTING_KEYS.FOOTER_IMPRINT_URL,
|
||||
SETTING_KEYS.FOOTER_COPYRIGHT_TEXT
|
||||
])
|
||||
]);
|
||||
|
||||
return ok({
|
||||
mitarbeiter,
|
||||
config: {
|
||||
companyName: settings[SETTING_KEYS.COMPANY_NAME] ?? "CalBook",
|
||||
bookingNoticeText: settings[SETTING_KEYS.BOOKING_NOTICE_TEXT] ?? "",
|
||||
defaultDurationMinutes: Number(settings[SETTING_KEYS.DEFAULT_DURATION_MINUTES] ?? "60"),
|
||||
headerText: settings[SETTING_KEYS.FRONTEND_HEADER_TEXT] ?? "Gespräch",
|
||||
headerLogoUrl: settings[SETTING_KEYS.FRONTEND_HEADER_LOGO_URL] ?? "",
|
||||
footerPrivacyLabel: settings[SETTING_KEYS.FOOTER_PRIVACY_LABEL] ?? "Datenschutz",
|
||||
footerPrivacyUrl: settings[SETTING_KEYS.FOOTER_PRIVACY_URL] ?? "/datenschutz",
|
||||
footerImprintLabel: settings[SETTING_KEYS.FOOTER_IMPRINT_LABEL] ?? "Impressum",
|
||||
footerImprintUrl: settings[SETTING_KEYS.FOOTER_IMPRINT_URL] ?? "/impressum",
|
||||
footerCopyrightText:
|
||||
settings[SETTING_KEYS.FOOTER_COPYRIGHT_TEXT] ?? "© {{year}} {{companyName}}",
|
||||
defaultTimezone: DEFAULT_TIMEZONE,
|
||||
personCount: mitarbeiter.length
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user