refactor: replace @prisma/client/runtime imports with public API#23087
refactor: replace @prisma/client/runtime imports with public API#23087
Conversation
- Replace PrismaClientKnownRequestError and other error classes with Prisma namespace equivalents - Remove internal DefaultArgs and InternalArgs type imports from Prisma extensions - Ensure all error handling uses stable public API exports - Maintain compatibility with future Prisma versions by avoiding runtime dependencies Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
WalkthroughThis PR refactors Prisma imports and type references across multiple modules to use the Prisma namespace (import { Prisma } from @prisma/client). It updates instanceof checks to Prisma.PrismaClientKnownRequestError and related types in API filters, TRPC handlers, Stripe billing, and auth adapter. In Prisma extensions, it removes runtime-library generics (InternalArgs, DefaultArgs) and switches to non-generic Prisma arg types (e.g., Prisma.UserFindUniqueArgs, Prisma.TeamFindFirstArgs). No runtime logic or control flow changes were made, and no exported/public signatures changed. 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 (
|
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Graphite Automations"Add consumer team as reviewer" took an action on this PR • (08/23/25)1 reviewer was added to this PR based on Keith Williams's automation. |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/features/auth/lib/next-auth-custom-adapter.ts (1)
69-71: updateUser accepts CreateInput; should use UpdateInput to match prisma.user.update.Using Prisma.UserUncheckedCreateInput (or CreateInput) for an update method is incorrect and can hide invalid fields at compile-time. Switch to UpdateInput (or UncheckedUpdateInput) to align with prisma.user.update’s expected XOR<UserUpdateInput, UserUncheckedUpdateInput>.
Apply this diff:
- updateUser: ({ id, ...data }: Prisma.UserUncheckedCreateInput) => + updateUser: ({ id, ...data }: Prisma.UserUncheckedUpdateInput) => prismaClient.user.update({ where: { id }, data }),If you prefer the checked path:
- updateUser: ({ id, ...data }: Prisma.UserUncheckedCreateInput) => + updateUser: ({ id, ...data }: Prisma.UserUpdateInput) => prismaClient.user.update({ where: { id }, data }),apps/api/v2/src/filters/prisma-exception.filter.ts (1)
1-85: Address Prisma runtime import and direct error usage in testsWe ran the requested repo-wide scans and found the following critical issues that must be fixed before merging:
• In packages/trpc/server/routers/viewer/eventTypes/duplicate.handler.test.ts (line 3):
– The test is importing directly from@prisma/client/runtime/library.
– It also instantiatesnew PrismaClientKnownRequestError(…)without thePrisma.namespace.
Fix:
```diff
- import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
+ import { Prisma } from "@prisma/client";- new PrismaClientKnownRequestError("Unique constraint failed", { ... }); + new Prisma.PrismaClientKnownRequestError("Unique constraint failed", { ... }); ```• Please search for any other direct imports from
@prisma/client/runtimeor un-namespacedPrismaClient*Errorclasses in tests or source files and update them to use thePrismanamespace.
Additional guardrails (for awareness / future refactors):
• Prisma
includeusage:
Our scan flagged extensive use ofinclude: { … }across the codebase. We preferselectto avoid over-fetching — consider scheduling a gradual refactor to replace high-riskincludecalls with explicitselectclauses.•
credential.keyexposures:
Dozens of API and tRPC handlers reference or parsecredential.key. Audit these to ensure no sensitive keys are accidentally sent to clients or logged in plaintext.packages/trpc/server/routers/viewer/eventTypes/create.handler.ts (1)
62-64: Bug:usersconnect is gated byschedulingTypeinstead ofteamId.Comment says "non-managed event types and non team event types" but the condition disables
userswheneverschedulingTypeis truthy (i.e., always), so the current user is never connected. Gate byteamIdinstead.Apply:
- // Only connecting the current user for non-managed event types and non team event types - users: isManagedEventType || schedulingType ? undefined : { connect: { id: userId } }, + // Only connect the current user for non-managed, non-team event types + users: isManagedEventType || !!teamId ? undefined : { connect: { id: userId } },
🧹 Nitpick comments (9)
packages/features/auth/lib/next-auth-custom-adapter.ts (3)
80-93: Tighten P2025 handling and simplify the catch branch.Minor cleanup: collapse the nested if and explicitly ignore only P2025; rethrow everything else.
- } catch (error) { - // If token already used/deleted, just return null - // https://www.prisma.io/docs/reference/api-reference/error-reference#p2025 - if (error instanceof Prisma.PrismaClientKnownRequestError) { - if (error.code === "P2025") return null; - } - throw error; - } + } catch (error) { + // If token already used/deleted, just return null (P2025) + if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2025") { + return null; + } + throw error; + }
33-35: Specify radix in parseInt for id normalization.Guard against environment-dependent parsing by providing base 10.
- prismaClient.user.findUnique({ where: { id: typeof id === "string" ? parseInt(id) : id } }), + prismaClient.user.findUnique({ where: { id: typeof id === "string" ? parseInt(id, 10) : id } }),
41-47: Consider narrowing selected user fields in getUserByAccount.You already use select, which is good. If the caller doesn’t need the entire User, prefer an explicit subset (e.g., id, email, name) to reduce payload and risk of accidental leakage. Only do this if the adapter’s return type can be relaxed accordingly.
- const account = await prismaClient.account.findUnique({ + const account = await prismaClient.account.findUnique({ where: { provider_providerAccountId, }, - select: { user: true }, + select: { user: { select: { id: true, email: true, name: true, image: true, identityProvider: true } } }, });packages/prisma/extensions/exclude-pending-payment-teams.ts (1)
27-35: Simplify the union with a structural generic to improve type safety.A structural constraint avoids repeating all Team*Args unions while keeping intellisense for where. Optional—current code is fine.
-async function excludePendingPayments( - args: - | Prisma.TeamFindUniqueArgs - | Prisma.TeamFindFirstArgs - | Prisma.TeamFindManyArgs - | Prisma.TeamFindUniqueOrThrowArgs - | Prisma.TeamFindFirstOrThrowArgs, - query: <T>(args: T) => Promise<unknown> -) { +type WithTeamWhere<T extends { where?: Prisma.TeamWhereInput }> = T; +async function excludePendingPayments<T extends { where?: Prisma.TeamWhereInput }>( + args: WithTeamWhere<T>, + query: (args: WithTeamWhere<T>) => Promise<unknown> +) {apps/api/v2/src/filters/prisma-exception.filter.ts (1)
38-39: Header lookup should be case-insensitive.Express lower-cases header names. Consider checking the lowercase form first to avoid missing a provided X-Request-Id.
- const requestId = request.headers["X-Request-Id"] ?? "unknown-request-id"; + const requestId = (request.headers["x-request-id"] ?? request.headers["X-Request-Id"] ?? "unknown-request-id").toString(); - response.setHeader("X-Request-Id", requestId.toString()); + response.setHeader("X-Request-Id", requestId);packages/prisma/extensions/exclude-locked-users.ts (1)
45-50: Avoid stringify-based detection; use a recursive key check for accuracy.String matching can false-positive on values or nested strings. A small recursive helper is clearer and safer. Optional improvement.
- const whereString = safeJSONStringify(args.where); - const shouldIncludeLocked = whereString.includes('"locked":'); + const shouldIncludeLocked = hasKey(args.where, "locked"); // Unless explicitly specified, we exclude locked users if (!shouldIncludeLocked) { args.where.locked = false; }Add this helper near the top of the file:
function hasKey(obj: unknown, key: string): boolean { if (!obj || typeof obj !== "object") return false; if (Object.prototype.hasOwnProperty.call(obj as Record<string, unknown>, key)) return true; for (const v of Object.values(obj as Record<string, unknown>)) { if (hasKey(v, key)) return true; } return false; }packages/trpc/server/routers/viewer/eventTypes/create.handler.ts (3)
83-89: Prisma query shouldselectonly required fields.We only use
rolefrommembership. Per guidelines, preferselectfor minimal data.const hasMembership = await ctx.prisma.membership.findFirst({ where: { userId, teamId: teamId, accepted: true, - }, - }); + }, + select: { role: true }, + });
141-146: LGTM on switching toPrisma.PrismaClientKnownRequestError; broaden target check.In some Prisma versions
e.meta.targetcan be a string or an array. Slightly harden the guard.- if (e instanceof Prisma.PrismaClientKnownRequestError) { - if (e.code === "P2002" && Array.isArray(e.meta?.target) && e.meta?.target.includes("slug")) { - throw new TRPCError({ code: "BAD_REQUEST", message: "URL Slug already exists for given user." }); - } - } + if (e instanceof Prisma.PrismaClientKnownRequestError) { + const target = e.meta?.target as unknown; + const isSlugUniqueViolation = + e.code === "P2002" && + ((Array.isArray(target) && target.includes("slug")) || + (typeof target === "string" && target.includes("slug"))); + if (isSlugUniqueViolation) { + throw new TRPCError({ code: "BAD_REQUEST", message: "URL Slug already exists for given user." }); + } + }
146-147: Consider returning 500 for unknown errors instead of 400.Unknown failures are more accurately mapped to INTERNAL_SERVER_ERROR; 400 implies client fault.
- throw new TRPCError({ code: "BAD_REQUEST" }); + throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });
📜 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 (6)
apps/api/v2/src/filters/prisma-exception.filter.ts(3 hunks)packages/app-store/stripepayment/lib/team-billing.ts(1 hunks)packages/features/auth/lib/next-auth-custom-adapter.ts(2 hunks)packages/prisma/extensions/exclude-locked-users.ts(1 hunks)packages/prisma/extensions/exclude-pending-payment-teams.ts(1 hunks)packages/trpc/server/routers/viewer/eventTypes/create.handler.ts(2 hunks)
🧰 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:
packages/features/auth/lib/next-auth-custom-adapter.tspackages/trpc/server/routers/viewer/eventTypes/create.handler.tspackages/prisma/extensions/exclude-pending-payment-teams.tspackages/prisma/extensions/exclude-locked-users.tspackages/app-store/stripepayment/lib/team-billing.tsapps/api/v2/src/filters/prisma-exception.filter.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/features/auth/lib/next-auth-custom-adapter.tspackages/trpc/server/routers/viewer/eventTypes/create.handler.tspackages/prisma/extensions/exclude-pending-payment-teams.tspackages/prisma/extensions/exclude-locked-users.tspackages/app-store/stripepayment/lib/team-billing.tsapps/api/v2/src/filters/prisma-exception.filter.ts
🧬 Code graph analysis (1)
apps/api/v2/src/filters/prisma-exception.filter.ts (4)
apps/api/v2/src/filters/calendar-service-exception.filter.ts (1)
Catch(24-61)apps/api/v2/src/filters/http-exception.filter.ts (1)
Catch(9-38)apps/api/v2/src/filters/zod-exception.filter.ts (1)
Catch(11-46)apps/api/v2/src/filters/trpc-exception.filter.ts (1)
Catch(104-142)
🔇 Additional comments (7)
packages/app-store/stripepayment/lib/team-billing.ts (1)
1-1: Refactor to Prisma namespace looks correct and keeps runtime behavior unchanged.The instanceof check against Prisma.PrismaClientKnownRequestError for P2002 is the right public API and aligns with the PR goal. No functional changes introduced here.
Also applies to: 9-12
packages/features/auth/lib/next-auth-custom-adapter.ts (1)
1-2: Correct switch to Prisma namespace for error types.Importing the Prisma namespace and using Prisma.PrismaClientKnownRequestError resolves the type/value import issue cleanly.
packages/prisma/extensions/exclude-pending-payment-teams.ts (1)
29-33: Good move to public Prisma arg types (no generics from runtime).Dropping InternalArgs/DefaultArgs removes a dependency on private runtime types and matches the public API. Behavior is preserved.
apps/api/v2/src/filters/prisma-exception.filter.ts (1)
5-5: Namespace refactor is consistent and correct.Switching to Prisma.PrismaClient*Error everywhere (type alias, @catch, and instanceof) uses the public API and avoids any runtime subpath imports. Control flow unchanged.
Also applies to: 17-22, 25-30, 55-75
packages/prisma/extensions/exclude-locked-users.ts (1)
37-41: Public Prisma arg types only—looks good.Removing DefaultArgs/InternalArgs keeps this extension on public, stable types without impacting runtime behavior.
packages/trpc/server/routers/viewer/eventTypes/create.handler.ts (2)
1-1: Fix lingering @prisma/client/runtime import in duplicate.handler.test.tsA quick sweep uncovered a direct import from
@prisma/client/runtime/libraryin your test, which should be replaced with the Prisma namespace import to keep runtime checks working correctly.• File:
packages/trpc/server/routers/viewer/eventTypes/duplicate.handler.test.ts
○ Line 3:import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";Suggested replacement:
-import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { Prisma } from "@prisma/client"; // … - new PrismaClientKnownRequestError(/* … */) + new Prisma.PrismaClientKnownRequestError(/* … */)After this change, there should be no remaining imports from
@prisma/client/runtimeoutside of your bundler configs.Likely an incorrect or invalid review comment.
138-139: ✅ No credential.key is returned by EventTypeRepository#createI’ve verified that
EventTypeRepository#createcalls:return this.prismaClient.eventType.create({ data: …, include: { calVideoSettings: true }, });– The
EventTypemodel inschema.prismadoes not have anycredentialIdorkeyfields, and
– The only included relation iscalVideoSettings, which likewise contains only its own boolean flags and timestamps (no credentials).Therefore, returning
{ eventType }cannot leak anycredential.key.
E2E results are ready! |
emrysal
left a comment
There was a problem hiding this comment.
LGTM, very safe change (keeping it the way it is is actually more dangerous)
Summary
This PR eliminates all imports from
@prisma/client/runtimeand its subpaths, replacing them with the corresponding public API exports from thePrismanamespace. This change removes brittle dependencies on internal Prisma runtime modules and ensures compatibility with future Prisma versions.Key changes:
PrismaClientKnownRequestError,PrismaClientValidationError, etc. withPrisma.PrismaClientKnownRequestError,Prisma.PrismaClientValidationErrorDefaultArgsandInternalArgstype imports, simplified function signatures to use base Prisma typesFiles modified:
apps/api/v2/src/filters/prisma-exception.filter.ts- API exception filterpackages/app-store/stripepayment/lib/team-billing.ts- Stripe payment error handlingpackages/features/auth/lib/next-auth-custom-adapter.ts- NextAuth adapterpackages/trpc/server/routers/viewer/eventTypes/create.handler.ts- tRPC event type creationpackages/prisma/extensions/exclude-locked-users.ts- Prisma extensionpackages/prisma/extensions/exclude-pending-payment-teams.ts- Prisma extension