mcpField
P
prisma-next-contract

prisma-next-contract

github.com/prisma数据与数据库4112.0k 次安装9 周前更新
代码仓库

关于 prisma-next-contract

面向 Prisma Next 的数据契约编写技能,涵盖 PSL 和 TypeScript builder 两种方式。它指导模型、字段、关系、约束及扩展的修改,并区分契约编辑与迁移、查询任务。

主要功能

  1. 01使用 PSL 或 TypeScript 编写契约
  2. 02生成并验证契约产物
  3. 03编辑模型、字段和关系
  4. 04定义索引、枚举和值对象
  5. 05配置扩展

适用场景

  1. 01添加或修改模型、字段
  2. 02定义关系与约束
  3. 03配置扩展类型
  4. 04排查契约生成诊断

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/prisma/prisma-next --skill prisma-next-contract

安装后在 Claude Code 中输入/prisma-next-contract确认已加载。

详细介绍

Prisma Next — 契约编写

编辑你的数据契约。其余工作交给 Prisma。

数据契约是数据层的唯一事实来源。你编辑契约源文件——contract.prisma(PSL,规范表层)或 contract.ts(TypeScript 构建器)——框架会据此生成类型、迁移和运行时配置。用户模型分为三步:

  1. 编辑数据契约。
  2. 系统为你规划迁移。(prisma-next-migrations)
  3. 如果需要数据迁移,编辑 migration.ts 并执行。(prisma-next-migrations)

在第 1 步中,Agent 每次编辑契约后都会运行 prisma-next contract emit(或者安装 Vite 插件,让打包器在保存时运行该命令——参见 prisma-next-build)。Emit 会通过 façade 根据 prisma-next.config.ts 中 contract: 的文件扩展名所选定的 provider 读取契约源文件,然后在同一目录下写入两个产物:

  • contract.json — 规范的、经过内容哈希处理的 Contract IR。规划器、运行时和 db verify 会读取此文件。
  • contract.d.ts — 从中导入 Contract 时,运行时和各 lane 会传递的精确 TypeScript 类型。

这两个文件都是生成的产物。编辑源文件;切勿编辑 JSON 或 .d.ts 文件。

适用场景

  • 用户想要添加、更改或移除模型、字段或关系。
  • 用户想要添加索引、唯一约束、枚举或值对象(复合类型)。
  • 用户想要添加命名空间块(Postgres 模式)或跨契约外键。
  • 用户想要在模型上设置 @@control 或配置 defaultControlPolicy。
  • 用户想要使用扩展中的自定义类型(pgvector.Vector(length: 1536)、cipherstash.EncryptedString({...}))。
  • 用户想要通过 prisma-next.config.ts 中的 extensions: [...] 安装或配置扩展,包括 @prisma-next/extension-supabase。
  • 用户正在切换契约编写源(PSL ↔ TypeScript 构建器)。
  • 用户在运行 contract emit 时收到 PN-CLI-4002、PN-CLI-4003 或 PN-CLI-4011。
  • 用户提到:schema、字段、模型、属性、prisma schema、PSL、contract.prisma、contract.ts、contract.json、contract.d.ts、contract emit、façade 导入、@prisma-next/postgres/config、@prisma-next/postgres/contract-builder、扩展、pgvector、cipherstash、postgis、paradedb、supabase、命名空间、跨空间 FK、@@control、枚举、值对象、验证、回调、软删除、paranoid、作用域。(最后一组应转到下文的 Prisma Next 尚不支持的功能。)

不适用场景

  • 用户想要将契约更改应用到数据库 → prisma-next-migrations。
  • 用户想要针对契约编写查询 → prisma-next-queries。
  • 用户想要配置 db.ts(运行时入口、中间件、环境配置)→ prisma-next-runtime。
  • 用户想要配置 Vite / 打包器集成 → prisma-next-build。
  • 用户想要首次设置 Prisma Next → prisma-next-quickstart。
  • 用户想要深入了解单个结构化错误信封 → prisma-next-debug。
  • 用户想要提交缺失功能请求 → prisma-next-feedback。

