Initial PHP rebuild of the app
This commit is contained in:
690 files changed
+33944
-12046
No files matched your search
@@ -1,72 +0,0 @@
|
||||
import type { PrismaClient } from "@/generated/prisma/client";
|
||||
import { fail, ok } from "@/lib/validation-result";
|
||||
import type { ValidationResult } from "@/lib/validation-result";
|
||||
import type { BookingRuleConfig } from "./business-rules.service";
|
||||
|
||||
/**
|
||||
* Read/write for the BookingRule row itself — deliberately separate from
|
||||
* business-rules.service.ts, which is pure evaluation logic with no Prisma
|
||||
* access by design (see that file's own header). This file owns the one
|
||||
* thing that one doesn't: loading and validating the actual configuration
|
||||
* an owner edits, which every booking-time check then reads via
|
||||
* AvailabilityService exactly as before — nothing about how rules are
|
||||
* *evaluated* changes here, only how they're *set*.
|
||||
*/
|
||||
|
||||
export type BookingRuleErrorCode = "INVALID_INPUT";
|
||||
|
||||
export type BookingRuleInput = BookingRuleConfig;
|
||||
|
||||
export function validateBookingRuleInput(input: BookingRuleInput): ValidationResult<BookingRuleErrorCode> {
|
||||
if (!Number.isInteger(input.minNoticeMinutes) || input.minNoticeMinutes < 0) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Minimum notice can't be negative." });
|
||||
}
|
||||
if (!Number.isInteger(input.maxAdvanceDays) || input.maxAdvanceDays < 1) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Maximum advance booking must be at least 1 day." });
|
||||
}
|
||||
if (!Number.isInteger(input.cancellationWindowHours) || input.cancellationWindowHours < 0) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Cancellation window can't be negative." });
|
||||
}
|
||||
if (!Number.isInteger(input.rescheduleWindowHours) || input.rescheduleWindowHours < 0) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Reschedule window can't be negative." });
|
||||
}
|
||||
if (!Number.isInteger(input.slotIntervalMinutes) || input.slotIntervalMinutes < 5 || input.slotIntervalMinutes > 120) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Slot interval must be between 5 and 120 minutes." });
|
||||
}
|
||||
if (!Number.isInteger(input.bufferBeforeMinutes) || input.bufferBeforeMinutes < 0) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Buffer before can't be negative." });
|
||||
}
|
||||
if (!Number.isInteger(input.bufferAfterMinutes) || input.bufferAfterMinutes < 0) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Buffer after can't be negative." });
|
||||
}
|
||||
if (input.maxAppointmentsPerDay !== null && (!Number.isInteger(input.maxAppointmentsPerDay) || input.maxAppointmentsPerDay < 1)) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Max appointments per day must be at least 1, or left unlimited." });
|
||||
}
|
||||
if (
|
||||
input.maxAppointmentsPerStaffPerDay !== null &&
|
||||
(!Number.isInteger(input.maxAppointmentsPerStaffPerDay) || input.maxAppointmentsPerStaffPerDay < 1)
|
||||
) {
|
||||
return fail({ code: "INVALID_INPUT", message: "Max appointments per staff member per day must be at least 1, or left unlimited." });
|
||||
}
|
||||
return ok();
|
||||
}
|
||||
|
||||
export async function getBookingRule(prisma: PrismaClient, businessId: string) {
|
||||
return prisma.bookingRule.findUnique({ where: { businessId } });
|
||||
}
|
||||
|
||||
export async function updateBookingRule(
|
||||
prisma: PrismaClient,
|
||||
params: { businessId: string; input: BookingRuleInput },
|
||||
): Promise<{ success: boolean; validation: ValidationResult<BookingRuleErrorCode> }> {
|
||||
const validation = validateBookingRuleInput(params.input);
|
||||
if (!validation.valid) return { success: false, validation };
|
||||
|
||||
await prisma.bookingRule.upsert({
|
||||
where: { businessId: params.businessId },
|
||||
create: { businessId: params.businessId, ...params.input },
|
||||
update: { ...params.input },
|
||||
});
|
||||
|
||||
return { success: true, validation: ok() };
|
||||
}
|
||||
Reference in new issue
Block a user