Inbox Zero 的 Prisma 7 使用指南:统一从 @/generated/prisma 导入枚举与类型

发布时间:2026/11/15 0:47:33

Inbox Zero 的 Prisma 7 使用指南:统一从 @/generated/prisma 导入枚举与类型 Inbox Zero 的 Prisma 7 使用指南统一从 /generated/prisma 导入枚举与类型【免费下载链接】inbox-zeroThe worlds best AI personal assistant for email. Open source app to help you reach inbox zero fast.项目地址: https://gitcode.com/GitHub_Trending/in/inbox-zeroInbox Zero 是一款开源的 AI 邮件助手其 Web 应用apps/web基于 PostgreSQL 与 Prisma 7 构建数据访问层。本篇指南以仓库内的 .claude/skills/prisma/SKILL.md 为骨架结合 apps/web/utils/prisma.ts、apps/web/prisma/schema.prisma、apps/web/scripts/check-enum-imports.js 等源码完整讲解该项目的 Prisma 导入规范、客户端初始化方式、代码生成配置与迁移流程。读完本文你将掌握在 Inbox Zero 代码库中正确、安全地使用 Prisma 的全部要点并能理解这些约定背后的工程原因。技术栈与文档约定Inbox Zero 的数据层采用PostgreSQL Prisma 7这一点在技能文档开头即被明确声明。与之配套的关键事实还包括Prisma 运行时依赖锁定为prisma7.10.0与prisma/client7.10.0并引入prisma/adapter-pg7.10.0作为 PostgreSQL 驱动适配器见 apps/web/package.json数据库 Schema 的权威位置是 apps/web/prisma/schema.prisma该文件共 2686 行覆盖用户、账户、邮件、规则、订阅、组织等全部业务模型所有 Prisma 相关代码的导入入口被严格限定这是本仓库最核心的工程约定下文详细展开。三大导入来源实例、枚举与类型技能文档将 Prisma 的导入划分为三类每一类都有唯一指定的来源模块任何业务代码、测试代码都必须遵守// Prisma client 实例单例 import prisma from /utils/prisma; // 枚举NOT from prisma/client import { ActionType, SystemType } from /generated/prisma/enums; // 类型NOT from prisma/client import type { Rule, PrismaClient } from /generated/prisma/client; import { Prisma } from /generated/prisma/client;对应的三类模块职责如下导入内容来源模块用途客户端实例prisma默认导出/utils/prisma执行查询、事务、扩展方法枚举值如ActionType、SystemType/generated/prisma/enums作为运行时的值使用如条件判断、写入数据类型如Rule、PrismaClient、Prisma/generated/prisma/client仅用于类型标注与类型推导值得注意枚举也可以从/generated/prisma/client导入但只有类型才能这样做。文档明确要求枚举一律走enums入口原因在下一节说明。为什么严禁从 prisma/client 导入技能文档用加粗强调的方式给出了铁律Never import fromprisma/client— always use/generated/prisma/enumsand/generated/prisma/client.这条规则的根源在于Next.js 打包bundling问题。仓库中的校验脚本 apps/web/scripts/check-enum-imports.js 在文件头部注释里给出了完整解释Importing Prisma enums from /generated/prisma/client causes Next.js bundling errors in production when used in client components. This happens because Prisma Client depends on Node.js modules that cant be bundled for the browser.即prisma/client以及与其等价的/generated/prisma/client运行时导出依赖 Node.js 原生模块无法被浏览器端打包器处理若在客户端组件中以值的形式导入枚举生产构建就会失败。而/generated/prisma/enums是 Prisma 自动生成的纯 TypeScript 枚举天然适合客户端使用。从代码结构看这种拆分的设计思路是纯类型导入import type ...在编译后会被完全擦除不会残留任何运行时依赖因此从/generated/prisma/client导入类型是安全的枚举值导入会留下真实的运行时代码一旦进入客户端 bundle 就会触发 Node.js 模块解析错误所以必须从独立的enums文件导入/utils/prisma是服务端专属的客户端实例封装默认仅被 Server Components、Server Actions 与 API 路由使用天然不会进入客户端 bundle。路径别名/*在 apps/web/tsconfig.json 中被映射为./*即apps/web目录因此/generated/prisma/...实际指向apps/web/generated/prisma/.../utils/prisma指向apps/web/utils/prisma.ts。客户端实例的创建与扩展源码解析技能文档指明的/utils/prisma模块在 apps/web/utils/prisma.ts 中实现完整还原如下import { PrismaPg } from prisma/adapter-pg; import { env } from /env; import { PrismaClient } from /generated/prisma/client; import { encryptedTokens } from /utils/prisma-extensions; import { auditPrismaQueries } from /utils/audit/prisma-extension; declare global { var prisma: PrismaClient | undefined; } // Create the Prisma client with extensions, but cast it back to PrismaClient for type compatibility const _prisma global.prisma || (new PrismaClient({ adapter: new PrismaPg({ connectionString: env.PREVIEW_DATABASE_URL ?? env.DATABASE_URL, }), }) .$extends(encryptedTokens) .$extends(auditPrismaQueries) as unknown as PrismaClient); if (env.NODE_ENV development) global.prisma _prisma; export default _prisma;这段代码揭示了几个关键实现事实驱动适配器模式Prisma 7 采用 driver adapter 架构通过PrismaPg来自prisma/adapter-pg将连接字符串交给pg驱动。连接串优先级为PREVIEW_DATABASE_URL预览/隔离环境优先回退到DATABASE_URL。扩展链$extends实例依次叠加两个扩展——encryptedTokens用于敏感字段的透明加解密auditPrismaQueries用于查询审计具体见下文。开发环境全局缓存if (env.NODE_ENV development) global.prisma _prisma;借助 Node 全局对象复用实例避免开发热重载时反复创建数据库连接生产环境则不挂载全局变量。类型回退由于$extends返回的是扩展后的类型代码通过as unknown as PrismaClient将其收敛为统一的PrismaClient类型保证全项目调用方看到的 API 一致。透明加密扩展encryptedTokensapps/web/utils/prisma-extensions.ts 中定义了encryptedTokens扩展。它以一张字段清单ENCRYPTED_FIELDS驱动覆盖 OAuth Token、API Key 等敏感数据const ENCRYPTED_FIELDS { account: [access_token, refresh_token], calendarConnection: [accessToken, refreshToken], driveConnection: [accessToken, refreshToken], messagingChannel: [accessToken, refreshToken], mcpConnection: [accessToken, refreshToken, apiKey], mcpIntegration: [oauthClientSecret], meetingRecording: [meetingUrl], user: [aiApiKey, webhookSecret], } as const satisfies Recordstring, readonly string[];其实现机制值得注意写入时加密通过query拦截create/update/updateMany/upsert四个操作在调用底层查询前用encryptToken()对字段值做随机 IV 加密对update系列还额外兼容了{ set: ... }包装结构读取时解密通过result计算属性在读出记录时调用decryptToken()还原明文使用边界明确注释特别警告——不要给会被按值查询的字段开启加密如Session.sessionToken、EmailToken.token因为随机 IV 加密会破坏WHERE等值查找meetingRecording.meetingUrl之所以安全是因为去重查询走的是normalizedMeetingUrl和activeKey字段从不按原始链接检索。查询审计扩展auditPrismaQueries客户端叠加的第二个扩展来自/utils/audit/prisma-extension用于对 Prisma 查询执行审计与仓库中的审计体系apps/web/utils/audit/目录配套为邮件自动化操作规则执行、归档、标记等提供可追溯的查询记录。Schema 与代码生成配置apps/web/prisma/schema.prisma 顶部的配置决定了生成代码的形态datasource db { provider postgresql } generator client { provider prisma-client output ../generated/prisma generatedFileExtension ts importFileExtension ts }解读如下provider postgresql数据源锁定 PostgreSQLprovider prisma-client使用 Prisma 7 的prisma-client 生成器区别于旧版prisma-client-js生成的代码是带类型定义的客户端源码而非打包产物output ../generated/prisma生成目录为apps/web/generated/prisma相对apps/web/prisma上跳一级这正是/generated/prisma别名指向的位置generatedFileExtension ts与importFileExtension ts生成物及其内部导入均使用.ts扩展名与/generated/prisma/enums、/generated/prisma/client这两个模块入口一一对应。Schema 文件中还可看到 Prisma 对项目业务模型的完整覆盖例如User模型承载了登录、调查问卷、AI 设置、推荐系统与多组织关联等字段Account、Session基于 Auth.js Prisma 适配器模型扩展而来并加入了emailOtp、activeOrganization、OAuth Token 记录等 Inbox Zero 特有字段。迁移与工程化脚本prisma.config.ts迁移专用配置apps/web/prisma.config.ts 是 Prisma 7 独立的配置文件defineConfig来自prisma/configconst migrationUrl process.env.PREVIEW_DATABASE_URL_UNPOOLED || process.env.PREVIEW_DATABASE_URL || process.env.DIRECT_URL || process.env.DATABASE_URL_UNPOOLED || process.env.DATABASE_URL; export default defineConfig({ schema: ./prisma/schema.prisma, datasource: { url: migrationUrl, }, migrations: { path: ./prisma/migrations, }, });它把 Schema 路径固定为./prisma/schema.prisma迁移目录固定为./prisma/migrations仓库中已有 271 个 SQL 迁移文件并为迁移工具链提供独立于运行时连接串的 URL 解析优先级先是PREVIEW_DATABASE_URL_UNPOOLED再依次回退到预览地址、DIRECT_URL、非池化地址与默认地址。运行时实例与迁移工具使用不同的连接配置正是为了在连接池PgBouncer 等环境下保证 DDL 迁移可用。package.json 中的 Prisma 脚本apps/web/package.json 中与 Prisma 相关的脚本包括脚本命令作用postinstallprisma generate安装依赖后自动生成客户端保证/generated/prisma随时可用buildprisma migrate deploy ... next build生产构建前先应用迁移再构建 Next.jsprisma:migrate:localdotenv -e .env.local -- prisma migrate deploy本地环境应用迁移prisma:migrate:e2edotenv -e .env.e2e -- prisma migrate deployE2E 测试环境应用迁移check-enumsnode scripts/check-enum-imports.js静态检查枚举导入规范其中postinstall的prisma generate意味着只要执行pnpm installapps/web/generated/prisma就会被重新生成开发者在 Clone 仓库后无需手动生成即可运行代码。用 check-enums 守住导入边界为了把“从/generated/prisma/client只导入类型、枚举一律走enums”的规范固化到 CI仓库提供了 apps/web/scripts/check-enum-imports.js。其工作原理用 grep 扫描所有.ts/.tsx文件中from /generated/prisma/client的导入语句归一化多行 import 为单行便于解析跳过import type { ... }纯类型导入在剩余导入中用内置的PRISMA_ENUMS清单含ActionType、LogicalOperator、SystemType、ExecutedRuleStatus、PremiumTier、NewsletterStatus、ColdEmailStatus、GroupItemType、ReferralStatus、ScheduledActionStatus、DigestStatus、Frequency、CleanAction、ThreadTrackerType共 14 个枚举做负向前瞻匹配揪出以值形式从 client 导入的枚举发现违规即打印文件:行号、枚举名与导入语句并以退出码 1 中断流程。脚本头部注释中还给出了判断矩阵从 client 导入枚举值含与类型混导会被拦截从enums导入枚举、以及从 client 做纯类型导入则被放行。这意味着即使开发者误写了 importCI 也会在合并前给出明确修复提示import { ActionType } from /generated/prisma/enums。实践要点速查写查询import prisma from /utils/prisma直接使用该单例执行 CRUD、事务$transaction与扩展方法用枚举import { ActionType, SystemType } from /generated/prisma/enums可以安全地在客户端组件与服务端代码中作为值使用标注类型import type { Rule, PrismaClient } from /generated/prisma/client或import { Prisma } from /generated/prisma/client仅用于类型上下文如Prisma.UserWhereInput改模型编辑 apps/web/prisma/schema.prisma然后运行prisma migrate dev本地开发或pnpm prisma:migrate:local应用既有迁移迁移文件统一落在 apps/web/prisma/migrations加敏感字段若新增字段需要落库加密在 apps/web/utils/prisma-extensions.ts 的ENCRYPTED_FIELDS中登记并遵守“不可按值查询”的限制回归检查提交前运行pnpm check-enums在apps/web下或在 CI 中保留该步骤防止枚举导入回退到/generated/prisma/client。以上约定共同保证了 Inbox Zero 在 Prisma 7 时代既能享受类型安全的数据库访问又不会让服务端依赖泄漏进浏览器 bundle——这也是本项目将“导入规范”作为 Prisma 技能文档核心内容的根本原因。若需进一步深入可继续阅读 apps/web/utils/audit/prisma-extension.ts 了解查询审计扩展或浏览 apps/web/prisma/migrations 了解项目真实的 Schema 演进历史。【免费下载链接】inbox-zeroThe worlds best AI personal assistant for email. Open source app to help you reach inbox zero fast.项目地址: https://gitcode.com/GitHub_Trending/in/inbox-zero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/4 10:12:02

