应用代码不含权限检查,访问规则集中在 db/policy.authz 一个文件
starter-nextjs-prisma — Next.js 启动器模板
作者 rowstile
基于 Next.js App Router 与 Prisma 的文档共享启动器,应用代码不做权限检查,访问规则集中在一个 policy 文件中,由 rowstile 编译为 Postgres 行级安全策略。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
全部页面与视图 3
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
规则由 rowstile 编译为 Postgres 行级安全策略,由数据库执行过滤与拒绝
提供 docker compose 一键启动 Postgres、迁移与应用
规则测试位于 db/tests/sharing.authz,每个测试自带数据并回滚
CI 工作流运行测试,并在 PR 中评论谁获得或失去访问权
Apache-2.0 许可,可自由使用、修改与分发
模板详细介绍
这是一个文档共享场景的启动器:用户之间、用户与团队之间共享文档,前端使用 Next.js App Router,数据层使用 Prisma 连接 Postgres。它的特殊之处在于应用代码里没有权限检查,谁可以查看和修改文档写在 db/policy.authz 这一个文件中,由 rowstile 编译成 Postgres 行级安全(RLS)策略,数据库负责过滤每次读取、拒绝规则不允许的写入。
仓库提供了可运行的本地环境:docker compose up --build 会启动 Postgres、执行迁移(建表、再应用策略)并在 localhost:3000 提供应用。初始数据包含 ann、bo、cy 三个用户,cy 属于 writers 团队,README 用这三人演示了共享与权限变化的过程。
代码结构上,db/policy.authz 是规则,db/tests/sharing.authz 是规则测试(每个测试自带数据并回滚),src/db.ts 负责以请求用户身份执行每个 Prisma 事务,app/page.tsx 与 app/actions.ts 是页面和表单且不含检查,prisma/ 存放表结构与迁移,rowstile.toml 配置策略、测试与迁移的位置,CI 工作流会运行测试并在 PR 中评论谁获得或失去访问权。
需要注意的限制:requestUser 目前信任一个任何人都能设置的 cookie,README 明确要求在他人访问前替换为真实会话;docker-compose.yml、docker/init.sql 和首个迁移中的密码仅用于本地;示例用户和团队由首个迁移创建,应删除;新增表需要自行编写迁移并授予 starter_app 权限,再在策略中定义类型和规则,没有规则的表对应用完全可读。rowstile 本身是 0.x 预览版,语言和函数在 1.0 前可能变化,且没有项目外部人员审计。
适合你的项目吗?
适用场景
- 演示基于 Postgres 行级安全的文档共享与团队协作权限
- 学习如何把权限规则从应用代码移到数据库策略中
- 作为需要文档共享与细粒度访问控制的 Next.js 项目起点
- 在本地通过 docker compose 快速运行并修改策略、观察测试反馈
适合人群
- 使用 Next.js App Router 与 Prisma 的开发者
- 希望用 Postgres 行级安全实现权限控制的团队
- 需要文档共享场景参考实现的项目
- 愿意接受 0.x 预览版工具并自行替换会话与密码的开发者
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
运行 docker compose up --build 启动 Postgres、执行迁移并在 localhost:3000 提供应用
- 2
修改规则需要 Node 22 或更高版本,并设置 ROWSTILE_OWNER_DSN 与 ROWSTILE_APP_URL
- 3
首次使用 rowstile dev 前需执行 npx rowstile push --development 标记该数据库为开发库
- 4
应用连接使用 starter_app 角色,切勿把表所有者 starter_owner 的 URL 交给应用,否则行级安全不生效
- 5
使用 rowstile dev 直接改动的数据库需用 npx prisma migrate resolve --applied 告知 Prisma 迁移已应用
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 Apache-2.0 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发;分发时需随附 Apache-2.0 许可证。
- 修改过的文件需显著标明改动,并保留相关版权、专利、商标及归属声明。
- 若原项目附有 NOTICE 文件,分发衍生作品时需保留其中适用的归属声明。
- 许可包含适用的贡献者专利授权;发起许可所述专利诉讼会终止该专利授权,且不授予商标使用权。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 Apache-2.0 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
- src/db.ts 中的 requestUser 信任任何人都能设置的 cookie,页面上的“Signed in as”会写入该 cookie。在他人访问应用前,必须将这两处替换为真实会话机制,否则身份可被伪造。
- docker-compose.yml、docker/init.sql 和首个迁移中的密码仅适用于本地笔记本环境,不可用于生产或对外部署。
- 示例用户(ann、bo、cy)和 writers 团队由首个迁移创建,仅用于 README 演示流程,实际使用时应删除这些行。
- 没有在策略中定义规则的表,应用可以完整读取其全部数据;需用 npx rowstile lint 列出这类表并补充规则。
- rowstile 处于 0.x 预览阶段,其语言和函数在 1.0 之前仍可能变化,且没有项目外部人员对其进行审计,稳定性与安全性无外部保证。
- 绝不能把表所有者 starter_owner 的数据库 URL 交给应用使用,因为行级安全对表所有者不生效,会导致权限策略失效。
查看原文依据
no-charge, royalty-free, irrevocable copyright license
许可证原文
`requestUser` in `src/db.ts` believes a cookie that anyone can set, and the page's "Signed in as" writes it. Replace both with your session before anyone else can reach the app.
README 原文
**The passwords** in `docker-compose.yml`, `docker/init.sql` and the first migration are for a laptop.
README 原文
**The people and the team** are made by the first migration, for the walk above. Delete those lines.
README 原文
A table without rules is readable by the app in full; `npx rowstile lint` lists them.
README 原文
rowstile is a 0.x preview: its language and its functions may still change before 1.0, and nobody outside the project has audited it
README 原文
https://github.com/rowstile/starter-nextjs-prisma/blob/main/LICENSEhttps://github.com/rowstile/starter-nextjs-prisma/blob/main/README.mdNever give the app the owner's URL: row-level security doesn't apply to a table's owner.
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-07。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料较完整 · 80 / 100
- 技术栈
- Next.js · React
- 网站类型
- 启动器
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2026-10-07
- 截图检查日期
- 2026-10-07
已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。
目录记录的主要技术栈是 Next.js。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
审核声明: [email protected] · 2026-10-08
查看当时使用的来源资料
SHA-256: 876fb1c473df73b1dc20bfb5a5df4ad365799b9b194da022ecb74991d8986ea8
2026-10-07T14:20:15.865Z
来源文件 / 仓库# rowstile starter: Next.js and Prisma
Documents that people share with each other and with teams, in a Next.js app (App Router) on Prisma. There
is no permission check in the app's code. Who may see and change a document is written in one file,
[`db/policy.authz`](db/policy.authz), which [rowstile](https://rowstile.dev) compiles into Postgres row-level
security: the database filters every read and refuses every write the rules don't allow.
## Run it
docker compose up --build
That starts Postgres, runs the migrations (the tables, then the policy) and serves the app on
<http://localhost:3000>. Three people are there: ann, bo and cy, and cy is in the team "writers".
1. Sign in as **ann** and create a document.
2. Sign in as **bo**: the list is empty. The document isn't hidden by the page; Postgres doesn't return it.
3. As ann, share it with bo as a **viewer**. Bo now sees it. When he renames it, the database refuses, and
the page shows the rule and what was missing.
4. As ann, share it with the team **writers** as **editor**. Cy, a member, renames it.
## What is where
| | |
|---|---|
| [`db/policy.authz`](db/policy.authz) | the rules: who owns, who may share, what a viewer and an editor may do |
| [`db/tests/sharing.authz`](db/tests/sharing.authz) | the rules' tests: each brings its own rows and is rolled back |
| [`src/db.ts`](src/db.ts) | Prisma, signed in as the request's user on every transaction |
| [`app/page.tsx`](app/page.tsx), [`app/actions.ts`](app/actions.ts) | the page and its forms, with no checks in them |
| [`prisma/`](prisma/) | the tables, and Prisma's migrations; the policy is one of them |
| [`rowstile.toml`](rowstile.toml) | where the policy, its tests and its migrations are |
| [`.github/workflows/ci.yml`](.github/workflows/ci.yml) | the tests, and on a pull request a comment that says who gains or loses access |
Two roles connect to the database. `starter_owner` owns the tables and runs the migrations: its URL is
`ROWSTILE_OWNER_DSN`, which Prisma uses. The app connects as `starter_app` (`ROWSTILE_APP_URL`), which
row-level security applies to. Never give the app the owner's URL: row-level security doesn't apply to a
table's owner.
## Change the rules
You need Node 22 or later. With the containers up:
npm install
export ROWSTILE_OWNER_DSN=postgresql://starter_owner:owner@localhost:15432/starter
export ROWSTILE_APP_URL=postgresql://starter_app:app@localhost:15432/starter
npx rowstile push --development # once: migrations set this database up, so say it is a development one
npx rowstile dev # on every save: check, apply to this database, run the tests
Edit `db/policy.authz` (say, let an editor share: `can share = owner or editor`) and watch `rowstile dev` say
which tests now fail. When the change is what you want:
npx rowstile migrate # writes the next Prisma migration, from db/policy.lock
npm test # the app's own tests (npx prisma generate first, once)
`rowstile dev` changes this database directly, which is fine on your laptop, and it then already holds what
the new migration brings. So on this database `npx prisma migrate deploy` stops at that migration (AZ607):
tell Prisma it is applied, `npx prisma migrate resolve --applied <the new migration's folder>`. Any other
database takes migrations only. To start over, `docker compose down -v`.
## Make it yours
- **Who the request is.** `requestUser` in `src/db.ts` believes a cookie that anyone can set, and the page's
"Signed in as" writes it. Replace both with your session before anyone else can reach the app.
- **The passwords** in `docker-compose.yml`, `docker/init.sql` and the first migration are for a laptop.
- **The people and the team** are made by the first migration, for the walk above. Delete those lines.
- **Your tables.** Add them to `prisma/schema.prisma`, write their migration (with their grants to
`starter_app`), then give them a type and rules in the policy. A table without rules is readable by the
app in full; `npx rowstile lint` lists them.
rowstile is a 0.x preview: its language and its functions may still change before 1.0, and nobody outside
the project has audited it ([how it is checked](https://rowstile.dev/how-it-is-checked)). The docs:
[Next.js and Prisma](https://rowstile.dev/stacks/nextjs), [the policy language](https://rowstile.dev/reference/language),
[the cookbook](https://rowstile.dev/cookbook/).
This starter is yours to take and change: [Apache-2.0](LICENSE).
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

ai-website-cloner-template
Clone any website with one command using AI coding agents
Next.js · 启动器

Next.js SaaS Starter
Next.js SaaS Starter 是 Next.js 官方维护的 SaaS 起点模板,定位介于学习资源和可直接部署的脚手架之间。
Next.js · SaaS

Next.js Commerce
Next.js Commerce 是 Vercel 团队维护的电商启动模板,基于 Next.js App Router 构建,采用服务端渲染、React Server Components、Server Actions …
Next.js · 电商

Next-js-Boilerplate
Next-js-Boilerplate 是一个面向 Next.js 16、Tailwind CSS 4 和 TypeScript 的启动器,核心定位是开发者体验优先。
Next.js · 启动器

tailwind-nextjs-starter-blog
tailwind-nextjs-starter-blog 是一个面向个人技术博客的 Next.js 与 Tailwind CSS 启动模板,其 v2 版本基于 App Router 与 React Server Comp…
Next.js · 博客

next-forge
Production-grade Turborepo template for Next.js apps.
Next.js · 启动器
