feat: make actionSource required with ValidActionSource type across booking handlers (#27869)
* feat: make actionSource required with ValidActionSource type across booking handlers Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: update getAuditActionSource to return ValidActionSource, default to SYSTEM Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: revert getAuditActionSource, handleSeats, RegularBookingService back to ActionSource Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
This commit is contained in:
11 files changed
+42
-22
No files matched your search
@@ -82,6 +82,7 @@ async function handler(req: NextApiRequest) {
|
||||
return await handleCancelBooking({
|
||||
bookingData: { id, allRemainingBookings, cancellationReason, cancelledBy },
|
||||
userId: req.userId,
|
||||
actionSource: "API_V1",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -279,6 +279,7 @@ export class BookingsController_2024_04_15 {
|
||||
platformCancelUrl: bookingRequest.platformCancelUrl,
|
||||
platformRescheduleUrl: bookingRequest.platformRescheduleUrl,
|
||||
platformBookingUrl: bookingRequest.platformBookingUrl,
|
||||
actionSource: "API_V2",
|
||||
});
|
||||
if (!res.onlyRemovedAttendee && res.isPlatformManagedUserBooking) {
|
||||
void (await this.billingService.cancelUsageByBookingUid(res.bookingUid));
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
makeGuestActor,
|
||||
makeUserActor,
|
||||
} from "@calcom/features/booking-audit/lib/makeActor";
|
||||
import type { ActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import type { ValidActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import { BookingReferenceRepository } from "@calcom/features/bookingReference/repositories/BookingReferenceRepository";
|
||||
import { getBookingEventHandlerService } from "@calcom/features/bookings/di/BookingEventHandlerService.container";
|
||||
import EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
@@ -81,7 +81,7 @@ export type CancelBookingInput = {
|
||||
userId?: number;
|
||||
userUuid?: string;
|
||||
bookingData: z.infer<typeof bookingCancelInput>;
|
||||
actionSource?: ActionSource;
|
||||
actionSource: ValidActionSource;
|
||||
} & PlatformParams;
|
||||
|
||||
type Dependencies = {
|
||||
@@ -173,17 +173,7 @@ async function handler(input: CancelBookingInput, dependencies?: Dependencies) {
|
||||
|
||||
const userUuid = input.userUuid ?? null;
|
||||
|
||||
// Extract action source once for reuse
|
||||
const actionSource = input.actionSource ?? "UNKNOWN";
|
||||
if (actionSource === "UNKNOWN") {
|
||||
log.warn(
|
||||
"Booking cancellation with unknown actionSource",
|
||||
safeStringify({
|
||||
bookingUid: bookingToDelete.uid,
|
||||
userUuid,
|
||||
})
|
||||
);
|
||||
}
|
||||
const actionSource = input.actionSource;
|
||||
|
||||
const actorToUse = getAuditActor({
|
||||
userUuid,
|
||||
@@ -724,10 +714,15 @@ type BookingCancelServiceDependencies = {
|
||||
export class BookingCancelService implements IBookingCancelService {
|
||||
constructor(private readonly deps: BookingCancelServiceDependencies) {}
|
||||
|
||||
async cancelBooking(input: { bookingData: CancelRegularBookingData; bookingMeta?: CancelBookingMeta }) {
|
||||
async cancelBooking(input: {
|
||||
bookingData: CancelRegularBookingData;
|
||||
bookingMeta?: CancelBookingMeta;
|
||||
actionSource: ValidActionSource;
|
||||
}) {
|
||||
const cancelBookingInput: CancelBookingInput = {
|
||||
bookingData: input.bookingData,
|
||||
...(input.bookingMeta || {}),
|
||||
actionSource: input.actionSource,
|
||||
};
|
||||
|
||||
return handler(cancelBookingInput, this.deps);
|
||||
|
||||
@@ -134,6 +134,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "No reason",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expectBookingCancelledWebhookToHaveBeenFired({
|
||||
@@ -264,6 +265,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "No reason",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expectBookingCancelledWebhookToHaveBeenFired({
|
||||
@@ -411,6 +413,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "Testing round robin cancellation with host as attendee",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -563,6 +566,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: primaryHost.email,
|
||||
cancellationReason: "Testing EMAIL_HOST workflow sends to secondary host in round robin",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -640,6 +644,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "Testing past booking cancellation",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
})
|
||||
).rejects.toThrow("Cannot cancel a booking that has already ended");
|
||||
});
|
||||
@@ -708,6 +713,7 @@ describe("Cancel Booking", () => {
|
||||
uid: uidOfBookingToBeCancelled,
|
||||
cancelledBy: organizer.email,
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
})
|
||||
).rejects.toThrow("Cancellation reason is required when you are the host");
|
||||
});
|
||||
@@ -819,6 +825,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "No reason",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -945,6 +952,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "No reason",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -1062,6 +1070,7 @@ describe("Cancel Booking", () => {
|
||||
cancellationReason: "Attendee cancelled within time threshold",
|
||||
},
|
||||
userId: 999,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -1170,6 +1179,7 @@ describe("Cancel Booking", () => {
|
||||
cancelledBy: organizer.email,
|
||||
cancellationReason: "Organization booking cancellation test",
|
||||
},
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expectBookingCancelledWebhookToHaveBeenFired({
|
||||
@@ -1292,6 +1302,7 @@ describe("Cancel Booking", () => {
|
||||
cancellationReason: "Cancelling seated event",
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -1413,6 +1424,7 @@ describe("Cancel Booking", () => {
|
||||
allRemainingBookings: true,
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -1534,6 +1546,7 @@ describe("Cancel Booking", () => {
|
||||
cancelSubsequentBookings: true,
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -1647,6 +1660,7 @@ describe("Cancel Booking", () => {
|
||||
cancellationReason: "Testing booking reference cleanup",
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils"
|
||||
import { scheduleMandatoryReminder } from "@calcom/ee/workflows/lib/reminders/scheduleMandatoryReminder";
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import type { Actor } from "@calcom/features/booking-audit/lib/dto/types";
|
||||
import type { ActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import type { ValidActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import { getBookingEventHandlerService } from "@calcom/features/bookings/di/BookingEventHandlerService.container";
|
||||
import type { EventManagerUser } from "@calcom/features/bookings/lib/EventManager";
|
||||
import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
|
||||
@@ -48,7 +48,7 @@ async function fireBookingAcceptedEvent({
|
||||
}: {
|
||||
actor: Actor;
|
||||
organizationId: number | null;
|
||||
actionSource: ActionSource;
|
||||
actionSource: ValidActionSource;
|
||||
acceptedBookings: {
|
||||
uid: string;
|
||||
oldStatus: BookingStatus;
|
||||
@@ -133,7 +133,7 @@ export async function handleConfirmation(args: {
|
||||
emailsEnabled?: boolean;
|
||||
platformClientParams?: PlatformClientParams;
|
||||
traceContext: TraceContext;
|
||||
actionSource: ActionSource;
|
||||
actionSource: ValidActionSource;
|
||||
actor: Actor;
|
||||
}) {
|
||||
const {
|
||||
|
||||
@@ -1976,6 +1976,7 @@ describe("handleSeats", () => {
|
||||
cancellationReason: "test cancellation reason",
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
// Ensure that the booking has been cancelled
|
||||
@@ -2115,6 +2116,7 @@ describe("handleSeats", () => {
|
||||
cancellationReason: "test cancellation reason",
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
// Ensure that the booking has been cancelled
|
||||
@@ -2967,6 +2969,7 @@ describe("handleSeats", () => {
|
||||
cancellationReason: "test cancellation reason",
|
||||
},
|
||||
userId: organizer.id,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
|
||||
// Ensure that the booking has been cancelled
|
||||
|
||||
@@ -3,10 +3,12 @@ import type {
|
||||
CancelBookingMeta,
|
||||
HandleCancelBookingResponse,
|
||||
} from "../dto/BookingCancel";
|
||||
import type { ValidActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
|
||||
export interface IBookingCancelService {
|
||||
cancelBooking(input: {
|
||||
bookingData: CancelRegularBookingData;
|
||||
bookingMeta?: CancelBookingMeta;
|
||||
actionSource: ValidActionSource;
|
||||
}): Promise<HandleCancelBookingResponse>;
|
||||
}
|
||||
@@ -121,6 +121,7 @@ export const bookingsRouter = router({
|
||||
return reportBookingHandler({
|
||||
ctx,
|
||||
input,
|
||||
actionSource: "WEBAPP",
|
||||
});
|
||||
}),
|
||||
reportWrongAssignment: authedProcedure
|
||||
|
||||
@@ -2,7 +2,7 @@ import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/app-store/d
|
||||
import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { makeUserActor } from "@calcom/features/booking-audit/lib/makeActor";
|
||||
import type { ActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import type { ValidActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import { getBookingEventHandlerService } from "@calcom/features/bookings/di/BookingEventHandlerService.container";
|
||||
import { BookingEmailSmsHandler } from "@calcom/features/bookings/lib/BookingEmailSmsHandler";
|
||||
import EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
@@ -35,7 +35,7 @@ type AddGuestsOptions = {
|
||||
};
|
||||
input: TAddGuestsInputSchema;
|
||||
emailsEnabled?: boolean;
|
||||
actionSource: ActionSource;
|
||||
actionSource: ValidActionSource;
|
||||
};
|
||||
|
||||
export type Booking = NonNullable<
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { PrismaBookingReportRepository } from "@calcom/features/bookingReport/repositories/PrismaBookingReportRepository";
|
||||
import type { ValidActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import handleCancelBooking from "@calcom/features/bookings/lib/handleCancelBooking";
|
||||
import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository";
|
||||
import { BookingAccessService } from "@calcom/features/bookings/services/BookingAccessService";
|
||||
@@ -16,11 +17,12 @@ type ReportBookingOptions = {
|
||||
user: NonNullable<TrpcSessionUser>;
|
||||
};
|
||||
input: TReportBookingInputSchema;
|
||||
actionSource: ValidActionSource;
|
||||
};
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["reportBookingHandler"] });
|
||||
|
||||
export const reportBookingHandler = async ({ ctx, input }: ReportBookingOptions) => {
|
||||
export const reportBookingHandler = async ({ ctx, input, actionSource }: ReportBookingOptions) => {
|
||||
const { user } = ctx;
|
||||
const { bookingUid, reason, description } = input;
|
||||
|
||||
@@ -90,6 +92,7 @@ export const reportBookingHandler = async ({ ctx, input }: ReportBookingOptions)
|
||||
...(seatReferenceUid ? { seatReferenceUid } : {}),
|
||||
},
|
||||
userId: user.id,
|
||||
actionSource,
|
||||
});
|
||||
didCancel = true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/app-store/d
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import { makeUserActor } from "@calcom/features/booking-audit/lib/makeActor";
|
||||
import type { ActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import type { ValidActionSource } from "@calcom/features/booking-audit/lib/types/actionSource";
|
||||
import { getBookingEventHandlerService } from "@calcom/features/bookings/di/BookingEventHandlerService.container";
|
||||
import { getFeaturesRepository } from "@calcom/features/di/containers/FeaturesRepository";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
@@ -47,7 +47,7 @@ type RequestRescheduleOptions = {
|
||||
user: NonNullable<TrpcSessionUser>;
|
||||
};
|
||||
input: TRequestRescheduleInputSchema;
|
||||
source: ActionSource;
|
||||
source: ValidActionSource;
|
||||
};
|
||||
const log = logger.getSubLogger({ prefix: ["requestRescheduleHandler"] });
|
||||
export const requestRescheduleHandler = async ({ ctx, input, source }: RequestRescheduleOptions) => {
|
||||
|
||||
Reference in new issue
Block a user