ThinkPHP6学生成绩管理系统源码解析与扩展实践

简介:这是一套基于ThinkPHP6框架开发的学生成绩管理系统源码,专为中小学教师、教务管理人员及PHP初学者设计,解决日常成绩录入、统计分析与多角色协同管理的实际痛点。资源包共1836个文件,主体为1083个PHP后端逻辑文件、166个JS交…

2026/11/13 2:04:39

three.js r137 离线包全解析:从 importmap 到数字孪生场景搭建

简介:three.js-r137.zip 是为前端开发者准备的 three.js r137 版本资料集,聚焦 WebGL 3D 渲染技术,帮助读者快速掌握在浏览器中构建三维场景的方法。压缩包共 2000 个文件,约 306.64MB,以 JS 源码和 HTML 示例为主&…

2026/11/15 0:42:52

电工证过期了怎么报名丽江市电工证培训

电工证过期了怎么报名丽江市电工证培训 证书过期了不知道怎么复审延期?别慌,很多人在工作中都会遇到这个问题,尤其是像低压电工、高压电工这类特种作业操作证,一旦过期,就会影响正常上岗或承接项目。如果你正在丽江,想找【丽江市电工证培训】,那你知道…

2026/11/15 0:42:52

南桥哪里考电工证多少钱能一次过

