中后台脚手架 / v1.0.0
登录、权限、列表,
已经写好了。
认证、权限、列表、表单、文件、支付、队列和审计都接好了。克隆下来,改 schema 和 action 就能写业务。
vinext · React 19 · Prisma 7 · Better-Auth
OVERVIEW
工作台概览
今日访问
12,480
+18.2%
新增用户
128
+6.4%
待处理
9
需跟进
近 7 日收款
+18.2%创建部门
陈伟 · 2 分钟前
更新角色
林岚 · 18 分钟前
¥45,231.89
账户余额
61
页面路由
admin · user · auth
39
数据模型
Prisma models
9
能力插件
*.plugin.ts
2
认证体系
admin · user
01
Capabilities
这些能力,不用再写一遍。
新增业务时只考虑字段、事务和数据范围。认证、权限、列表、错误提示,框架里都有现成入口。
两套登录,互不影响
管理员和用户是两张表、两套 Cookie、两个 Better-Auth 实例。退出一个,不会把另一个带下线。
ADMIN
管理后台
独立会话 · 独立登出
USER
用户门户
独立表 · 独立 Cookie
写操作统一走 Action
页面调用 createAdminAction,Zod 校验、BizError、表单错误提示由工厂处理。
createAdminAction(schema)(
async (input) => {
await db.department.create(input)
}
)
按钮也有权限
用户 → 角色 → 权限 → 菜单。没权限的按钮不渲染,不是点了才报错。
列表交给 DataView
db.<model>.load 取数,分页、排序、筛选写进 URL。
按域拆插件
一个能力域一个 *.plugin.ts;plugin:init 生成注册表。
plugin:init 生成注册表
Agent 能调管理接口
admin-cli 把管理操作登记成 OpenAPI 3.0;龙虾 Agent 和助手页可以直接调用。
› 查询本月待处理订单
payment.orders.list · filter: PENDING
→ 9 条结果,按金额排序
02
How it works
新增一个能力,按这四步走。
插件声明能力,Action 处理写操作,db.load 读列表,页面只负责展示。每层都能单独测。
能力域
*.plugin.ts 里声明菜单、权限、队列和事件;plugin:init 生成注册表。
动作
页面调用 create*Action;Zod 校验、BizError、错误提示在工厂里统一。
数据
db.<model>.load 处理分页、排序、筛选;筛选条件写进 URL。
表面
@repo/ui + 语义 token;Admin 和 User 各自独立,不共用 token。
// 能力域:菜单、权限、队列一起注册
export const departmentPlugin = definePlugin({
id: 'sys-admin.department',
menus: ['system:department'],
})
// 写操作:工厂 + Zod + BizError
export const createDepartment = createAdminAction(
departmentSchema,
)(async (input) => {
const dept = await db.department.create({ data: input })
return dept
})
// 列表:服务端取数,状态进 URL
const page = await db.department.load({
page, filter, sort,
})01
bun run module <name>
生成模块
列表、Action、模型和菜单权限一次生成。
02
schema.ts · actions.ts
补业务规则
在 schema 和 action 里补字段、事务、数据范围。
03
DataView · Dialog
接列表和表单
DataView 读列表,Dialog 做新建和编辑。
04
bun run verify
跑 verify
干净目录里重装依赖,类型、测试、迁移、构建一起跑。
03
Modules
点得进去的模块,才算数。
每个入口都有真实路由和权限;没权限的菜单不会出现,接口还会再校验一次。