Skip to content

Comments

fix: including Prisma.sql for Prisma v6 upgrade#23775

Merged
emrysal merged 1 commit intomainfrom
fix/prisma-v6-query-raw
Sep 11, 2025
Merged

fix: including Prisma.sql for Prisma v6 upgrade#23775
emrysal merged 1 commit intomainfrom
fix/prisma-v6-query-raw

Conversation

@eunjae-lee
Copy link
Contributor

@eunjae-lee eunjae-lee commented Sep 11, 2025

What does this PR do?

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

  • Show screen recordings of the issue or feature.
  • Demonstrate how to reproduce the issue, the behavior before and after the change.

Image Demo (if applicable):

  • Add side-by-side screenshots of the original and updated change.
  • Highlight any significant change(s).

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

Prompt used to fix this problem

After upgrading Prisma to v6, things are broken. Fix all the $queryRaw usages from

    const bookingsFromSelected = await this.prisma.$queryRaw<
      Array<{
        eventTypeId: number;
        count: number;
      }>
    >`
      SELECT
        "eventTypeId",
        COUNT(id)::int as count
      FROM "BookingTimeStatusDenormalized"
      WHERE ${baseConditions} AND "eventTypeId" IS NOT NULL
      GROUP BY "eventTypeId"
      ORDER BY count DESC
      LIMIT 10
    `;

to

    const query = Prisma.sql`
      SELECT
        "eventTypeId",
        COUNT(id)::int as count
      FROM "BookingTimeStatusDenormalized"
      WHERE ${baseConditions} AND "eventTypeId" IS NOT NULL
      GROUP BY "eventTypeId"
      ORDER BY count DESC
      LIMIT 10
    `;
    

    const bookingsFromSelected = await this.prisma.$queryRaw<
      Array<{
        eventTypeId: number;
        count: number;
      }>
    >(query);

We're basically extracting the whole query as Prisma.sql, and pass the query to queryRaw.

But this needs to be fixed only when the $queryRaw..... includes a parameter that is an instance of Prisma.sql. So no need to fix something like this, because the parameterized values (someString) is primitive values, and not an instance of Prisma.sql....

    const bookingsFromSelected = await this.prisma.$queryRaw<
      Array<{
        eventTypeId: number;
        count: number;
      }>
    >`
      SELECT
        "eventTypeId",
        COUNT(id)::int as count
      FROM "BookingTimeStatusDenormalized"
      WHERE "eventTypeId" IS NOT NULL OR "status" = ${someString}
      GROUP BY "eventTypeId"
      ORDER BY count DESC
      LIMIT 10
    `;

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Walkthrough

This change refactors SQL construction across InsightsBookingBaseService.ts and InsightsRoutingBaseService.ts by replacing inline prisma.$queryRaw... templates with Prisma.sql fragments assigned to local variables (e.g., query, totalCountQuery, dataQuery, usersQuerySql, periodStatsQuery, statsQuerySql) and executed via prisma.$queryRaw(query). In InsightsBookingBaseService, getBookingsByHourStats adds an explicit AND "status" = 'accepted' filter. In InsightsRoutingBaseService, data-mapping includes guarded updates and filters non-null dateRange entries. All affected methods retain their signatures and return shapes, with no exported/public API changes.

Possibly related PRs

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "fix: including Prisma.sql for Prisma v6 upgrade" clearly reflects the primary change in the diff—replacing tagged-template $queryRaw usages with Prisma.sql for a Prisma v6 upgrade—and matches the summaries for InsightsBookingBaseService and InsightsRoutingBaseService, so it is directly related and concise enough for history scanning.
Description Check ✅ Passed The PR description documents the motivation, shows before/after examples of the $queryRaw → Prisma.sql conversion, and includes testing guidance and checklist items, which align with the raw_summary and pr_objectives; therefore it is related to the changeset and passes this lenient check.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/prisma-v6-query-raw

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@keithwillcode keithwillcode added consumer core area: core, team members only labels Sep 11, 2025
@eunjae-lee eunjae-lee marked this pull request as ready for review September 11, 2025 17:13
@graphite-app graphite-app bot requested a review from a team September 11, 2025 17:14
@dosubot dosubot bot added the 🐛 bug Something isn't working label Sep 11, 2025
Copy link
Contributor

