Conversation
|
@shaun-ak is attempting to deploy a commit to the cal Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughAdds team schedules support: new TeamsSchedulesModule, TeamsSchedulesService, TeamsSchedulesController (GET /v2/teams/:teamId/schedules) and an organizations-team schedules endpoint (GET /v2/organizations/:orgId/teams/:teamId/schedules). Introduces SchedulesRepository_2024_06_11.getSchedulesByUserIds and updates OrganizationsSchedulesService to use that repository. Wires TeamsSchedulesModule into EndpointsModule. Updates OrganizationsModule controllers/providers (adds OrganizationsEventTypesPrivateLinksController, removes OrganizationsConferencingController). Adds e2e tests for both team and org-team schedules. Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Graphite Automations"Add consumer team as reviewer" took an action on this PR • (08/07/25)1 reviewer was added to this PR based on Keith Williams's automation. "Add community label" took an action on this PR • (08/07/25)1 label was added to this PR based on Keith Williams's automation. "Add platform team as reviewer" took an action on this PR • (08/14/25)1 reviewer was added to this PR based on Keith Williams's automation. "Add ready-for-e2e label" took an action on this PR • (08/19/25)1 label was added to this PR based on Keith Williams's automation. |
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts
Outdated
Show resolved
Hide resolved
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts
Outdated
Show resolved
Hide resolved
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts
Outdated
Show resolved
Hide resolved
...api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.repository.ts
Outdated
Show resolved
Hide resolved
...api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts
Show resolved
Hide resolved
|
Hey @Ryukemeister , sorry I got busy with some personal stuff and was not able to address the comments in time. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (8)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.service.ts (2)
16-27: Parallelize schedule transformations and add early-returns + explicit return type
- Avoids sequential awaits to reduce latency.
- Short-circuits when there are no team users or schedules.
- Adds an explicit return type for clarity.
- async getOrganizationTeamSchedules(teamId: number, skip = 0, take = 250) { + async getOrganizationTeamSchedules( + teamId: number, + skip = 0, + take = 250 + ): Promise<ScheduleOutput_2024_06_11[]> { - const userIds = await this.teamsRepository.getTeamUsersIds(teamId); - const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); + const userIds = await this.teamsRepository.getTeamUsersIds(teamId); + if (userIds.length === 0) return []; + const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); - - const responseSchedules: ScheduleOutput_2024_06_11[] = []; - - for (const schedule of schedules) { - responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); - } - - return responseSchedules; + if (!schedules.length) return []; + return Promise.all(schedules.map((s) => this.outputSchedulesService.getResponseSchedule(s))); }
10-14: Consider reusing existing service logic to avoid duplicationThere appears to be similar logic in SchedulesService_2024_06_11.getSchedulesByUserIds(teamId,...). If feasible, delegate to that method to keep a single source of truth for team schedule assembly.
apps/api/v2/src/modules/organizations/organizations.module.ts (1)
108-109: Remove unused provider if not referencedIf the repository above is indeed unused, remove it from providers to avoid unnecessary DI registrations.
- OrganizationsTeamsSchedulesService, - OrganizationsTeamsSchedulesRepository, + OrganizationsTeamsSchedulesService,apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts (1)
19-35: Fix API version docs and avoid drift with version constants
- The controller supports versions 2024-06-11 and 2024-06-14, but the header says “Must be set to 2024-06-11”.
- Prefer using API_VERSIONS_VALUES for the controller to stay in sync with platform-wide versions.
-import { VERSION_2024_06_14, VERSION_2024_06_11 } from "@/lib/api-versions"; +import { API_VERSIONS_VALUES, VERSION_2024_06_11 } from "@/lib/api-versions"; @@ - version: [VERSION_2024_06_14, VERSION_2024_06_11], + version: API_VERSIONS_VALUES, @@ -@ApiHeader({ - name: "cal-api-version", - description: `Must be set to ${VERSION_2024_06_11}`, - example: VERSION_2024_06_11, - required: true, - schema: { - default: VERSION_2024_06_11, - }, -}) +@ApiHeader({ + name: "cal-api-version", + description: `Supported versions: ${VERSION_2024_06_11}.`, + example: VERSION_2024_06_11, + required: true, + schema: { + default: VERSION_2024_06_11, + }, +})apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (1)
38-41: Redundant IsTeamInOrg guard at method-levelThe class already applies IsTeamInOrg. The additional method-level @UseGuards(IsTeamInOrg) is redundant.
- @UseGuards(IsTeamInOrg) @Roles("TEAM_ADMIN") @PlatformPlan("ESSENTIALS") @Get("/schedules")apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.ts (3)
4-5: Reduce cross-module coupling: avoid depending on OrganizationSchedulesRepository from SchedulesServiceImporting OrganizationSchedulesRepository here leaks organization-layer concerns into the schedules domain. Prefer keeping schedule data access within SchedulesRepository and reusing it across org/team contexts to minimize circular dependencies and hidden module requirements.
Apply this in-file diff to drop the org repo dependency in favor of a schedules-level method:
-import { OrganizationSchedulesRepository } from "@/modules/organizations/schedules/organizations-schedules.repository"; import { TeamsRepository } from "@/modules/teams/teams/teams.repository";- private readonly organizationSchedulesRepository: OrganizationSchedulesRepositoryAnd in the method (see lines 81-92) replace the repository call:
- const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); + const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take);Add this helper to SchedulesRepository_2024_06_11 (outside this file), following our Prisma guidelines (select-only, explicit order for stable pagination):
// inside SchedulesRepository_2024_06_11 async getSchedulesByUserIds(userIds: number[], skip = 0, take = 250) { if (!userIds.length) return []; return this.prisma.schedule.findMany({ where: { userId: { in: userIds } }, orderBy: { id: "asc" }, skip, take, select: { id: true, name: true, isDefault: true, timeZone: true, userId: true, // add other needed fields explicitly; never use `include` }, }); }
81-81: Naming nit: method name doesn’t reflect its inputMethod takes teamId, not userIds. Consider renaming to getTeamSchedules or getSchedulesByTeamUserIds for clarity.
83-84: Large teams: consider chunking IN-queries to avoid parameter limitsIf teams can be large, some databases enforce limits on IN-list sizes or SQL packet size. Consider chunking uniqueUserIds into batches (e.g., 1k each) and merging results, or push filtering into a join in the repository.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these settings in your CodeRabbit configuration.
📒 Files selected for processing (6)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts(1 hunks)apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.module.ts(1 hunks)apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.ts(3 hunks)apps/api/v2/src/modules/organizations/organizations.module.ts(2 hunks)apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts(2 hunks)apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.service.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.tsapps/api/v2/src/modules/organizations/organizations.module.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.tsapps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.service.tsapps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.module.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.tsapps/api/v2/src/modules/organizations/organizations.module.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.tsapps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.service.tsapps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.module.ts
**/*.{service,repository}.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.service.ts
🧬 Code Graph Analysis (3)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts (5)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (1)
Controller(24-81)packages/platform/constants/api.ts (3)
VERSION_2024_06_14(56-56)VERSION_2024_06_11(57-57)SUCCESS_STATUS(9-9)apps/api/v2/src/modules/auth/guards/api-auth/api-auth.guard.ts (1)
ApiAuthGuard(7-20)apps/api/v2/src/lib/docs/headers.ts (1)
API_KEY_OR_ACCESS_TOKEN_HEADER(42-47)packages/platform/types/pagination/pagination.input.ts (1)
SkipTakePagination(26-52)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (2)
packages/platform/types/pagination/pagination.input.ts (1)
SkipTakePagination(26-52)packages/platform/constants/api.ts (1)
SUCCESS_STATUS(9-9)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.module.ts (1)
apps/api/v2/src/modules/organizations/organizations.module.ts (1)
Module(82-190)
🔇 Additional comments (6)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.service.ts (1)
20-24: Incorrect — OutputSchedulesService_2024_06_11 does not expose credential.keygetResponseSchedule in apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/output-schedules.service.ts returns only { id, ownerId, name, timeZone, availability, isDefault, overrides } and contains no credential or key fields. It's used by organizations-schedules.service.ts and organizations-teams-schedules.service.ts but still returns the same sanitized object. No change required.
Likely an incorrect or invalid review comment.
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.module.ts (2)
14-22: Wiring TeamsModule into SchedulesModule looks correctImporting TeamsModule and registering TeamsSchedulesController_2024_06_11 aligns with the new dependency on TeamsRepository.
10-10: No action needed — TeamsModule provides & exports TeamsRepositoryVerified: apps/api/v2/src/modules/teams/teams/teams.module.ts lists TeamsRepository in both providers and exports (providers at line 14; exports at line 16), so the DI requirement for SchedulesService_2024_06_11 is satisfied.
- File: apps/api/v2/src/modules/teams/teams/teams.module.ts — providers: [TeamsRepository, ...] (line 14); exports: [TeamsRepository] (line 16)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts (2)
56-61: Good controller delegation and response contractThe controller delegates to SchedulesService and returns a strongly-typed envelope. Looks consistent with platform patterns.
23-24: No additional guard required — RolesGuard already enforces team-scoped checks when :teamId is presentRolesGuard checks membership by teamId and will deny access if the caller isn't a team member; org/user-scoped guards (IsTeamInOrg / IsUserInOrgTeam) are available and used where appropriate.
- apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/teams-schedules.controller.ts — uses @UseGuards(ApiAuthGuard, PermissionsGuard, RolesGuard, PlatformPlanGuard) and @roles("TEAM_ADMIN") on the /v2/teams/:teamId/schedules route.
- apps/api/v2/src/modules/auth/guards/roles/roles.guard.ts — checkUserRoleAccess calls MembershipsRepository.findMembershipByTeamId(...) and throws if no membership; handles org/team combinations and system-admin bypass.
- apps/api/v2/src/modules/auth/guards/users/is-user-in-org-team.guard.ts and apps/api/v2/src/modules/auth/guards/teams/is-team-in-org.guard.ts — exist and are applied in org-scoped/user-scoped controllers (e.g. organizations-teams-schedules.controller.ts uses IsUserInOrgTeam for user-specific endpoints).
Action: do not add @UseGuards(IsUserInTeam) here — RolesGuard already provides the required team-scoped authorization.
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (1)
51-60: LGTM: Endpoint wiring and service usageThe endpoint properly extracts pagination, delegates to OrganizationsTeamsSchedulesService, and returns the standardized response.
apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.ts
Outdated
Show resolved
Hide resolved
| async getSchedulesByUserIds(teamId: number, skip = 0, take = 250) { | ||
| const userIds = await this.teamsRepository.getTeamUsersIds(teamId); | ||
| const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); | ||
|
|
||
| const responseSchedules = []; | ||
|
|
||
| for (const schedule of schedules) { | ||
| responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); | ||
| } | ||
|
|
||
| return responseSchedules; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Harden and streamline: explicit return type, dedupe/empty-guard userIds, and parallelize mapping
- Add the explicit return type.
- De-duplicate user IDs and short-circuit on empty teams (avoid IN () queries that may misbehave).
- Use Promise.all to transform results concurrently.
Apply this diff:
- async getSchedulesByUserIds(teamId: number, skip = 0, take = 250) {
- const userIds = await this.teamsRepository.getTeamUsersIds(teamId);
- const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take);
-
- const responseSchedules = [];
-
- for (const schedule of schedules) {
- responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule));
- }
-
- return responseSchedules;
- }
+ async getSchedulesByUserIds(
+ teamId: number,
+ skip = 0,
+ take = 250
+ ): Promise<ScheduleOutput_2024_06_11[]> {
+ const userIds = await this.teamsRepository.getTeamUsersIds(teamId);
+ const uniqueUserIds = Array.from(new Set(userIds));
+ if (uniqueUserIds.length === 0) return [];
+
+ const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(
+ uniqueUserIds,
+ skip,
+ take
+ );
+ return Promise.all(
+ schedules.map((s) => this.outputSchedulesService.getResponseSchedule(s))
+ );
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getSchedulesByUserIds(teamId: number, skip = 0, take = 250) { | |
| const userIds = await this.teamsRepository.getTeamUsersIds(teamId); | |
| const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); | |
| const responseSchedules = []; | |
| for (const schedule of schedules) { | |
| responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); | |
| } | |
| return responseSchedules; | |
| } | |
| async getSchedulesByUserIds( | |
| teamId: number, | |
| skip = 0, | |
| take = 250 | |
| ): Promise<ScheduleOutput_2024_06_11[]> { | |
| const userIds = await this.teamsRepository.getTeamUsersIds(teamId); | |
| const uniqueUserIds = Array.from(new Set(userIds)); | |
| if (uniqueUserIds.length === 0) return []; | |
| const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds( | |
| uniqueUserIds, | |
| skip, | |
| take | |
| ); | |
| return Promise.all( | |
| schedules.map((s) => this.outputSchedulesService.getResponseSchedule(s)) | |
| ); | |
| } |
🤖 Prompt for AI Agents
In
apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.ts
around lines 81 to 92, the method lacks an explicit return type, doesn't guard
against empty or duplicate team user IDs, and maps schedules serially; change
the signature to include an explicit return type (e.g.,
Promise<ResponseScheduleType[]>), after fetching userIds deduplicate them and if
the resulting array is empty return an empty array early to avoid an IN ()
query, call getSchedulesByUserIds with the deduped IDs, and use Promise.all to
concurrently map schedules to response objects via
outputSchedulesService.getResponseSchedule before returning the array.
|
|
||
| async getSchedulesByUserIds(teamId: number, skip = 0, take = 250) { | ||
| const userIds = await this.teamsRepository.getTeamUsersIds(teamId); | ||
| const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Ensure stable pagination and Prisma ‘select’-only usage in repository
- Pagination is only correct if the underlying query has a deterministic order (e.g., orderBy: { id: 'asc' }). Please confirm the repository implements ordering.
- Per guidelines, ensure the repository uses select (never include) and only selects necessary fields.
Run this script to inspect the repository method:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Locating organizations-schedules.repository.ts and getSchedulesByUserIds…"
FD_PATHS="$(fd -a -g 'organizations-schedules.repository.ts' | tr '\n' ' ')"
if [[ -z "$FD_PATHS" ]]; then
echo "organizations-schedules.repository.ts not found"; exit 1
fi
for p in $FD_PATHS; do
echo "---- File: $p ----"
rg -n "getSchedulesByUserIds\\s*\\(" -A 60 "$p"
echo
done
echo "Scanning for Prisma 'include' usage in the same file(s)…"
rg -n "include\\s*:" $FD_PATHS || echo "No 'include' found (good)"
echo "Scanning for 'orderBy' near getSchedulesByUserIds…"
for p in $FD_PATHS; do
rg -n "getSchedulesByUserIds\\s*\\(" -n "$p" | awk -F: '{print $1":"$2}' | while IFS=: read -r file line; do
start=$((line)); end=$((line+120)); sed -n "${start},${end}p" "$file" | rg -n "orderBy\\s*:"
done
doneLength of output: 1957
Ensure deterministic ordering and use Prisma select (fix required)
Verified: apps/api/v2/src/modules/organizations/schedules/organizations-schedules.repository.ts — async getSchedulesByUserIds (lines ~9–21) uses prisma.schedule.findMany with include: { availability: true } and skip/take but no orderBy.
Actionable items:
- Add a deterministic orderBy (e.g., orderBy: { id: 'asc' } or createdAt) so pagination is stable.
- Replace Prisma
includewithselect, selecting only the scalar/relation fields actually needed by the caller (use nested select for relations).
Suggested diff:
@@
- include: {
- availability: true,
- },
- skip,
- take,
+ orderBy: { id: 'asc' },
+ select: {
+ id: true,
+ userId: true,
+ // other scalar fields required by the service
+ availability: {
+ select: {
+ /* only availability fields required */
+ },
+ },
+ },
+ skip,
+ take,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const schedules = await this.organizationSchedulesRepository.getSchedulesByUserIds(userIds, skip, take); | |
| // In apps/api/v2/src/modules/organizations/schedules/organizations-schedules.repository.ts | |
| return prisma.schedule.findMany({ | |
| // ...other existing params (where, etc.) | |
| orderBy: { id: 'asc' }, | |
| select: { | |
| id: true, | |
| userId: true, | |
| // other scalar fields required by the service | |
| availability: { | |
| select: { | |
| /* only availability fields required */ | |
| }, | |
| }, | |
| }, | |
| skip, | |
| take, | |
| }); |
🤖 Prompt for AI Agents
In
apps/api/v2/src/ee/schedules/schedules_2024_06_11/services/schedules.service.ts
around line 83: the repository call getSchedulesByUserIds returns results from
prisma.findMany that currently lacks a deterministic order and uses include;
update the repository method
(apps/api/v2/src/modules/organizations/schedules/organizations-schedules.repository.ts
async getSchedulesByUserIds) to add a stable orderBy (e.g., orderBy: { id: 'asc'
} or orderBy: { createdAt: 'asc' }) so pagination is deterministic, and replace
prisma include: { availability: true } with a prisma select that only selects
the scalar fields and the specific nested availability fields the service
actually needs (use nested select for relations) to minimize data fetched and
surface only required fields to the caller.
Hey Shaunak, no worries! Since this was kind of an urgent request from an important customer I took over the PR and will finish it, and yes i've addressed the comments so no issues on that end as well, also thank you for the PR! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (4)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts (1)
233-246: Use Prismaselect(notinclude) and add deterministic ordering for paginationPer repo guidelines, avoid
includeand only select needed fields. Also, addorderByto makeskip/takepagination deterministic across calls.Apply:
- async getSchedulesByUserIds(userIds: number[], skip: number, take: number) { - return this.dbRead.prisma.schedule.findMany({ - where: { - userId: { - in: userIds, - }, - }, - include: { - availability: true, - }, - skip, - take, - }); - } + async getSchedulesByUserIds(userIds: number[], skip: number, take: number) { + return this.dbRead.prisma.schedule.findMany({ + where: { + userId: { + in: userIds, + }, + }, + select: { + id: true, + userId: true, + name: true, + timeZone: true, + availability: { + select: { + id: true, + date: true, + days: true, + startTime: true, + endTime: true, + }, + }, + }, + orderBy: [{ userId: "asc" }, { id: "asc" }], + skip, + take, + }); + }If
OutputSchedulesService_2024_06_11.getResponseSchedulerequires additional fields, adjust theselectaccordingly. To verify, run:#!/bin/bash # Inspect which schedule/availability fields are accessed in OutputSchedulesService fd -a output-schedules.service.ts rg -n -C3 '\bgetResponseSchedule\s*\(' $(fd output-schedules.service.ts) rg -n -C2 '\bschedule\.' $(fd output-schedules.service.ts) rg -n -C2 '\bavailability\.' $(fd output-schedules.service.ts)apps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.ts (1)
12-12: Good switch to SchedulesRepository_2024_06_11This addresses the earlier duplication concerns by reusing a single schedules repository across modules.
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts (2)
16-27: Add explicit return type, early-return on empty team, and parallelize mappingAlso consider delegating to a single implementation to avoid duplication with
getTeamSchedules.- async getTeamSchedulesByUserIds(teamId: number, skip = 0, take = 250) { - const userIds = await this.teamsRepository.getTeamUsersIds(teamId); - const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); - - const responseSchedules = []; - - for (const schedule of schedules) { - responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); - } - - return responseSchedules; - } + async getTeamSchedulesByUserIds( + teamId: number, + skip = 0, + take = 250 + ): Promise<ScheduleOutput_2024_06_11[]> { + return this.getTeamSchedules(teamId, skip, take); + }
29-40: DRY the two methods and parallelize transformsUnify logic in
getTeamSchedulesand letgetTeamSchedulesByUserIdsdelegate to it. Also add an explicit return type and early-return on empty teams.- async getTeamSchedules(teamId: number, skip = 0, take = 250) { - const userIds = await this.teamsRepository.getTeamUsersIds(teamId); - const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); - - const responseSchedules: ScheduleOutput_2024_06_11[] = []; - - for (const schedule of schedules) { - responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); - } - - return responseSchedules; - } + async getTeamSchedules( + teamId: number, + skip = 0, + take = 250 + ): Promise<ScheduleOutput_2024_06_11[]> { + const userIds = await this.teamsRepository.getTeamUsersIds(teamId); + if (userIds.length === 0) return []; + const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); + return Promise.all(schedules.map((s) => this.outputSchedulesService.getResponseSchedule(s))); + }
🧹 Nitpick comments (6)
apps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.ts (2)
16-21: Early-return when org has no usersAvoids an unnecessary DB call when
usersIdsis empty.- async getOrganizationSchedules(organizationId: number, skip = 0, take = 250) { + async getOrganizationSchedules(organizationId: number, skip = 0, take = 250): Promise<ScheduleOutput_2024_06_11[]> { const users = await this.usersRepository.getOrganizationUsers(organizationId); const usersIds = users.map((user) => user.id); + if (usersIds.length === 0) return [];
22-29: Parallelize mapping with Promise.all and simplify returnCurrent loop processes transforms sequentially. Use
Promise.allfor throughput and add explicit return type for clarity.- const responseSchedules: ScheduleOutput_2024_06_11[] = []; - - for (const schedule of schedules) { - responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); - } - - return responseSchedules; + return Promise.all(schedules.map((s) => this.outputSchedulesService.getResponseSchedule(s)));apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (2)
33-37: Mark injected services as readonlyConstructor-injected deps should be immutable.
- constructor( - private schedulesService: SchedulesService_2024_06_11, - - private teamsSchedulesService: TeamsSchedulesService - ) {} + constructor( + private readonly schedulesService: SchedulesService_2024_06_11, + private readonly teamsSchedulesService: TeamsSchedulesService + ) {}
39-41: Redundant IsTeamInOrg guard at method levelAlready applied at class level via
@UseGuards(..., IsTeamInOrg, ...). The method-level guard is redundant.- @UseGuards(IsTeamInOrg) @Roles("TEAM_ADMIN") @PlatformPlan("ESSENTIALS")apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts (2)
10-14: Mark injected services as readonlyKeep DI fields immutable for clarity and safety.
- constructor( - private readonly teamsRepository: TeamsRepository, - private readonly schedulesRepository: SchedulesRepository_2024_06_11, - private readonly outputSchedulesService: OutputSchedulesService_2024_06_11 - ) {} + constructor( + private readonly teamsRepository: TeamsRepository, + private readonly schedulesRepository: SchedulesRepository_2024_06_11, + private readonly outputSchedulesService: OutputSchedulesService_2024_06_11 + ) {}
16-40: Naming consistency: method names don’t reflect parameters
getTeamSchedulesByUserIdstakes ateamId, not userIds. Consider renaming for clarity (e.g., keep onlygetTeamSchedules) and update controllers accordingly in a follow-up.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (8)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts(1 hunks)apps/api/v2/src/modules/organizations/organizations.module.ts(3 hunks)apps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.ts(2 hunks)apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts(2 hunks)apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts(4 hunks)apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.e2e-spec.ts(1 hunks)apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts(1 hunks)apps/api/v2/src/modules/teams/schedules/teams-schedules.module.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- apps/api/v2/src/modules/teams/schedules/teams-schedules.module.ts
- apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.e2e-spec.ts
- apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts
- apps/api/v2/src/modules/organizations/organizations.module.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{service,repository}.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.tsapps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.tsapps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.ts
**/*.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.tsapps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.tsapps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.tsapps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.tsapps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.tsapps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts
🧠 Learnings (1)
📚 Learning: 2025-07-28T11:50:23.946Z
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: Applies to **/*.ts : For Prisma queries, only select data you need; never use `include`, always use `select`
Applied to files:
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts
🧬 Code Graph Analysis (2)
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts (2)
apps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.ts (1)
Injectable(8-30)apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts (1)
Injectable(25-247)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (2)
packages/platform/types/pagination/pagination.input.ts (1)
SkipTakePagination(26-52)packages/platform/constants/api.ts (1)
SUCCESS_STATUS(9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Tests / Unit
🔇 Additional comments (2)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts (1)
233-246: Centralizing schedule-by-userIds in a single repository is the right callGood consolidation; reduces duplication across org/teams flows and makes future changes easier to maintain.
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.controller.ts (1)
42-56: Endpoint shape and pagination usage look goodRoute, guards, and
SkipTakePaginationintegration are consistent with v2 patterns.
| private readonly outputSchedulesService: OutputSchedulesService_2024_06_11 | ||
| ) {} | ||
|
|
||
| async getTeamSchedulesByUserIds(teamId: number, skip = 0, take = 250) { |
There was a problem hiding this comment.
Why do we have getTeamSchedulesByUserIds and getTeamSchedules - their function body looks the same.
I assume we can get rid of getTeamSchedulesByUserIds (it also is named by user ids but does not take any user ids as a parameter so has an inaccurate name).
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts (1)
17-24: Resolved earlier feedback: RolesGuard is now correctly applied and @roles is enforcedClass-level RolesGuard combined with method-level @roles("TEAM_ADMIN") addresses the earlier gap where roles weren’t being checked.
🧹 Nitpick comments (4)
apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts (2)
24-24: Nit: Prefer @get() over @get("/")Trailing slash is unnecessary and can be omitted for consistency with NestJS patterns.
- @Get("/") + @Get()
25-31: Add Swagger success response decoratorThe
getTeamSchedulesendpoint is missing an explicit success response schema. Since there’s noApiSuccessResponsehelper in the repo, use Nest’s built-in@ApiOkResponseto document the output DTO:
- File:
apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts- Changes:
import { ApiOperation, + ApiOkResponse, } from "@nestjs/swagger"; @ApiOperation({ summary: "Get all team member schedules", }) + @ApiOkResponse({ type: GetSchedulesOutput_2024_06_11 }) async getTeamSchedules( @Param("teamId", ParseIntPipe) teamId: number, @Query() queryParams: SkipTakePagination ): Promise<GetSchedulesOutput_2024_06_11> {This will ensure the response schema appears correctly in Swagger UI.
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts (2)
16-27: Add explicit return type, early-return on empty team, and parallelize mappingThis reduces unnecessary DB calls for empty teams and speeds up the per-schedule transformation.
- async getTeamSchedules(teamId: number, skip = 0, take = 250) { + async getTeamSchedules( + teamId: number, + skip = 0, + take = 250 + ): Promise<ScheduleOutput_2024_06_11[]> { const userIds = await this.teamsRepository.getTeamUsersIds(teamId); - const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); - - const responseSchedules: ScheduleOutput_2024_06_11[] = []; - - for (const schedule of schedules) { - responseSchedules.push(await this.outputSchedulesService.getResponseSchedule(schedule)); - } - - return responseSchedules; + if (!userIds.length) return []; + const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); + return Promise.all(schedules.map((s) => this.outputSchedulesService.getResponseSchedule(s))); }
16-16: Nit: avoid drift between service defaults and SkipTakePagination defaultsController always passes validated skip/take from SkipTakePagination, so these default values are effectively unused here and can drift from the global defaults. Consider removing the defaults from the service signature or deriving them from a shared constant.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts(1 hunks)apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{service,repository}.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts
**/*.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.tsapps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.tsapps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts
🧠 Learnings (1)
📚 Learning: 2025-07-28T11:50:23.946Z
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: Applies to **/*.ts : For Prisma queries, only select data you need; never use `include`, always use `select`
Applied to files:
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts
🧬 Code Graph Analysis (2)
apps/api/v2/src/modules/teams/schedules/services/teams-schedules.service.ts (2)
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts (1)
Injectable(25-247)apps/api/v2/src/modules/organizations/schedules/services/organizations-schedules.service.ts (1)
Injectable(8-30)
apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts (4)
apps/api/v2/src/modules/auth/guards/api-auth/api-auth.guard.ts (1)
ApiAuthGuard(7-20)apps/api/v2/src/lib/docs/headers.ts (1)
API_KEY_OR_ACCESS_TOKEN_HEADER(42-47)packages/platform/types/pagination/pagination.input.ts (1)
SkipTakePagination(26-52)packages/platform/constants/api.ts (1)
SUCCESS_STATUS(9-9)
🔇 Additional comments (1)
apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts (1)
17-19: Evaluate Plan Gating on TeamsSchedulesControllerThe
TeamsSchedulesController(apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.controller.ts) currently only appliesApiAuthGuardandRolesGuard, whereas all other “schedules” endpoints enforcePlatformPlanGuardfor paid-feature gating:
organizations-teams-schedules.controller.tsorganizations-schedules.controller.tsIf team schedules are a paid feature, add
PlatformPlanGuardfor consistency:+import { PlatformPlanGuard } from "@/modules/auth/guards/billing/platform-plan.guard"; @@ -@UseGuards(ApiAuthGuard, RolesGuard) +@UseGuards(ApiAuthGuard, RolesGuard, PlatformPlanGuard)Verify whether this endpoint should be behind a paid plan and, if so, include
PlatformPlanGuardaccordingly.
|
|
||
| async getTeamSchedules(teamId: number, skip = 0, take = 250) { | ||
| const userIds = await this.teamsRepository.getTeamUsersIds(teamId); | ||
| const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Prisma: switch repository to select-only (no include) per guidelines
The called repository method currently uses include: { availability: true }. Repo guideline: only select required fields; never use include. Update SchedulesRepository_2024_06_11.getSchedulesByUserIds accordingly.
To verify current usage:
Suggested change in apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts:
async getSchedulesByUserIds(userIds: number[], skip: number, take: number) {
return this.dbRead.prisma.schedule.findMany({
where: {
userId: {
in: userIds,
},
},
- include: {
- availability: true,
- },
+ select: {
+ id: true,
+ userId: true,
+ name: true,
+ timeZone: true,
+ availability: {
+ select: {
+ id: true,
+ date: true,
+ startTime: true,
+ endTime: true,
+ days: true,
+ },
+ },
+ },
skip,
take,
});
}Adjust fields to exactly what OutputSchedulesService_2024_06_11 requires.
🏁 Script executed:
#!/bin/bash
# Confirm include usage in schedules repository
rg -n 'class SchedulesRepository_2024_06_11|getSchedulesByUserIds|include\s*:' apps/api/v2/src/ee/schedules/schedules_2024_06_11 -n -C3Length of output: 4949
Prisma: replace include with explicit select in getSchedulesByUserIds
The getSchedulesByUserIds method in
apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts
currently uses an include on the read query. Per our Prisma guideline—only select the fields you need; never use include on read operations—please refactor this to use a select block instead:
--- a/apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts
+++ b/apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts
@@ async getSchedulesByUserIds(userIds: number[], skip: number, take: number) {
- include: {
- availability: true,
- },
+ select: {
+ id: true,
+ userId: true,
+ name: true,
+ timeZone: true,
+ availability: {
+ select: {
+ id: true,
+ date: true,
+ startTime: true,
+ endTime: true,
+ days: true,
+ },
+ },
+ },Adjust the selected fields to exactly match what OutputSchedulesService_2024_06_11 consumes.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const schedules = await this.schedulesRepository.getSchedulesByUserIds(userIds, skip, take); | |
| // apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts | |
| async getSchedulesByUserIds(userIds: number[], skip: number, take: number) { | |
| return this.prisma.schedule.findMany({ | |
| where: { userId: { in: userIds } }, | |
| skip, | |
| take, | |
| - include: { | |
| - availability: true, | |
| select: { | |
| id: true, | |
| userId: true, | |
| name: true, | |
| timeZone: true, | |
| availability: { | |
| select: { | |
| id: true, | |
| date: true, | |
| startTime: true, | |
| endTime: true, | |
| days: true, | |
| }, | |
| }, | |
| }, | |
| }); | |
| } |
E2E results are ready! |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
f8f5b4a
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts (3)
237-239: Good: asserting exact count (2) addresses earlier feedbackSwitching from “> 0” to an exact length of 2 tightens the contract and aligns with the test setup (admin + member).
240-245: Good: replaced brittle filter()[0] with find() and existence checksUsing find() and asserting definedness prevents undefined access and produces clearer failures. Thanks for addressing the earlier comment.
250-253: Fix incorrect variable in the last assertion (timeZone)The final assertion compares userOneSchedule?.timeZone to user2Schedule.timeZone. It should use userTwoSchedule to validate the second user’s schedule. With both schedules sharing the same time zone, this bug wouldn’t fail, so please correct it.
Apply this diff:
- expect(userOneSchedule?.timeZone).toEqual(user2Schedule.timeZone); + expect(userTwoSchedule?.timeZone).toEqual(user2Schedule.timeZone);
🧹 Nitpick comments (1)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts (1)
79-88: Strengthen assertions by using different time zones for each userBoth schedules use the same time zone ("America/New_York"), which can mask variable-mixup bugs in assertions. Use a different time zone for user2 to make the test robust against mistakes (see fix suggested below for the final assertion).
Example (outside this hunk): set user2’s schedule to a different time zone:
user2Schedule = await scheduleRepositoryFixture.create({ user: { connect: { id: user2.id } }, name: `organizations-teams-schedules-user2-schedule-${randomString()}`, timeZone: "Europe/London", });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts(4 hunks)apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.e2e-spec.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/api/v2/src/modules/teams/schedules/controllers/teams-schedules.e2e-spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts
🧬 Code Graph Analysis (1)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts (2)
apps/api/v2/test/utils/randomString.ts (1)
randomString(3-6)packages/platform/constants/api.ts (1)
SUCCESS_STATUS(9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (2)
apps/api/v2/src/modules/organizations/teams/schedules/organizations-teams-schedules.e2e-spec.ts (2)
21-21: Type import aligns with aggregator response shapeBringing in GetSchedulesOutput_2024_06_11 for the team-aggregate response is correct and improves type safety in the test.
41-42: Explicit schedule fixture typing is clearDeclaring userSchedule and user2Schedule as Schedule keeps the fixtures self-documenting and prevents accidental misuse.
What does this PR do?
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
This can be tested in api v2