南桥哪里考电工证多少钱能一次过 怕考不过白交培训费?南桥电工证考试到底多少钱?别急,今天咱们就来聊聊这个事,讲讲怎么选培训机构、怎么备考、怎么避免踩坑。 一、南桥电工证考试到底值不值得考? 你可能在想:“我是不是必须考这个证?”其实,…

2026/11/15 0:42:52

证书过期了不知道怎么复审延期?考电工证贺兰县真实经历全揭秘

证书过期了不知道怎么复审延期?考电工证贺兰县真实经历全揭秘 证书过期了不知道怎么复审延期?这事儿真不是小事,我身边就有个朋友,因为没及时复审,差点丢了工作。今天就来聊一聊【考电工证贺兰县】的那些事,包括怎么考、怎么复审,还有考试内容、备考建…

2026/11/15 0:42:52

_特种作业操作证电工证全国通用吗

电工证考不过怕被扣钱?特种作业操作证电工全国通用怎么考 你是不是也觉得学历不高,担心自己根本考不上特种作业操作证电工?别急,今天就给你说清楚, _特种作业操作证电工 到底能不能考,怎么考,以及它到底是不是 全国通用…

2026/11/15 0:42:52

泉州电工证培训班怎么考,上岗必备的电工证你别再拖了

泉州电工证培训班怎么考,上岗必备的电工证你别再拖了 工地太忙根本没时间复习考试,这几乎是每个一线电工都遇到的难题。你天天在工地跑,连上厕所的时间都紧张,哪还有空去报什么泉州电工证培训班?可别小看这个电工证,它是你 上岗必备…

