Skip to content

Commit cc19a81

Browse files
chore: deprecate platform libraries 0.0.2 (calcom#22149)
* chore: deprecate platform libraries 0.0.2 * fixup! chore: deprecate platform libraries 0.0.2 * Update packages/lib/server/repository/schedule.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * Update apps/api/v2/src/ee/schedules/schedules_2024_04_15/services/schedules.service.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * chore: bump platform libs * Update apps/api/v2/src/ee/event-types/event-types_2024_04_15/controllers/event-types.controller.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * chore: bump platform libs --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
1 parent 67032dd commit cc19a81

9 files changed

Lines changed: 3326 additions & 862 deletions

File tree

apps/api/v2/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
"@axiomhq/winston": "^1.2.0",
3939
"@calcom/platform-constants": "*",
4040
"@calcom/platform-enums": "*",
41-
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.233",
42-
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2",
41+
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.236",
4342
"@calcom/platform-types": "*",
4443
"@calcom/platform-utils": "*",
4544
"@calcom/prisma": "*",

apps/api/v2/src/ee/event-types/event-types_2024_04_15/controllers/event-types.controller.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { GetUser } from "@/modules/auth/decorators/get-user/get-user.decorator";
1818
import { Permissions } from "@/modules/auth/decorators/permissions/permissions.decorator";
1919
import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard";
2020
import { PermissionsGuard } from "@/modules/auth/guards/permissions/permissions.guard";
21+
import { OrganizationsRepository } from "@/modules/organizations/index/organizations.repository";
2122
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
2223
import { UserWithProfile } from "@/modules/users/users.repository";
2324
import {
@@ -33,13 +34,19 @@ import {
3334
HttpStatus,
3435
Delete,
3536
Query,
37+
Headers,
3638
InternalServerErrorException,
3739
ParseIntPipe,
3840
} from "@nestjs/common";
3941
import { ApiExcludeController as DocsExcludeController } from "@nestjs/swagger";
4042

41-
import { EVENT_TYPE_READ, EVENT_TYPE_WRITE, SUCCESS_STATUS } from "@calcom/platform-constants";
42-
import { getPublicEvent, getEventTypesByViewer } from "@calcom/platform-libraries-0.0.2";
43+
import {
44+
EVENT_TYPE_READ,
45+
EVENT_TYPE_WRITE,
46+
SUCCESS_STATUS,
47+
X_CAL_CLIENT_ID,
48+
} from "@calcom/platform-constants";
49+
import { getPublicEvent, getEventTypesByViewer } from "@calcom/platform-libraries/event-types";
4350
import { PrismaClient } from "@calcom/prisma";
4451

4552
@Controller({
@@ -51,7 +58,8 @@ import { PrismaClient } from "@calcom/prisma";
5158
export class EventTypesController_2024_04_15 {
5259
constructor(
5360
private readonly eventTypesService: EventTypesService_2024_04_15,
54-
private readonly prismaReadService: PrismaReadService
61+
private readonly prismaReadService: PrismaReadService,
62+
private readonly organizationsRepository: OrganizationsRepository
5563
) {}
5664

5765
@Post("/")
@@ -109,19 +117,30 @@ export class EventTypesController_2024_04_15 {
109117
async getPublicEventType(
110118
@Param("username") username: string,
111119
@Param("eventSlug") eventSlug: string,
112-
@Query() queryParams: GetPublicEventTypeQueryParams_2024_04_15
120+
@Query() queryParams: GetPublicEventTypeQueryParams_2024_04_15,
121+
@Headers(X_CAL_CLIENT_ID) clientId?: string
113122
): Promise<GetEventTypePublicOutput> {
114123
try {
124+
let orgSlug = queryParams.org;
125+
126+
if (clientId && !orgSlug && username.includes(`-${clientId}`)) {
127+
const org = await this.organizationsRepository.findTeamIdAndSlugFromClientId(clientId).catch(() => null);
128+
if (org) {
129+
orgSlug = org.slug;
130+
}
131+
}
132+
115133
const event = await getPublicEvent(
116134
username.toLowerCase(),
117135
eventSlug,
118136
queryParams.isTeamEvent,
119-
queryParams.org || null,
137+
orgSlug ?? null,
120138
this.prismaReadService.prisma as unknown as PrismaClient,
121139
// We should be fine allowing unpublished orgs events to be servable through platform because Platform access is behind license
122140
// If there is ever a need to restrict this, we can introduce a new query param `fromRedirectOfNonOrgLink`
123141
true
124142
);
143+
125144
return {
126145
data: event,
127146
status: SUCCESS_STATUS,

apps/api/v2/src/ee/event-types/event-types_2024_04_15/event-types.module.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@ import { EventTypesController_2024_04_15 } from "@/ee/event-types/event-types_20
22
import { EventTypesRepository_2024_04_15 } from "@/ee/event-types/event-types_2024_04_15/event-types.repository";
33
import { EventTypesService_2024_04_15 } from "@/ee/event-types/event-types_2024_04_15/services/event-types.service";
44
import { MembershipsModule } from "@/modules/memberships/memberships.module";
5+
import { OrganizationsModule } from "@/modules/organizations/organizations.module";
56
import { PrismaModule } from "@/modules/prisma/prisma.module";
67
import { SelectedCalendarsModule } from "@/modules/selected-calendars/selected-calendars.module";
78
import { TokensModule } from "@/modules/tokens/tokens.module";
89
import { UsersModule } from "@/modules/users/users.module";
910
import { Module } from "@nestjs/common";
1011

1112
@Module({
12-
imports: [PrismaModule, MembershipsModule, TokensModule, UsersModule, SelectedCalendarsModule],
13+
imports: [
14+
PrismaModule,
15+
MembershipsModule,
16+
TokensModule,
17+
UsersModule,
18+
SelectedCalendarsModule,
19+
OrganizationsModule,
20+
],
1321
providers: [EventTypesRepository_2024_04_15, EventTypesService_2024_04_15],
1422
controllers: [EventTypesController_2024_04_15],
1523
exports: [EventTypesService_2024_04_15, EventTypesRepository_2024_04_15],

apps/api/v2/src/ee/schedules/schedules_2024_04_15/controllers/schedules.controller.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ export class SchedulesController_2024_04_15 {
4646
@Body() bodySchedule: CreateScheduleInput_2024_04_15
4747
): Promise<CreateScheduleOutput_2024_04_15> {
4848
const schedule = await this.schedulesService.createUserSchedule(user.id, bodySchedule);
49-
const scheduleFormatted = await this.schedulesService.formatScheduleForAtom(user, schedule);
5049

5150
return {
5251
status: SUCCESS_STATUS,
53-
data: scheduleFormatted,
52+
data: schedule,
5453
};
5554
}
5655

@@ -60,13 +59,10 @@ export class SchedulesController_2024_04_15 {
6059
@GetUser() user: UserWithProfile
6160
): Promise<GetDefaultScheduleOutput_2024_04_15 | null> {
6261
const schedule = await this.schedulesService.getUserScheduleDefault(user.id);
63-
const scheduleFormatted = schedule
64-
? await this.schedulesService.formatScheduleForAtom(user, schedule)
65-
: null;
6662

6763
return {
6864
status: SUCCESS_STATUS,
69-
data: scheduleFormatted,
65+
data: schedule,
7066
};
7167
}
7268

@@ -77,23 +73,25 @@ export class SchedulesController_2024_04_15 {
7773
@Param("scheduleId") scheduleId: number
7874
): Promise<GetScheduleOutput_2024_04_15> {
7975
const schedule = await this.schedulesService.getUserSchedule(user.id, scheduleId);
80-
const scheduleFormatted = await this.schedulesService.formatScheduleForAtom(user, schedule);
8176

8277
return {
8378
status: SUCCESS_STATUS,
84-
data: scheduleFormatted,
79+
data: schedule,
8580
};
8681
}
8782

8883
@Get("/")
8984
@Permissions([SCHEDULE_READ])
9085
async getSchedules(@GetUser() user: UserWithProfile): Promise<GetSchedulesOutput_2024_04_15> {
91-
const schedules = await this.schedulesService.getUserSchedules(user.id);
92-
const schedulesFormatted = await this.schedulesService.formatSchedulesForAtom(user, schedules);
86+
const schedules = await this.schedulesService.getUserSchedules(
87+
user.id,
88+
user.timeZone,
89+
user.defaultScheduleId
90+
);
9391

9492
return {
9593
status: SUCCESS_STATUS,
96-
data: schedulesFormatted,
94+
data: schedules,
9795
};
9896
}
9997

apps/api/v2/src/ee/schedules/schedules_2024_04_15/services/schedules.service.ts

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
import { CreateAvailabilityInput_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/inputs/create-availability.input";
22
import { CreateScheduleInput_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/inputs/create-schedule.input";
3-
import { ScheduleOutput } from "@/ee/schedules/schedules_2024_04_15/outputs/schedule.output";
43
import { SchedulesRepository_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/schedules.repository";
4+
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
55
import { UserWithProfile, UsersRepository } from "@/modules/users/users.repository";
66
import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
77
import { Schedule } from "@prisma/client";
8-
import { User } from "@prisma/client";
9-
10-
import type { ScheduleWithAvailabilities } from "@calcom/platform-libraries-0.0.2";
11-
import { updateScheduleHandler } from "@calcom/platform-libraries-0.0.2";
12-
import {
13-
transformWorkingHoursForClient,
14-
transformAvailabilityForClient,
15-
transformDateOverridesForClient,
16-
} from "@calcom/platform-libraries-0.0.2";
8+
9+
import { updateSchedule } from "@calcom/platform-libraries/schedules";
10+
import { ScheduleRepository } from "@calcom/platform-libraries/schedules";
1711
import { UpdateScheduleInput_2024_04_15 } from "@calcom/platform-types";
12+
import { PrismaClient } from "@calcom/prisma";
1813

1914
@Injectable()
2015
export class SchedulesService_2024_04_15 {
2116
constructor(
2217
private readonly schedulesRepository: SchedulesRepository_2024_04_15,
23-
private readonly usersRepository: UsersRepository
18+
private readonly usersRepository: UsersRepository,
19+
private readonly dbWrite: PrismaWriteService
2420
) {}
2521

2622
async createUserDefaultSchedule(userId: number, timeZone: string) {
@@ -48,19 +44,39 @@ export class SchedulesService_2024_04_15 {
4844
await this.usersRepository.setDefaultSchedule(userId, createdSchedule.id);
4945
}
5046

51-
return createdSchedule;
47+
const formattedSchedule = await this.getUserSchedule(userId, createdSchedule.id);
48+
49+
return formattedSchedule;
5250
}
5351

5452
async getUserScheduleDefault(userId: number) {
5553
const user = await this.usersRepository.findById(userId);
5654

5755
if (!user?.defaultScheduleId) return null;
5856

59-
return this.schedulesRepository.getScheduleById(user.defaultScheduleId);
57+
return await ScheduleRepository.findDetailedScheduleById({
58+
scheduleId: user.defaultScheduleId,
59+
isManagedEventType: undefined,
60+
userId,
61+
timeZone: user.timeZone,
62+
defaultScheduleId: user.defaultScheduleId,
63+
});
6064
}
6165

6266
async getUserSchedule(userId: number, scheduleId: number) {
63-
const existingSchedule = await this.schedulesRepository.getScheduleById(scheduleId);
67+
const user = await this.usersRepository.findById(userId);
68+
69+
if (!user) {
70+
throw new NotFoundException(`User with ID=${userId} does not exist.`);
71+
}
72+
73+
const existingSchedule = await ScheduleRepository.findDetailedScheduleById({
74+
scheduleId: scheduleId,
75+
isManagedEventType: undefined,
76+
userId,
77+
timeZone: user.timeZone,
78+
defaultScheduleId: user.defaultScheduleId,
79+
});
6480

6581
if (!existingSchedule) {
6682
throw new NotFoundException(`Schedule with ID=${scheduleId} does not exist.`);
@@ -71,8 +87,8 @@ export class SchedulesService_2024_04_15 {
7187
return existingSchedule;
7288
}
7389

74-
async getUserSchedules(userId: number) {
75-
return this.schedulesRepository.getSchedulesByUserId(userId);
90+
async getUserSchedules(userId: number, timeZone: string, defaultScheduleId: number | null) {
91+
return ScheduleRepository.findManyDetailedScheduleByUserId({ userId, timeZone, defaultScheduleId });
7692
}
7793

7894
async updateUserSchedule(
@@ -89,20 +105,23 @@ export class SchedulesService_2024_04_15 {
89105
this.checkUserOwnsSchedule(user.id, existingSchedule);
90106

91107
const schedule = await this.getUserSchedule(user.id, Number(scheduleId));
92-
const scheduleFormatted = await this.formatScheduleForAtom(user, schedule);
93108

94109
if (!bodySchedule.schedule) {
95110
// note(Lauris): When updating an availability in cal web app, lets say only its name, also
96111
// the schedule is sent and then passed to the update handler. Notably, availability is passed too
97112
// and they have same shape, so to match shapes I attach "scheduleFormatted.availability" to reflect
98113
// schedule that would be passed by the web app. If we don't, then updating schedule name will erase
99114
// schedule.
100-
bodySchedule.schedule = scheduleFormatted.availability;
115+
bodySchedule.schedule = schedule.availability;
101116
}
102117

103-
return updateScheduleHandler({
104-
input: { scheduleId: Number(scheduleId), ...bodySchedule },
105-
ctx: { user },
118+
return updateSchedule({
119+
input: {
120+
scheduleId: Number(scheduleId),
121+
...bodySchedule,
122+
},
123+
user,
124+
prisma: this.dbWrite.prisma as unknown as PrismaClient,
106125
});
107126
}
108127

@@ -118,44 +137,6 @@ export class SchedulesService_2024_04_15 {
118137
return this.schedulesRepository.deleteScheduleById(scheduleId);
119138
}
120139

121-
async formatScheduleForAtom(user: User, schedule: ScheduleWithAvailabilities): Promise<ScheduleOutput> {
122-
const usersSchedulesCount = await this.schedulesRepository.getUserSchedulesCount(user.id);
123-
return this.transformScheduleForAtom(schedule, usersSchedulesCount, user);
124-
}
125-
126-
async formatSchedulesForAtom(
127-
user: User,
128-
schedules: ScheduleWithAvailabilities[]
129-
): Promise<ScheduleOutput[]> {
130-
const usersSchedulesCount = await this.schedulesRepository.getUserSchedulesCount(user.id);
131-
return Promise.all(
132-
schedules.map((schedule) => this.transformScheduleForAtom(schedule, usersSchedulesCount, user))
133-
);
134-
}
135-
136-
async transformScheduleForAtom(
137-
schedule: ScheduleWithAvailabilities,
138-
userSchedulesCount: number,
139-
user: Pick<User, "id" | "defaultScheduleId" | "timeZone">
140-
): Promise<ScheduleOutput> {
141-
const timeZone = schedule.timeZone || user.timeZone;
142-
const defaultSchedule = await this.getUserScheduleDefault(user.id);
143-
144-
return {
145-
id: schedule.id,
146-
name: schedule.name,
147-
isManaged: schedule.userId !== user.id,
148-
workingHours: transformWorkingHoursForClient(schedule),
149-
schedule: schedule.availability,
150-
availability: transformAvailabilityForClient(schedule),
151-
timeZone,
152-
dateOverrides: transformDateOverridesForClient(schedule, timeZone),
153-
isDefault: defaultSchedule?.id === schedule.id,
154-
isLastSchedule: userSchedulesCount <= 1,
155-
readOnly: schedule.userId !== user.id,
156-
};
157-
}
158-
159140
checkUserOwnsSchedule(userId: number, schedule: Pick<Schedule, "id" | "userId">) {
160141
if (userId !== schedule.userId) {
161142
throw new ForbiddenException(`User with ID=${userId} does not own schedule with ID=${schedule.id}`);

apps/api/v2/src/modules/organizations/index/organizations.repository.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class OrganizationsRepository {
6969
return id;
7070
}
7171

72-
async findTeamIdFromClientId(clientId: string) {
72+
async findTeamIdAndSlugFromClientId(clientId: string) {
7373
return this.dbRead.prisma.team.findFirstOrThrow({
7474
where: {
7575
platformOAuthClient: {
@@ -80,6 +80,7 @@ export class OrganizationsRepository {
8080
},
8181
select: {
8282
id: true,
83+
slug: true,
8384
},
8485
});
8586
}

0 commit comments

Comments
 (0)