@emrysal emrysal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one man! oversight of a merge 🙏

@eunjae-lee eunjae-lee enabled auto-merge (squash) September 11, 2025 17:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/lib/server/service/InsightsBookingBaseService.ts (3)

171-181: Type mismatch: hour should be number, not string.

You cast to ::int in SQL but type hour: string in TS. Tighten typing to prevent unnecessary Number(...) conversions.

-    const results = await this.prisma.$queryRaw<
-      Array<{
-        hour: string;
-        count: number;
-      }>
-    >(query);
+    const results = await this.prisma.$queryRaw<
+      Array<{
+        hour: number;
+        count: number;
+      }>
+    >(query);

Also applies to: 182-187


456-461: CSV query refactor looks good; two small checks.

  • Selecting explicit columns: great. Consider aligning uid nullability with the view (schema says non-null). If uid can be null, update bookingDataSchema or remove the filter-on-null path.
  • Minor: you can drop the interim array type’s nullable uid if it’s guaranteed.

Also applies to: 462-462, 467-488, 490-509


1083-1115: Cast avg_rating to float for consistency with decoder.

AVG(...) without cast may come back as string (numeric) from pg. Align with other queries that use ::float.

-          AVG(CASE WHEN "rating" IS NOT NULL THEN "rating" END) as avg_rating,
+          AVG(CASE WHEN "rating" IS NOT NULL THEN "rating" END)::float as avg_rating,

Also applies to: 1116-1129

packages/lib/server/service/InsightsRoutingBaseService.ts (1)

186-206: Safer status check: cast enum to text before string comparison.

If bookingStatus is an enum, compare via ::text to avoid implicit casts.

-        COUNT(CASE WHEN "bookingStatus" NOT IN ('cancelled', 'rejected') THEN 1 END) as "acceptedBookings"
+        COUNT(CASE WHEN "bookingStatus"::text NOT IN ('cancelled', 'rejected') THEN 1 END) as "acceptedBookings"

Also applies to: 208-216

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c28eb90 and 6a6a7f5.