2026/11/15 0:37:52

松阳电工证含金量高吗?实操考试心里没底怕挂科怎么办

松阳电工证含金量高吗?实操考试心里没底怕挂科怎么办 实操考试心里没底怕挂科,这是很多准备考取 松阳电工证 的人的真实写照。尤其是对于转岗从业者来说,面对陌生的操作流程和严格的考核标准,难免会有些紧张。但你可能不知道,这张证书的 含金量…

2026/11/15 0:02:49

电工证考试口诉怎么准备值不值得考

电工证考试口诉怎么准备值不值得考 实操考试心里没底怕挂科,这是大多数准备考电工证的人心里最真实的感受。尤其是面对【电工证考试口诉】环节,很多人不知道该怎么准备,甚至担心自己说不好就被淘汰。其实,只要掌握方法, 值不值得考…

2026/11/15 0:02:49

桑植县考电工证千万别踩坑!报名全流程教你避坑

桑植县考电工证千万别踩坑!报名全流程教你避坑 你是不是也遇到过这种情况:想考个电工证,但不知道从哪儿下手,怕被中介坑,怕花冤枉钱,更怕考了证还不能用?别急,这正是你该看这篇文章的原因。在桑植县考电工证,确实有很多人被坑过,但只要你知道流程、…

2026/11/15 0:02:49

电工证考试口诉怎么准备值不值得考

电工证考试口诉怎么准备值不值得考 实操考试心里没底怕挂科,这是大多数准备考电工证的人心里最真实的感受。尤其是面对【电工证考试口诉】环节,很多人不知道该怎么准备,甚至担心自己说不好就被淘汰。其实,只要掌握方法, 值不值得考…

2026/11/15 0:02:49

桑植县考电工证千万别踩坑!报名全流程教你避坑

桑植县考电工证千万别踩坑!报名全流程教你避坑 你是不是也遇到过这种情况:想考个电工证,但不知道从哪儿下手,怕被中介坑,怕花冤枉钱,更怕考了证还不能用?别急,这正是你该看这篇文章的原因。在桑植县考电工证,确实有很多人被坑过,但只要你知道流程、…

2026/11/13 22:32:11

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/13 12:14:39

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