关于 taruvi-refine-providers
面向使用 Refine 构建 Taruvi 前端的技能,涵盖数据提供器、Hook、认证、访问控制和生产环境 UI 规范,适合实现浏览器端数据与用户流程的开发者。
主要功能
- 01Refine 提供器与 Hook 指引
- 02CRUD、存储与应用数据流程
- 03认证与访问控制
- 04生产环境 UI 规范
- 05弃用 API 迁移指引
适用场景
- 01构建分页和筛选数据表
- 02添加上传与文件管理
- 03实现登录和角色化界面
- 04执行 Taruvi 函数与分析查询
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ taruvi-ai/ taruvi-skills --skill taruvi-refine-providers安装后在 Claude Code 中输入/taruvi-refine-providers确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
eval_queries.jsonreferences/access-control-provider.mdapp-provider.mdauth-provider.mddatabase-provider.mdoverview.mdstorage-provider.mdtypes-and-utilities.mduser-provider.md详细介绍
Taruvi Refine 服务提供方(前端)
适用于 Taruvi 的单一前端技能。涵盖所有在浏览器中运行的内容:接入 @taruvi/refine-providers、针对 Taruvi 使用所有 Refine 钩子、适用于生产环境的列表/仪表板/下拉菜单/上传体验、身份验证流程和访问控制。
如果任务涉及配置资源或编写 Python 函数体,请切换到 taruvi-app-developer。
服务提供方一览
| 服务提供方 | Refine 键 | 用途 |
|---|---|---|
dataProvider(client) | default | 数据表 CRUD、筛选、分页、聚合、图表 |
storageDataProvider(client) | storage | 文件/对象上传、列出、下载、删除 |
appDataProvider(client) | app | 函数/分析执行、角色、设置、密钥(通过 useCustom / useList / useOne) |
userDataProvider(client) | user | 用户 CRUD |
authProvider(client) | authProvider prop | 登录、登出、令牌刷新、身份信息、权限 |
accessControlProvider(client) | accessControlProvider prop | 为 useCan / CanAccess 批量执行 Cerbos 检查 |
钩子支持矩阵和 meta 选项见 overview.md。
已弃用 — 请勿使用: functionsDataProvider、analyticsDataProvider。请改用 appDataProvider + useCustom,并设置 meta.kind: "function" 或 meta.kind: "analytics"。
工作流
- 阅读一次
overview.md— 安装、客户端设置,以及完整的服务提供方/钩子一览。 - 打开对应任务的参考文档(见下表)。
- 确认已安装软件包当前未弃用的 API。不要仅因为旧示例仍然存在,就用已弃用的接口编写新代码。
- 采用适用于生产环境的默认设置(见下一节)。
- 完成前按每种角色检查 UI,确认列表操作、创建按钮和菜单项均能正确显示/隐藏。
参考文档索引
| 任务 | 阅读 |
|---|---|
| 数据库 CRUD、筛选、聚合、图表 | database-provider.md |
| 文件上传、批量删除、元数据、筛选 | storage-provider.md |
| 函数执行、分析、角色、设置、密钥 | app-provider.md |
| 用户 CRUD | user-provider.md |
| 登录、登出、令牌流程、身份信息 | auth-provider.md |
useCan、CanAccess、带前缀的 ACL 资源 | access-control-provider.md |
| TypeScript 类型、已弃用接口迁移 | types-and-utilities.md |
适用于生产环境的默认设置
除非用户明确缩小范围,否则每项前端交付都必须满足以下要求。这些要求并非可选建议。
列表/表格
- 默认使用后端分页。默认
pageSize为10;提供10/20/50/100选项。 - 搜索、筛选和排序都在服务端执行 — 通过服务提供方的
filters/sorters传入,绝不在 React 中对已获取的行重复处理。 - 显示搜索输入框和相关筛选控件(状态、部门、日期范围)— 搜索防抖设为 300–500ms。
- 每个页面只保留一个主要搜索控件(不要在同一字段上同时使用
DataGrid快速筛选和单独的页面搜索)。 - MUI
DataGrid→ 使用useDataGrid。手动接线useList+ 组件状态属于有文档说明的例外,并非默认做法。
仪表板 / KPI / 图表
- 默认做法:通过
useList使用 datatable 的aggregate+groupBy,并设置meta.aggregate: ["count"](注意这是数组——aggregate: "count"会静默失败)。如需跨表查询,数据提供程序支持同时使用populate和聚合——请先尝试这种方式;对已填充的 FK 字段进行聚合通常就能满足需求。 - 分析查询是例外,而非默认做法。 仅在以下情况下使用
appDataProvider+useCustom({ meta: { kind: "analytics" } }):(a)数据源是外部数据库;或(b)SQL 确实无法通过数据提供程序表达——例如包含分组聚合的多表联接、窗口函数、递归 CTE 等。注册查询需要单独往返一次后端(taruvi-app-developer);对于单个useList配合meta.aggregate+meta.populate就能完成的任务,不要使用这种方式。 - 切勿将完整行集拉取到 React 中再计算汇总指标。
- 图查询必须设置明确的
depth。 having仅在groupBy之后生效。预聚合筛选请使用filters。
网络支持的下拉菜单
- 使用
Autocomplete(或同类的输入联想组件),不要使用静态Select。 - 使用分页后端查询(默认选项
pageSize为10),并通过防抖将搜索推送到提供程序筛选器中。不要一次性加载后在客户端筛选。
文件上传 / 附件
- 默认提供多文件操作体验。逐个报告文件成功或失败的结果——切勿将结果汇总为全成或全败。
- 分块批量上传,最多每块 10 个文件 / 100 MB;分块批量删除,最多每块 100 个路径。
- 配额仅供参考——应显示为警告,而不是阻止上传。
- 覆盖时发出警告——上传会静默替换现有路径。
- 在存储桶级别设置
visibility;对象级别的覆盖设置优先于存储桶默认值。
批量操作
- 单一资源使用后端批量操作(
updateMany、deleteMany);多资源级联使用无服务器函数。 - 清楚显示选择范围(已选行还是筛选结果集),展示部分失败的详细信息,并使受影响的查询缓存失效。
通知
使用已接入的 Refine notificationProvider(useNotification)。不要另行添加 Toast / SnackBar 系统。
契约规则(强制)
函数执行
useCustom({
url: "<function-slug>",
method: "post",
dataProviderName: "app",
payload: { /* inputs */ },
meta: { kind: "function" },
});
payload 用于传递输入——不是 values,也不是 config.payload。
分析执行
使用相同结构,并设置 meta: { kind: "analytics" }。
访问控制
useCan/CanAccess的资源必须使用带前缀的 ACL 字符串——datatable:employees、function:employee-terminate、query:hrms-dashboard-summary。绝不要使用params.entityType,也不要使用不带前缀的资源名称。- 检查前,先将 UI 操作映射到规范的 Cerbos 操作:
list/show→read,edit→update,create→create,delete→delete,函数 / 查询使用execute。 - 验证运行时载荷——
/check/resources中的resource.kind必须与请求的resource字符串完全一致。 - 不要手动对
useCan进行防抖或限流——accessControlProvider已通过 DataLoader 批处理。
客户端设置
const client = new Client({
apiKey: import.meta.env.VITE_TARUVI_API_KEY,
appSlug: import.meta.env.VITE_TARUVI_APP_SLUG,
apiUrl: import.meta.env.VITE_TARUVI_API_URL,
});
<Refine
dataProvider={{
default: dataProvider(client),
storage: storageDataProvider(client),
app: appDataProvider(client),
user: userDataProvider(client),
}}
notificationProvider={useNotificationProvider}
authProvider={authProvider(client)}
accessControlProvider={accessControlProvider(client)}
/>
环境变量使用框架用于向浏览器公开变量的前缀(VITE_*、REACT_APP_*、NEXT_PUBLIC_*)。绝不要硬编码。
值得在此提醒的易踩坑点
这些坑不易察觉。各领域的注意事项请参阅相关参考资料。
- 401 与 403 — 401 = 会话过期(重新登录)。403 = 禁止访问(显示拒绝访问)。将 403 当作 401 会导致无限循环地重新登录。
- 角色变更后
_cachedUser的处理 — 身份信息缓存在模块本地,只有调用logout()才会清除。管理员角色变更后,请强制重新登录,或使["identity"]和["access-control"]查询键失效。 - 异步函数使用
useCustom— 异步函数返回的是task_id,而不是结果。要么让函数保持同步(<30s),要么使用单独的状态检查函数接入轮询模式。 - 缺少
dataProviderName—useCustom/useCreate未设置正确的dataProviderName时,会路由到default,并返回令人困惑的“找不到资源”错误。函数/分析始终设置为"app",存储桶始终设置为"storage"。 - 表单预填字段 — 对带有默认值的 TextFields 设置
InputLabelProps: { shrink: true },避免标签重叠。 aggregate必须是数组 —aggregate: "count"会静默失败。请使用aggregate: ["count"]。- 对后端数据进行客户端筛选 — 获取一页数据后再在 React 中筛选,既会导致正确性问题,也会造成可扩展性问题。始终在 provider 查询中传入状态。