核心概念

  • 用户编写的代码只能从 @prisma-next/<target> 门面导入。 对于 Postgres 应用:@prisma-next/postgres/config、@prisma-next/postgres/contract-builder、@prisma-next/postgres/control、@prisma-next/postgres/runtime。Mongo 的布局相同(@prisma-next/mongo/config、@prisma-next/mongo/contract-builder、@prisma-next/mongo/runtime)。每个扩展都会发布自己的门面:@prisma-next/extension-pgvector/control、@prisma-next/extension-postgis/control、@prisma-next/extension-paradedb/control。用户代码绝不能深入使用 @prisma-next/cli/*、@prisma-next/family-*、@prisma-next/target-*、@prisma-next/adapter-*、@prisma-next/driver-* 或 @prisma-next/sql-contract-*。 门面会封装好 family / target / adapter / driver 的连接配置。参见 常见陷阱 #4。
  • Contract 源文件。 框架会读取并降级为规范 Contract IR 的文件。有两种形式,二者都是一等形式:
    • contract.prisma (PSL) — 具有 schema 风格的 DSL。适用于典型应用和使用 Prisma 的棕地项目。通过 contract: './<path>/contract.prisma' 接入——defineConfig 门面会检测 .prisma 扩展名,并路由到 PSL 提供程序。
    • contract.ts (TypeScript 构建器) — 使用 @prisma-next/postgres/contract-builder(或 @prisma-next/mongo/contract-builder)中的 defineContract({...}, ({ field, model, rel, type }) => ({...})) 以编程方式编写。通过 contract: './<path>/contract.ts' 接入——门面会检测 .ts 扩展名,并路由到 TS 提供程序。当你需要以编程方式组合(每租户变体、生成字段),或需要 PSL 尚无法表达的结构(例如注册参数化扩展类型——参见 pgvector 的 Contract)时使用。
  • prisma-next.config.ts。 用于连接 Contract 源文件、数据库连接、迁移目录和已安装的扩展。使用 @prisma-next/postgres/config(或 @prisma-next/mongo/config)中的 defineConfig({...})。门面接受四个字段:contract(路径字符串——.prisma 或 .ts)、db({ connection?: string })、extensions(控制描述符数组)、migrations({ dir?: string })。contract.json 的输出路径会根据 contract 自动推导(例如,./src/prisma/contract.prisma → ./src/prisma/contract.json)。
  • Emit 流程。 prisma-next contract emit --config <path>? 会读取 prisma-next.config.ts,调用门面选定的提供程序,验证生成的 Contract,然后将 contract.json + contract.d.ts 原子写入与源文件相同的目录。
  • 扩展命名空间。 扩展会提供带命名空间的构造器(pgvector.Vector(length: 1536)、cipherstash.EncryptedString({equality: true}))和辅助预设。通过在两个位置添加描述符来安装扩展——两个字段都命名为 extensions,但这两个接口使用不同类型和形状的描述符:
    • 在配置中(门面和核心): extensions: [pgvector] — 从 @prisma-next/extension-<name>/control 导入的 control 描述符数组。
    • 在 TS 构建器的 defineContract 中(仅编写 contract.ts 时): extensions: { pgvector } — 从 @prisma-next/extension-<name>/pack 导入的 pack 描述符记录。
  • Contract 空间。 每个生成 Contract 的包都有自己的 Contract 空间——包根目录下的 prisma-next.config.ts、Contract 源文件、与源文件同目录生成的产物,以及 migrations/ 目录。磁盘上有两种有意设计的布局,取决于 Contract 空间属于使用它的应用,还是属于 Contract 空间包(扩展、内部聚合根包等):
    • 应用布局(构建应用时使用)。仓库根目录下的 prisma-next.config.ts;src/prisma/contract.{prisma,ts};同目录下的 src/prisma/contract.{json,d.ts};同目录下的 src/prisma/db.ts;迁移文件位于 migrations/app/<timestamp>_<slug>/。app/ 段是使用该空间的应用的空间 ID;扩展空间 ID 则位于由扩展包管理的同级 migrations/<extension-space-id>/ 目录中。examples/prisma-next-demo 使用这种布局。目前 prisma-next init 生成的布局有所不同(仓库根目录下的 prisma/...)——这是一个缺陷(TML-2532);每条命令实际预期使用的规范布局即为此布局。
    • Contract 空间包布局(发布 Contract 空间包时使用——例如扩展、内部 monorepo 包)。包根目录下的 prisma-next.config.ts;直接位于 src/contract.{prisma,ts}(没有 prisma/ 子目录);同目录下的 src/contract.{json,d.ts};迁移文件直接位于 migrations/<timestamp>_<slug>/(没有 <space-id> 段——该包本身就是一个独立空间)。详见 .cursor/rules/contract-space-package-layout.mdc 和 ADR 212。 两种布局都允许 defineConfig 的 contract: 路径指向源文件;框架会据此推导其他所有内容(生成输出、迁移根目录)。选择与当前构建内容匹配的布局并保持一致——不要混用。

可用于路由的诊断代码

prisma-next contract emit 会返回带有稳定代码的结构化错误;应根据 code 分支处理,而不是依据消息文本。

代码含义后续操作
PN-CLI-4002 缺少 Contract 配置prisma-next.config.ts 中未设置 contract。在 @prisma-next/postgres/config 的 defineConfig({...}) 中添加 contract: './src/prisma/contract.prisma'(应用布局)或 './src/contract.prisma'(contract-space-package 布局);.ts 源文件也同理。
PN-CLI-4003 Contract 验证失败已加载源文件,但 Contract IR 未通过结构验证。查看 meta.diagnostics / meta.issues,找出有问题的模型/字段,修复源文件后重新生成。
PN-CLI-4011 配置中缺少扩展包Contract 使用了带命名空间的构造器(例如 pgvector.Vector(...)),但配置中的 extensions 未列出匹配的描述符。meta.missingExtensions 会列出缺少的扩展。安装该包,导入其控制描述符(import pgvector from '@prisma-next/extension-pgvector/control'),并将其添加到 prisma-next.config.ts 的 extensions: [...] 中。

工作流 — 阅读 Contract 的真实来源

概念:每次更改 Contract,都应先定位源文件。配置是权威依据——阅读 prisma-next.config.ts,找到 contract: 字段(门面下的路径字符串),然后打开它指向的文件。同一字段还会告知已安装的 extensions: [...]。

cat prisma-next.config.ts

如果 contract: 以 .prisma 结尾,源文件就是 PSL;如果以 .ts 结尾,源文件就是 TS 构建器。如果缺少 prisma-next.config.ts,请转到 prisma-next-quickstart。

工作流 — 编辑模型 / 字段 / 关系(PSL)

概念:PSL 模型会映射为表(Mongo 中则为集合);字段会映射为列;@relation(...) 用于声明外键一侧。只在拥有关系的一侧添加关系——框架会自动推导反向引用。

model User {
  id    Int    @id @default(autoincrement())
  email String @unique
}

model Post {
  id       Int    @id @default(autoincrement())
  title    String
  authorId Int
  author   User   @relation(fields: [authorId], references: [id], onDelete: Cascade)

  @@unique([title, authorId])
  @@index([authorId])
}

然后运行 pnpm prisma-next contract emit(或使用 Vite 插件——参见 prisma-next-build)。通过 onDelete / onUpdate 显式指定级联行为;默认值为 Restrict。

@@index 还接受 expression:(替代字段列表)、where:(部分索引谓词)、unique:、type:/options:(目标注册的访问方法),以及 name: 或 map:(二者只能选其一):

@@index(expression: "lower(email)", name: "users_email_lower")
@@index([authorId], where: "(archived_at IS NULL)", name: "posts_author_active")

name: 声明受管理的索引(物理名称为 <name>_<8-hex hash>,重命名计划为 ALTER INDEX … RENAME);map: 则按原样采用精确的物理名称(适用于 infer 捕获的对象——将它与 SQL 正文结合使用时会发出警告,因为漂移检测会逐字节比较编写的文本与 Postgres 重新打印的文本)。expression: 必须配合 name: 或 map: 使用。TS 构建器通过 constraints.index([cols.x], {...}) / constraints.index({ expression, ... }) 提供对应功能——参见 packages/2-sql/2-authoring/contract-ts/README.md。

用于重复类型的 PSL 别名可在顶层 types {} 块中定义:

types {
  Email = String
}

model User {
  id    Int    @id @default(autoincrement())
  email Email  @unique
}

注意:SQL 解释器不支持标量列表(例如 String[])和隐式 Prisma-ORM 多对多关系(双方都有列表导航属性但没有联结模型)——请改用联结模型。支持复合/可嵌入类型(模型中使用 type Address { ... } 和 address Address):解释器会将其映射为领域中的 valueObjects,并将其存储为 jsonb 列。参见下文的 工作流 — 值对象。

工作流 — 编辑模型 / 字段 / 关系(TS 构建器)

概念:同一个模型,不同的编写方式。该门面将 defineContract、field、model、rel 重新导出,并将 family/target 包作为 @prisma-next/postgres/family 和 @prisma-next/postgres/target 的默认导出。使用回调重载(defineContract({...}, ({ field, model, rel, type }) => ({...})))即可使用更高层级的辅助函数(field.text()、field.id.uuidv7String()、field.temporal.createdAt()、type.sql.String(35))。

import sqlFamily from '@prisma-next/postgres/family';
import { defineContract } from '@prisma-next/postgres/contract-builder';
import postgresPack from '@prisma-next/postgres/target';

export const contract = defineContract(
  {
    family: sqlFamily,
    target: postgresPack,
  },
  ({ field, model }) => ({
    models: {
      User: model('User', {
        fields: {
          id: field.id.uuidv7String(),
          email: field.text().unique(),
          createdAt: field.temporal.createdAt(),
        },
      }).sql({ table: 'app_user' }),
    },
  }),
);

然后运行 pnpm prisma-next contract emit。field.<scalar>() 辅助函数仅在回调重载中可用;在回调外仅有 field.column(...)、field.generated(...)、field.namedType(...)。

对于 Mongo,将所有 @prisma-next/postgres/* 导入替换为 @prisma-next/mongo/*。Mongo 构建器还提供 index 和 valueObject。

工作流 — 添加扩展类型标量(pgvector)

概念:扩展提供一个命名空间(pgvector.*)和两种描述符类型——用于配置门面的 control 描述符,以及用于 TS 构建器的 pack 描述符。在 defineConfig.extensions 中注册 control 描述符(数组形式)。如果使用 TS 构建器编写,还要在 defineContract.extensions 中注册 pack 描述符(记录形式)。然后在 contract 中引用带命名空间的构造器。

prisma-next.config.ts:

import pgvector from '@prisma-next/extension-pgvector/control';
import { defineConfig } from '@prisma-next/postgres/config';

export default defineConfig({
  contract: './src/prisma/contract.prisma',
  extensions: [pgvector],
});

src/prisma/contract.prisma:

model Document {
  id        Int                          @id @default(autoincrement())
  content   String
  embedding pgvector.Vector(length: 1536)
}

运行 Emit。命名类型降级会将 vector(1536) 放到列上,而 contract.d.ts 中的类型映射则包含正确的 TS 类型。

如果引用 pgvector.* 却未在配置中注册 pack,Emit 会以 PN-CLI-4011 失败,并包含 meta.missingExtensions: ['pgvector']。信封中的 fix 文本为 "Add the missing extension descriptors to extensions in prisma-next.config.ts"——该字段名与门面一致。

有关单扩展和多扩展设置的规范示例,请阅读 examples/multi-extension-monorepo/app/prisma-next.config.ts 和 examples/prisma-next-postgis-demo/prisma-next.config.ts。

工作流 — 多态(@@discriminator / @@base)

概念(SQL 目标):一个基模型声明判别字段;每个变体模型声明其基模型和判别值。变体通过**是否设置 @@map(...)**来选择 STI 还是 MTI:不设置 @@map 表示变体继承基模型的表(单表继承);@@map("variant_table") 表示变体拥有自己的表,并通过主键进行 1:1 关联(多表继承)。

model Task {
  id    Int    @id @default(autoincrement())
  title String
  type  String

  @@discriminator(type)
  @@map("tasks")
}

// STI variant — shares the `tasks` table.
model Bug {
  severity String

  @@base(Task, "bug")
}

// MTI variant — joins to `tasks` via PK; carries its own `features` table.
model Feature {
  priority Int

  @@base(Task, "feature")
  @@map("features")
}

如有疑问,请对照解释器测试验证多态语法:packages/2-sql/2-authoring/contract-psl/test/interpreter.polymorphism.test.ts。

Mongo 没有 schema 层,因此 Mongo 上的多态通过 TS 构建器中模型上的显式 discriminator 字段建模(参见 @prisma-next/mongo/contract-builder);@@base / @@discriminator PSL 属性仅适用于 SQL。

查询变体属于运行时问题——请参阅 prisma-next-queries。

工作流 — 值对象(复合类型)

概念:type Foo { ... } 块声明值对象形状。解释器会将它们降级为 contract domain 中的 valueObjects,并将其存储为 jsonb 列。支持嵌套值对象引用。

type Address {
  street  String
  city    String
  zip     String?
  country String
}

model User {
  id      String   @id @default(uuid())
  email   String
  address Address?
}

生成的 contract.json 包含带字段描述符的 domain.namespaces.<ns>.valueObjects.Address,而 address 列在 storage 中的取值为 codecId: "pg/jsonb@1" / nativeType: "jsonb"。

规范示例:examples/prisma-next-demo/src/prisma/contract.prisma。

工作流 — 枚举

概念:PSL enum 块用于声明领域枚举:一个命名值集,通过声明的编解码器存储(@@type("pg/text@1") → text 列),并由规划器生成的 CHECK 约束强制执行。每个成员通过 Name = "value" 映射到数据库值。在同一契约中的任何模型里,都可以将枚举名称用作字段类型。

enum user_type {
  @@type("pg/text@1")
  admin = "admin"
  user  = "user"
}

model User {
  id   String    @id @default(uuid())
  kind user_type
}

规范示例:examples/prisma-next-demo/src/prisma/contract.prisma。

工作流 — 命名空间(Postgres 模式)

概念:将模型放入 namespace <name> { ... } 块中,以便将其置于非默认的 Postgres 模式中。不属于任何块的模型会放入隐式默认命名空间。

namespace public {
  model Profile {
    id       String @id @default(uuid())
    username String
    userId   String @unique
    @@map("profile")
  }
}

规范示例:examples/supabase/src/contract.prisma。

工作流 — 跨契约外键

概念:关系字段可以使用 <space>:<namespace>.<Model> 形式引用其他契约空间中的模型。契约还支持在 types {} 块中声明顶层命名类型别名,其基础是字段所用的相同裸类型位置构造器。@db.X(args) 通道已移除:将 @db.X 改写为 X,将 @db.X(args) 改写为 X(args);其余用法会报错,并提供明确诊断,指出替代写法。

types {
  AuthUserId = Uuid
}

namespace public {
  model Profile {
    id       String     @id @default(uuid())
    username String
    userId   AuthUserId @unique
    user     supabase:auth.AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
    @@map("profile")
  }
}

supabase:auth.AuthUser 表示契约空间 supabase 中命名空间 auth 的模型 AuthUser。目标空间由已注册的扩展包提供(此处为 @prisma-next/extension-supabase/pack)。

规范示例:examples/supabase/src/contract.prisma。

工作流 — @@control(控制策略)

概念:模型上的 @@control(<policy>) 用于设置 Prisma 是否在迁移中管理该表的 DDL。参数是位置型小写字面量,可选值为 managed、tolerated、external 或 observed。

model AuditLog {
  id        Int    @id
  message   String

  @@control(observed)
}

可以通过 prismaContract(path, { defaultControlPolicy }) 上的 defaultControlPolicy 设置契约级默认值。有关控制策略对 DDL 规划的影响,请参阅 prisma-next-migrations。

工作流 — @prisma-next/extension-supabase

概念:Supabase 扩展提供 supabase 契约空间(将 auth / storage 模式作为 external 表,并提供平台角色),以及自己的角色优先运行时工厂。它不提供 /control 子路径,因此无法通过面向用户的 defineConfig({ extensions: [...] }) 外观注册,而是通过底层配置中的 extensions 接入。完整的实践模式请参阅 examples/supabase。

prisma-next.config.ts(与示例一致):

import supabasePack from '@prisma-next/extension-supabase/pack';
import { defineConfig } from '@prisma-next/cli/config-types';
// ... other low-level imports

export default defineConfig({
  // ...
  extensions: [supabasePack],
});

db.ts 不使用标准的 postgres() 工厂 — Supabase 应用通过 @prisma-next/extension-supabase/runtime 中的 supabase() 工厂构建客户端(角色优先:asUser(jwt) / asAnon() / asServiceRole(),JWT 验证、RLS)。该运行时以及 RLS 策略编写(policy_select / @@rls)由 prisma-next-supabase 介绍;如需了解配置接入以外的内容,请加载它。

导出子路径:@prisma-next/extension-supabase/pack、@prisma-next/extension-supabase/runtime、@prisma-next/extension-supabase/contract。规范示例:examples/supabase。

工作流 — 棕地内省

概念:从现有数据库提取契约源,并以此为基础继续操作。prisma-next contract infer --db <url> 会读取实时模式并写入 contract.prisma 文件。该命令到此为止 — 接下来分别执行 contract emit,以及(当模式与固定哈希匹配时)db sign。

pnpm prisma-next contract infer --db $DATABASE_URL --output ./src/prisma/contract.prisma
pnpm prisma-next contract emit

常见陷阱

  1. 编辑后忘记重新生成。 contract.json 和 contract.d.ts 会过时;下游类型检查和 migration plan 会看到旧结构。请重新生成,或安装 Vite 插件(prisma-next-build)。
  2. 编辑生成的文件。 contract.json 和 contract.d.ts 是生成的文件;下次生成时,对它们所做的编辑会被覆盖。请编辑源文件。
  3. TS 构建器使用了错误的工厂函数/导入路径。 defineContract、field、model、rel 来自 @prisma-next/postgres/contract-builder(或 @prisma-next/mongo/contract-builder)。在回调重载之外,可用的字段构造函数有 field.column(...)、field.generated(...)、field.namedType(...)。
  4. 在用户代码中引入内部包。 用户编写的文件(prisma-next.config.ts、contract.ts、db.ts、控制客户端)只从 @prisma-next/<target>/<subpath> 和 @prisma-next/extension-<name>/<subpath> 导入。来自 @prisma-next/cli/*、@prisma-next/family-*、@prisma-next/target-*、@prisma-next/adapter-*、@prisma-next/driver-* 或 @prisma-next/sql-contract-* 的导入属于框架内部导入——门面会为你组合这些内容。如果你的目标缺少所需的门面子路径,请参阅 Prisma Next 目前尚不支持的功能,并通过 prisma-next-feedback 提交反馈。规范示例见 examples/multi-extension-monorepo/app/prisma-next.config.ts 和 examples/prisma-next-postgis-demo/prisma-next.config.ts。
  5. 混淆配置中的 extensions 与 TS 构建器中的 extensions。 两者使用相同的扩展包,有两个不同的接口,字段名相同但结构不同:defineConfig({ extensions: [pgvector] })(来自 @prisma-next/extension-<name>/control 的控制描述符数组)与 defineContract({ extensions: { pgvector } })(来自 @prisma-next/extension-<name>/pack 的扩展包描述符记录)。
  6. 重命名字段并期望规划器检测到变更。 Prisma Next 不提供契约内的重命名提示;规划器会将其视为破坏性删除并新增。执行 migration plan 后手动编辑 migration.ts(参见 prisma-next-migrations),或使用先保留、后删除的两次迁移模式。

Prisma Next 目前尚不支持的功能

  • 契约内重命名提示。 不支持 @@rename(old: ..., new: ...) 或类似功能。请使用 常见陷阱 #6 中的变通方案。如需请求正式支持重命名,请通过 prisma-next-feedback 提交反馈。
  • 模型验证。 不提供声明式的 @validates(...) 接口。请在应用代码中验证(arktype)。如需请求在契约中加入声明式验证,请通过 prisma-next-feedback 提交反馈。
  • 生命周期回调(beforeSave、afterCreate 等)。不支持。请使用中间件(prisma-next-runtime)或应用代码。如需请求生命周期回调,请通过 prisma-next-feedback 提交反馈。
  • 软删除/paranoid: true。 不内置软删除列。请添加可空的 deletedAt DateTime?,并在查询中显式过滤(或在中间件中处理)。如需请求内置软删除,请通过 prisma-next-feedback 提交反馈。
  • 作用域/默认过滤器。 不支持 ActiveRecord 风格的作用域。请自行组合查询辅助函数。如需请求作用域,请通过 prisma-next-feedback 提交反馈。
  • 隐式 Prisma-ORM 多对多关系。 不支持双方都带列表导航但没有显式联结模型的关系。请显式编写联结模型。如需请求隐式 M2M,请通过 prisma-next-feedback 提交反馈。

参考

  • 运行 pnpm prisma-next contract --help 查看当前命令。
  • PSL 的功能范围及解释器接受的内容:packages/2-sql/2-authoring/contract-psl/README.md。
  • TS 构建器的功能范围及回调辅助工具词汇:packages/2-sql/2-authoring/contract-ts/README.md。
  • 布局(contract.prisma、contract.json、contract.d.ts 和 migrations/ 的存放位置):
    • 应用布局(src/prisma/... + migrations/app/...)——examples/prisma-next-demo 展示的布局;使用该布局的是规范形态的消费应用。
    • Contract-space-package 布局(直接放置 src/contract.{prisma,ts},migrations/<timestamp>_<slug>/ 中不含 space-id 段)——适用于扩展和聚合根包,详见 .cursor/rules/contract-space-package-layout.mdc 和 ADR 212。

检查清单

  • 阅读了 prisma-next.config.ts,并确定了契约源(以 .prisma 或 .ts 结尾的路径字符串)和已安装的 extensions: [...]。
  • 所有用户编写的导入都解析为 @prisma-next/<target>/<subpath>(例如 @prisma-next/postgres/config)或 @prisma-next/extension-<name>/<subpath>。用户文件中没有从 @prisma-next/cli/*、@prisma-next/family-*、@prisma-next/target-*、@prisma-next/adapter-*、@prisma-next/driver-* 或 @prisma-next/sql-contract-* 导入。
  • 编辑的是契约源(contract.prisma 或 contract.ts),而非生成的产物。
  • 对于新的扩展命名空间:已添加包,导入其控制描述符(@prisma-next/extension-<name>/control),将其添加到 defineConfig({...}) 中的 extensions: [...](若使用 TS 构建器,还需将匹配的 pack 描述符添加到 defineContract({extensions: {...}}))。
  • 对于重命名:在运行 migration plan 后手动编辑了 migration.ts(或使用先保留再删除的双迁移模式)——Prisma Next 目前没有重命名提示。
  • 编辑后运行了 pnpm prisma-next contract emit(或让 Vite 插件在保存时重新生成)。
  • 确认 contract.json 和 contract.d.ts 已在源文件旁更新。
  • 没有手动编辑 contract.json / contract.d.ts。
  • 没有杜撰缺失的功能(验证、回调、软删除、作用域、契约内重命名提示)——已将用户引导至 Prisma Next 目前尚未实现的功能 和 prisma-next-feedback。

评论

支持 Markdown