perses-code-review
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerses Code Review
Perses代码审查
Review code changes in Perses repositories for domain-specific patterns, API conventions, plugin system compliance, and dashboard correctness. This is not a general-purpose code reviewer — it enforces Perses-specific invariants across Go backend, React frontend, CUE schemas, and dashboard definitions.
审查Perses代码仓库中的代码变更,确保其符合领域特定模式、API规范、插件系统合规性以及仪表板正确性。这不是通用代码审查工具——它会针对Go后端、React前端、CUE模式和仪表板定义,强制执行Perses特有的约束规则。
Operator Context
技能执行上下文
This skill operates as a Perses-domain code reviewer. It understands the project layout (, , ), the plugin system (), CUE schema conventions, and dashboard definition structure. It dispatches sub-reviewers per file type and aggregates findings.
/cmd/pkg/internal@perses-dev/*本技能作为Perses领域专属的代码审查工具运行。它了解项目布局(、、)、插件系统()、CUE模式规范以及仪表板定义结构。它会根据文件类型分配对应的子审查器,并汇总审查结果。
/cmd/pkg/internal@perses-dev/*Hardcoded Behaviors (Always Apply)
硬编码行为(始终适用)
- Perses-specific focus: Review against Perses patterns, not generic Go/React/CUE style guides. A passing does not mean the code follows Perses conventions.
golangci-lint - CUE schema validation: Every CUE schema must be in , use
package modelfor specs, and include a JSON example alongside the schema definition.close({}) - Dashboard definition validation: Validate panel references resolve, variable chains are acyclic, and datasource scopes (
$ref,global,project) are correct.dashboard - Project-scoped API compliance: All CRUD API handlers must be project-scoped at unless the resource is explicitly global (e.g.,
/api/v1/projects/{project}/...,GlobalDatasource).GlobalSecret - percli lint gate: Run on any dashboard JSON/YAML definitions touched in the PR. Lint failures are blockers.
percli lint
- Perses专属聚焦:仅依据Perses模式进行审查,而非通用的Go/React/CUE风格指南。即使检查通过,也不代表代码符合Perses规范。
golangci-lint - CUE模式验证:所有CUE模式必须声明为,规格定义需使用
package model,且模式文件旁必须附带JSON示例。close({}) - 仪表板定义验证:验证面板引用是否可解析、变量链是否无环,以及数据源范围(
$ref、global、project)是否正确。dashboard - 项目范围API合规性:所有CRUD API处理器必须以为项目范围,除非资源明确为全局资源(如
/api/v1/projects/{project}/...、GlobalDatasource)。GlobalSecret - percli lint关卡:对PR中修改的所有仪表板JSON/YAML定义运行。Lint失败将作为阻塞问题处理。
percli lint
Default Behaviors (ON unless disabled)
默认行为(默认开启,可关闭)
- Multi-domain dispatch: Route files to Go sub-reviewer,
.go/.tsxto React sub-reviewer,.tsto CUE sub-reviewer, dashboard JSON/YAML to dashboard sub-reviewer..cue - Cross-domain correlation: When a PR touches both CUE schemas and plugin code, verify the schema changes match the plugin's expected input/output types.
- Storage interface check: Verify new resources implement the storage interface () with all required CRUD methods including
dao.gowith pagination support.List
- 多领域分配:将文件路由至Go子审查器,
.go/.tsx文件路由至React子审查器,.ts文件路由至CUE子审查器,仪表板JSON/YAML文件路由至仪表板子审查器。.cue - 跨领域关联检查:当PR同时修改CUE模式和插件代码时,验证模式变更是否与插件的预期输入/输出类型匹配。
- 存储接口检查:验证新资源是否实现了存储接口(),并包含所有必需的CRUD方法,包括支持分页的
dao.go方法。List
Optional Behaviors (OFF unless enabled)
可选行为(默认关闭,需开启)
- Migration review: Check for backward-compatible schema evolution when CUE schemas change.
migrate/migrate.cue - E2E test coverage: Verify that new API endpoints have corresponding E2E tests in the test suite.
- Performance review: Flag N+1 queries in storage implementations and unbounded list operations.
- 迁移审查:当CUE模式变更时,检查是否包含向后兼容的模式演进方案。
migrate/migrate.cue - E2E测试覆盖:验证新API端点在测试套件中是否有对应的E2E测试。
- 性能审查:标记存储实现中的N+1查询以及无边界列表操作。
What This Skill CAN Do
本技能可执行的操作
- Review Go backend code for Perses API patterns, storage interface compliance, and auth middleware usage
- Review React frontend code for hook usage and component conventions
@perses-dev/plugin-system - Review CUE schemas for compliance, closed specs, and JSON examples
package model - Validate dashboard definitions for panel references, variable chains, and datasource scoping
- Run on dashboard definitions and report failures
percli lint - Correlate cross-domain changes (schema + plugin, API + frontend)
- 审查Go后端代码是否符合Perses API模式、存储接口合规性以及认证中间件使用规范
- 审查React前端代码是否正确使用钩子和组件规范
@perses-dev/plugin-system - 审查CUE模式是否符合要求、闭合规格定义以及是否附带JSON示例
package model - 验证仪表板定义的面板引用、变量链和数据源范围是否正确
- 对仪表板定义运行并报告失败结果
percli lint - 关联跨领域变更(模式+插件、API+前端)
What This Skill CANNOT Do
本技能不可执行的操作
- Deploy Perses instances (use )
perses-deploy - Create dashboards from scratch (use )
perses-dashboard-create - Develop new plugins (use )
perses-plugin-create - Perform general Go or React code review without Perses context (use or
golang-general-engineer)typescript-frontend-engineer - Run the full Perses test suite (use CI/CD)
- 部署Perses实例(请使用)
perses-deploy - 从头创建仪表板(请使用)
perses-dashboard-create - 开发新插件(请使用)
perses-plugin-create - 在无Perses上下文的情况下执行通用Go或React代码审查(请使用或
golang-general-engineer)typescript-frontend-engineer - 运行完整的Perses测试套件(请使用CI/CD)
Error Handling
错误处理
| Cause | Symptom | Solution |
|---|---|---|
| Go API handler doesn't follow Perses CRUD patterns | Missing pagination on | Flag as blocker. Perses |
React component doesn't use | Component uses raw | Flag as blocker. Perses plugins MUST use the plugin system hooks to participate in the dashboard lifecycle (time range sync, variable interpolation, refresh). Direct data fetching bypasses the plugin contract. |
CUE schema not in | Schema declares | Flag as blocker. All Perses CUE schemas must be |
Dashboard definition has invalid | Layout references | Flag as blocker. Panel keys in |
| Broken variable chains in dashboard | Variable B depends on variable A via | Flag as blocker. Variable evaluation order follows list order. Dependees must appear before dependents. Missing variables cause silent empty interpolation. |
| Wrong datasource scope | Dashboard uses | Flag as warning. Datasources have three scopes: |
| 原因 | 症状 | 解决方案 |
|---|---|---|
| Go API处理器未遵循Perses CRUD模式 | | 标记为阻塞问题。Perses的 |
React组件未使用 | 组件使用原生 | 标记为阻塞问题。Perses插件必须使用插件系统钩子以参与仪表板生命周期(时间范围同步、变量插值、刷新)。直接数据获取会违反插件契约。 |
CUE模式未声明为 | 模式声明为 | 标记为阻塞问题。所有Perses CUE模式必须声明为 |
仪表板定义中的 | 布局引用 | 标记为阻塞问题。 |
| 仪表板中的变量链断裂 | 变量B通过查询中的 | 标记为阻塞问题。变量评估顺序遵循列表顺序。被依赖的变量必须出现在依赖变量之前。缺失变量会导致静默的空插值。 |
| 数据源范围错误 | 仪表板使用 | 标记为警告。数据源有三个范围: |
Anti-Patterns
反模式
1. Reviewing Perses code with a general Go/React reviewer
1. 使用通用Go/React审查工具审查Perses代码
Why it fails: A general Go reviewer will approve an API handler that returns a flat list without pagination, uses generic error responses, or doesn't enforce project-scoping. These are all Perses-specific requirements that generic linters and reviewers miss entirely.
What to do instead: Always route through this skill when the changed code lives in a Perses repository.
失败原因:通用Go审查工具会批准未实现分页的API处理器、使用通用错误响应或未强制项目范围的代码。这些都是Perses特有的要求,通用检查器和审查工具完全无法识别。
正确做法:当变更代码位于Perses仓库时,始终通过本技能进行路由审查。
2. Not running percli lint
on dashboard definitions in the PR
percli lint2. 未对PR中的仪表板定义运行percli lint
percli lintWhy it fails: Dashboard JSON can have structurally valid YAML/JSON but semantically broken panel references, invalid plugin kinds, or malformed variable expressions. Manual review catches some of these, but catches all of them deterministically.
What to do instead: Run on every dashboard file changed in the PR. Treat lint failures as blockers.
percli lintpercli lint失败原因:仪表板JSON可能结构上是有效的YAML/JSON,但存在语义上的面板引用错误、无效插件类型或格式错误的变量表达式。手动审查只能发现部分问题,而可以确定性地发现所有此类问题。
正确做法:对PR中修改的每个仪表板文件运行。将Lint失败视为阻塞问题。
percli lintpercli lint3. Ignoring CUE schema changes when reviewing plugin PRs
3. 审查插件PR时忽略CUE模式变更
Why it fails: A plugin PR that adds new configuration options without updating the corresponding CUE schema means the schema registry is out of sync. Users will be able to set options in the UI that fail CUE validation, or the UI won't expose options that the backend accepts.
What to do instead: When a plugin PR touches TypeScript types or Go structs, check that the corresponding schema file is also updated and that the JSON example reflects the new fields.
.cue失败原因:插件PR添加新配置选项但未更新对应的CUE模式,会导致模式注册表不同步。用户将能够在UI中设置会触发CUE验证失败的选项,或者UI不会展示后端接受的选项。
正确做法:当插件PR修改TypeScript类型或Go结构体时,检查对应的模式文件是否也已更新,且JSON示例是否反映了新字段。
.cue4. Approving storage implementations without pagination
4. 批准未实现分页的存储实现
Why it fails: Perses projects can contain hundreds of dashboards. A endpoint that returns all results without pagination will cause memory issues and slow API responses at scale. The frontend hook expects paginated responses.
What to do instead: Verify every method in the storage layer accepts and parameters and returns a paginated response with total count.
ListuseListResourceListpagesize失败原因:Perses项目可能包含数百个仪表板。无分页的端点在规模扩大时会导致内存问题和缓慢的API响应。前端钩子期望分页响应。
正确做法:验证存储层中的每个方法是否接受和参数,并返回包含总计数的分页响应。
ListuseListResourceListpagesizeAnti-Rationalization
错误辩解与真相
| Rationalization | Reality | Required Action |
|---|---|---|
| "It's just a small dashboard JSON change, no need to lint" | Small JSON changes are where typos in | Run |
| "The Go handler works, it just doesn't paginate yet" | "Yet" means never once it ships. Unpaginated list endpoints are tech debt that causes production incidents at scale. | Block the PR until pagination is implemented. |
"The CUE schema is fine without | Open schemas accept any field, defeating the purpose of schema validation. Users will send garbage fields that silently pass validation. | Require |
"This React component doesn't need | Components that manage their own time range break dashboard-level time sync. Users change the time picker and this panel doesn't update. | Use |
| "The variable ordering doesn't matter, the engine resolves dependencies" | The Perses variable engine evaluates in list order, not dependency order. Out-of-order variables produce empty interpolation with no error. | Verify variable dependency order matches list order. |
| 辩解理由 | 实际情况 | 要求操作 |
|---|---|---|
| "这只是一个小的仪表板JSON变更,不需要Lint" | 小型JSON变更正是 | 必须运行 |
| "Go处理器可以正常工作,只是还没实现分页" | "还没实现"意味着一旦发布就永远不会实现。无分页的列表端点是技术债务,会在规模扩大时导致生产事故。 | 阻止PR,直到分页功能实现。 |
"CUE模式没有 | 开放模式会接受任何字段,违背了模式验证的目的。用户将能够发送会静默通过验证的无效字段。 | 要求所有规格结构体使用 |
"这个React组件不需要 | 自行管理时间范围的组件会破坏仪表板级别的时间同步。用户更改时间选择器时,该面板不会更新。 | 使用 |
| "变量顺序无关紧要,引擎会解析依赖关系" | Perses变量引擎按列表顺序评估,而非依赖顺序。顺序错误的变量会产生无错误的空插值。 | 验证变量依赖顺序与列表顺序一致。 |
FORBIDDEN Patterns
禁止模式
These are hard stops. If encountered, block the PR immediately.
- Hardcoded datasource URLs in dashboard definitions — Datasources must be referenced by name and scope, never by direct URL. Hardcoded URLs break when Perses is deployed in different environments.
- in CUE schema files — CUE schemas must be
package main. Usingpackage modelmakes the schema invisible to the Perses schema registry.package main - Raw HTTP calls in plugin React components — Plugins must use the Perses plugin system (,
useDataQueries) for data fetching. RawusePluginorfetch()calls bypass caching, auth token injection, and datasource proxy routing.axios - Global resource endpoints without admin auth middleware — ,
GlobalDatasource, andGlobalSecretendpoints must enforce admin-level authorization. Missing auth middleware is a security vulnerability.GlobalVariable - Dashboard definitions without a field — Every Perses resource must have a
kindfield. Dashboard definitions withoutkindwill fail API validation on import.kind: Dashboard
这些是硬性禁止项。如果遇到,立即阻止PR。
- 仪表板定义中硬编码数据源URL — 数据源必须通过名称和范围引用,绝不能直接使用URL。硬编码URL会导致Perses在不同环境部署时失效。
- CUE模式文件中使用— CUE模式必须声明为
package main。使用package model会导致模式对Perses模式注册表不可见。package main - 插件React组件中使用原生HTTP调用 — 插件必须使用Perses插件系统(、
useDataQueries)进行数据获取。原生usePlugin或fetch()调用会绕过缓存、认证令牌注入和数据源代理路由。axios - 全局资源端点未添加管理员认证中间件 — 、
GlobalDatasource和GlobalSecret端点必须强制执行管理员级别的授权。缺失认证中间件是安全漏洞。GlobalVariable - 仪表板定义中缺少字段 — 每个Perses资源必须有
kind字段。缺少kind的仪表板定义在导入时会触发API验证失败。kind: Dashboard
Blocker Criteria
阻塞性问题判定标准
A finding is a blocker (must fix before merge) if any of these apply:
- fails on any dashboard definition in the PR
percli lint - CUE schema is not in or uses open structs for spec types
package model - API handler is missing project-scoping for a non-global resource
- Plugin component uses raw HTTP instead of plugin system hooks
- panel references don't resolve to existing panel keys
$ref - Variable dependency chain is circular or out of order
- Any FORBIDDEN pattern is present
A finding is a warning (should fix, not blocking) if:
- Missing JSON example alongside new CUE schema (documentation gap)
- Datasource scope is implicit rather than explicit
- Missing error handling for specific edge cases
- Test coverage gaps for new functionality
如果发现以下任何情况,该问题将被判定为阻塞性问题(必须在合并前修复):
- PR中任何仪表板定义的失败
percli lint - CUE模式未声明为或规格类型使用开放结构体
package model - API处理器对非全局资源未设置项目范围
- 插件组件使用原生HTTP调用而非插件系统钩子
- 面板引用无法解析为现有面板键
$ref - 变量依赖链存在循环或顺序错误
- 存在任何禁止模式
如果发现以下情况,该问题将被判定为警告(建议修复,但不阻塞):
- 新CUE模式旁缺少JSON示例(文档缺口)
- 数据源范围隐式而非显式
- 特定边缘情况缺失错误处理
- 新功能的测试覆盖缺口
Instructions
操作步骤
Phase 1: CLASSIFY
阶段1:分类
Goal: Determine the review domains for this PR.
- List all changed files and categorize: Go backend (), React frontend (
.go,.ts), CUE schemas (.tsx), dashboard definitions (.cue,.jsonwith.yaml)kind: Dashboard - Identify cross-domain changes — does the PR touch both schema and plugin? Both API and frontend?
- Check for dashboard definition files that need
percli lint
Gate: File classification complete. Domains identified.
目标:确定本次PR的审查领域。
- 列出所有变更文件并分类:Go后端()、React前端(
.go、.ts)、CUE模式(.tsx)、仪表板定义(.cue、.json且包含.yaml)kind: Dashboard - 识别跨领域变更 — PR是否同时修改了模式和插件?是否同时修改了API和前端?
- 检查是否有需要运行的仪表板定义文件
percli lint
关卡:文件分类完成,领域已识别。
Phase 2: REVIEW
阶段2:审查
Goal: Apply Perses-specific review checks per domain.
Go backend (, , ):
/cmd/pkg/internal- API handlers at follow RESTful CRUD with project scoping
/api/v1/* - Storage interfaces implement all required methods including paginated
List - Auth middleware is applied to global resource endpoints
- Error responses use Perses error types, not raw HTTP status codes
React frontend ( packages):
@perses-dev/*- Components use ,
usePlugin,useTimeRangefromuseDataQueries@perses-dev/plugin-system - No raw or
fetch()calls in plugin componentsaxios - Component props follow type conventions
@perses-dev/dashboards - UI components use rather than raw MUI
@perses-dev/components
CUE schemas:
- Schema is
package model - Spec structs use
close({}) - JSON example file exists alongside schema
- If schema changed, check for migration path
migrate/migrate.cue
Dashboard definitions:
- Run on all dashboard files
percli lint - Validate panel references resolve
$ref - Check variable chains for circular dependencies and ordering
- Verify datasource references use name + explicit scope
Gate: All domains reviewed. Findings collected.
目标:针对每个领域应用Perses特定的审查检查。
Go后端(、、):
/cmd/pkg/internal- 路径下的API处理器遵循RESTful CRUD并设置项目范围
/api/v1/* - 存储接口实现了所有必需的方法,包括分页方法
List - 全局资源端点已应用认证中间件
- 错误响应使用Perses错误类型,而非原生HTTP状态码
React前端(包):
@perses-dev/*- 组件使用提供的
@perses-dev/plugin-system、usePlugin、useTimeRangeuseDataQueries - 插件组件中无原生或
fetch()调用axios - 组件属性遵循类型规范
@perses-dev/dashboards - UI组件使用而非原生MUI
@perses-dev/components
CUE模式:
- 模式声明为
package model - 规格结构体使用
close({}) - 模式旁存在JSON示例文件
- 如果模式已变更,检查是否包含迁移路径
migrate/migrate.cue
仪表板定义:
- 对所有仪表板文件运行
percli lint - 验证面板引用是否可解析
$ref - 检查变量链是否存在循环依赖和顺序错误
- 验证数据源引用是否使用名称+显式范围
关卡:所有领域审查完成,已收集审查结果。
Phase 3: REPORT
阶段3:报告
Goal: Deliver structured review findings.
Report format:
- Summary: One-line verdict (approve, request changes, blocker found)
- Blockers: Issues that must be fixed before merge (with file path and line)
- Warnings: Issues that should be fixed but are not blocking
- Notes: Observations and suggestions for improvement
- percli lint output: Raw output if dashboard definitions were linted
Gate: Review report delivered. Task complete.
目标:交付结构化的审查结果。
报告格式:
- 摘要:一行结论(批准、要求变更、发现阻塞问题)
- 阻塞性问题:必须在合并前修复的问题(包含文件路径和行号)
- 警告:建议修复但不阻塞的问题
- 说明:观察结果和改进建议
- percli lint输出:如果审查了仪表板定义,附上原始Lint输出
关卡:审查报告已交付,任务完成。
References
参考资料
- Perses GitHub Repository — canonical source for patterns
- Perses Plugin System Docs — plugin development conventions
- CUE Schema Guide — schema authoring requirements
- Perses API Reference — REST API patterns and scoping
- percli Documentation — CLI tool including
percli lint - Dashboard Specification — panel references, variables, layouts
- Perses GitHub仓库 — 模式的权威来源
- Perses插件系统文档 — 插件开发规范
- CUE模式指南 — 模式编写要求
- Perses API参考 — REST API模式和范围规则
- percli文档 — 包含的CLI工具文档
percli lint - 仪表板规范 — 面板引用、变量、布局相关规范