📒 Files selected for processing (2)
  • packages/lib/server/service/InsightsBookingBaseService.ts (20 hunks)
  • packages/lib/server/service/InsightsRoutingBaseService.ts (13 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*Service.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Service files must include Service suffix, use PascalCase matching exported class, and avoid generic names (e.g., MembershipService.ts)

Files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
  • packages/lib/server/service/InsightsRoutingBaseService.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
  • packages/lib/server/service/InsightsRoutingBaseService.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:

  • packages/lib/server/service/InsightsBookingBaseService.ts
  • packages/lib/server/service/InsightsRoutingBaseService.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
  • packages/lib/server/service/InsightsRoutingBaseService.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: bandhan-majumder
PR: calcom/cal.com#23192
File: packages/lib/server/service/InsightsBookingBaseService.ts:814-816
Timestamp: 2025-08-22T16:38:00.225Z
Learning: In the InsightsBookingBaseService (packages/lib/server/service/InsightsBookingBaseService.ts), when filtering for "accepted" bookings in getMembersStatsWithCount(), using `endTime <= now()` in the SQL condition should be avoided as it conflicts with existing date filtering logic. The components already handle completion filtering by setting `endDate: currentTime` in their query parameters, making additional SQL-level endTime filtering unnecessary and potentially problematic.
📚 Learning: 2025-08-22T16:38:00.225Z
Learnt from: bandhan-majumder
PR: calcom/cal.com#23192
File: packages/lib/server/service/InsightsBookingBaseService.ts:814-816
Timestamp: 2025-08-22T16:38:00.225Z
Learning: In the InsightsBookingBaseService (packages/lib/server/service/InsightsBookingBaseService.ts), when filtering for "accepted" bookings in getMembersStatsWithCount(), using `endTime <= now()` in the SQL condition should be avoided as it conflicts with existing date filtering logic. The components already handle completion filtering by setting `endDate: currentTime` in their query parameters, making additional SQL-level endTime filtering unnecessary and potentially problematic.

Applied to files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.

Applied to files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
📚 Learning: 2025-07-24T08:39:06.185Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22702
File: packages/lib/server/service/insightsBooking.ts:120-124
Timestamp: 2025-07-24T08:39:06.185Z
Learning: In the InsightsBookingService (packages/lib/server/service/insightsBooking.ts), the constructor stores null for invalid options or filters but this is handled safely through null checks in buildFilterConditions() and buildAuthorizationConditions() methods. The service uses defensive programming to return safe fallback conditions (null or NOTHING_CONDITION) rather than throwing errors on invalid inputs.

Applied to files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.

Applied to files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.

Applied to files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.

Applied to files:

  • packages/lib/server/service/InsightsBookingBaseService.ts
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (17)
packages/lib/server/service/InsightsBookingBaseService.ts (9)

16-16: Prisma v6-safe import confirmed.

Switch to import { Prisma } aligns with Prisma v6 $queryRaw(Prisma.Sql) usage.


171-181: Accepted-only filter: verify product requirement.

Adding AND "status" = 'accepted' narrows previous behavior. Confirm UI/metrics expect excluding non-accepted bookings for this chart.


221-226: Good v6 migration to Prisma.sql + $queryRaw(query).

Pattern is correct and future-proof for Prisma v6.

Also applies to: 227-228


652-690: CTE split for host/guest stats LGTM.

Joins and casts are safe; counts are correctly narrowed.

Also applies to: 691-699


790-800: Popular events query migration LGTM.

Casts and top-N ordering preserved; execution path is v6-safe.

Also applies to: 801-807


881-890: Members count query migration LGTM; keep prior learning in mind.

No extra endTime <= now() filter added—good (per prior learning).

Also applies to: 892-898


944-954: Average rating query migration LGTM.

Type cast to ::float ensures numeric decode; consistent with downstream usage.

Also applies to: 955-961


1007-1016: Recent ratings query migration LGTM.

Ordering and limit preserved; safe for v6.

Also applies to: 1018-1025


1159-1195: Recent no-show guests query migration LGTM.

Accepted-only plus HAVING logic preserved; windowed row selection is correct.

Also applies to: 1197-1205

packages/lib/server/service/InsightsRoutingBaseService.ts (8)

270-275: Total count query migration LGTM.

Bigint handling retained; conversion occurs later.

Also applies to: 276-277


282-346: Paginated table data query migration LGTM.

JSON aggregation subqueries and ordering preserved; v6-safe pattern.

Also applies to: 348-349


368-373: Routing form stats queries migration LGTM.

Splitting total/without-booking is clear; filters preserved.

Also applies to: 374-375, 378-385


452-467: Users query (DISTINCT ON) migration LGTM.

ORDER BY "bookingUserId", "createdAt" DESC matches DISTINCT intent; optional LIMIT is safe.

Also applies to: 469-477


495-555: Period stats CTEs migration LGTM.

Parameterized period granularity is handled correctly with date_trunc and window bounds.

Also applies to: 556-563


565-577: Whole-period stats query migration LGTM.

Aggregations and ordering kept; used only for percentile-ish metrics.

Also applies to: 578-584


646-649: CSV map guard LGTM.

userStat null-check avoids undefined writes; minimal and safe.


964-1009: Failed bookings by field: migration LGTM.

CTEs and JSONB unnest logic preserved; integer cast on counts retained.

Also applies to: 1011-1021

@github-actions
Copy link
Contributor

github-actions bot commented Sep 11, 2025

E2E results are ready!

@emrysal emrysal disabled auto-merge September 11, 2025 22:16
@emrysal emrysal merged commit c3985e3 into main Sep 11, 2025
173 of 187 checks passed
@emrysal emrysal deleted the fix/prisma-v6-query-raw branch September 11, 2025 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working consumer core area: core, team members only ready-for-e2e size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants