
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),仅供参考