Skip to content

Commit 05e1ad0

Browse files
hariombalharaclaudecoderabbitai[bot]devin-ai-integration[bot]
authored
fix: Code Quality improvements to response record endpoint and added unit tests (calcom#22264)
* chore: remove unnecessary logs and fix documentation * refactor: extract GetSlotsInputWithRouting type and eliminate code duplication - Move GetSlotsInputWithRouting_2024_09_04 type to platform-types package for reuse - Refactor slots service to eliminate duplicate error handling logic - Fix TypeScript errors in slots service tests by adding missing type property - Update test expectations to match new implementation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: improve type safety in slots service - Export explicit types from slots-input.service for transformed queries - Replace 'any' type with proper TransformedSlotsQuery union type - Re-implement fetchAndFormatSlots abstraction to eliminate code duplication - Revert unrelated console.log in router.controller.ts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: simplify slots service implementation - Remove intermediate variable assignment in getAvailableSlotsWithRouting - Update test to match simplified routing parameters structure * test: add comprehensive error handling and edge case tests for slots service - Add error scenario tests for NotFoundException, invalid time range, and generic errors - Add edge case tests for null/undefined parameters and empty arrays - Improve test coverage for getAvailableSlotsWithRouting method - Mock SlotsInputService properly to enable isolated unit testing * 📝 CodeRabbit Chat: Rename TransformedGetSlotsQuery types to InternalGetSlotsQuery in slot services * fix: correct import path for AvailableSlotsService in slots service test - Fix import path from '@/lib/services/AvailableSlots' to '@/lib/services/available-slots.service' - Resolves unit test failure due to case sensitivity/naming mismatch - All API v2 tests now pass (9 test suites, 142 tests) Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent cf39256 commit 05e1ad0

9 files changed

Lines changed: 477 additions & 51 deletions

File tree

apps/api/v2/src/modules/organizations/routing-forms/outputs/create-routing-form-response.output.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,10 @@ export class CreateRoutingFormResponseOutputData {
8686
eventTypeId?: number;
8787

8888
@ValidateNested()
89-
@ApiProperty({ type: Routing })
9089
@Type(() => Routing)
9190
@ApiPropertyOptional({
9291
type: Routing,
93-
description: "The routing information.",
92+
description: "The routing information that could be passed as is to the booking API.",
9493
example: {
9594
eventTypeId: 123,
9695
routing: {
@@ -100,8 +99,6 @@ export class CreateRoutingFormResponseOutputData {
10099
},
101100
},
102101
})
103-
@ValidateNested()
104-
@Type(() => Routing)
105102
routing?: Routing;
106103

107104
@IsString()

apps/api/v2/src/modules/organizations/routing-forms/services/shared-routing-form-response.service.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,14 @@ export class SharedRoutingFormResponseService {
5555
// Extract event type information from the routed URL
5656
const { eventTypeId, crmParams } = await this.extractEventTypeAndCrmParams(user.id, redirectUrl);
5757

58-
const paramsForGetAvailableSlots = {
58+
// Get available slots using the slots service with CRM parameters
59+
const slots = await this.slotsService.getAvailableSlotsWithRouting({
5960
type: ById_2024_09_04_type,
6061
eventTypeId,
6162
...slotsQuery,
6263
...crmParams,
63-
} as const;
64+
});
6465

65-
// Get available slots using the slots service with CRM parameters
66-
const slots = await this.slotsService.getAvailableSlots(paramsForGetAvailableSlots);
6766
const teamMemberIds = crmParams.routedTeamMemberIds ?? [];
6867
const teamMemberEmail = crmParams.teamMemberEmail ?? undefined;
6968
const skipContactOwner = crmParams.skipContactOwner ?? undefined;

apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-input.service.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,32 @@ import {
1313
ByUsernameAndEventTypeSlug_2024_09_04,
1414
ByTeamSlugAndEventTypeSlug_2024_09_04,
1515
GetSlotsInput_2024_09_04,
16+
GetSlotsInputWithRouting_2024_09_04,
1617
ById_2024_09_04_type,
1718
ByUsernameAndEventTypeSlug_2024_09_04_type,
1819
ByTeamSlugAndEventTypeSlug_2024_09_04_type,
1920
} from "@calcom/platform-types";
2021

22+
export type InternalGetSlotsQuery = {
23+
isTeamEvent: boolean;
24+
startTime: string;
25+
endTime: string;
26+
duration?: number;
27+
eventTypeId: number;
28+
eventTypeSlug: string;
29+
usernameList: string[];
30+
timeZone: string | undefined;
31+
orgSlug: string | null | undefined;
32+
rescheduleUid: string | null;
33+
};
34+
35+
export type InternalGetSlotsQueryWithRouting = InternalGetSlotsQuery & {
36+
routedTeamMemberIds: number[] | null;
37+
skipContactOwner: boolean;
38+
teamMemberEmail: string | null;
39+
routingFormResponseId: number | undefined;
40+
};
41+
2142
@Injectable()
2243
export class SlotsInputService_2024_09_04 {
2344
constructor(
@@ -30,7 +51,7 @@ export class SlotsInputService_2024_09_04 {
3051
private readonly teamsEventTypesRepository: TeamsEventTypesRepository
3152
) {}
3253

33-
async transformGetSlotsQuery(query: GetSlotsInput_2024_09_04) {
54+
async transformGetSlotsQuery(query: GetSlotsInput_2024_09_04): Promise<InternalGetSlotsQuery> {
3455
const eventType = await this.getEventType(query);
3556
if (!eventType) {
3657
throw new NotFoundException(`Event Type not found`);
@@ -46,10 +67,6 @@ export class SlotsInputService_2024_09_04 {
4667
const timeZone = query.timeZone;
4768
const orgSlug = "organizationSlug" in query ? query.organizationSlug : null;
4869
const rescheduleUid = query.bookingUidToReschedule || null;
49-
const routedTeamMemberIds = query.routedTeamMemberIds || null;
50-
const skipContactOwner = query.skipContactOwner || false;
51-
const teamMemberEmail = query.teamMemberEmail || null;
52-
const routingFormResponseId = query.routingFormResponseId || null;
5370

5471
return {
5572
isTeamEvent,
@@ -62,10 +79,23 @@ export class SlotsInputService_2024_09_04 {
6279
timeZone,
6380
orgSlug,
6481
rescheduleUid,
65-
routedTeamMemberIds,
66-
skipContactOwner,
67-
teamMemberEmail,
68-
routingFormResponseId,
82+
};
83+
}
84+
85+
async transformRoutingGetSlotsQuery(
86+
query: GetSlotsInputWithRouting_2024_09_04
87+
): Promise<InternalGetSlotsQueryWithRouting> {
88+
const { routedTeamMemberIds, skipContactOwner, teamMemberEmail, routingFormResponseId, ...baseQuery } =
89+
query;
90+
91+
const baseTransformation = await this.transformGetSlotsQuery(baseQuery);
92+
93+
return {
94+
...baseTransformation,
95+
routedTeamMemberIds: routedTeamMemberIds || null,
96+
skipContactOwner: skipContactOwner || false,
97+
teamMemberEmail: teamMemberEmail || null,
98+
routingFormResponseId: routingFormResponseId ?? undefined,
6999
};
70100
}
71101

0 commit comments

Comments
 (0)