关于 frappe-agent-validator
面向 Frappe 和 ERPNext 代码审查的验证 Agent,依据 61 个技能涵盖的知识检查多种代码类型,并按严重程度输出问题与修复建议。
主要功能
- 01识别代码类型并运行对应检查
- 02检查安全、性能及错误处理
- 03覆盖 Server Script、客户端脚本与控制器
- 04检查 hooks.py、DocType JSON 和运维操作
- 05支持快速、标准和深入验证层级
- 06生成含问题与修复建议的报告
适用场景
- 01部署前审查生成的 Frappe 代码
- 02排查 Server Script 或客户端脚本错误
- 03检查 hooks.py 与 DocType 配置
- 04进行生产环境代码和运维审查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-agent-validator安装后在 Claude Code 中输入/frappe-agent-validator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/checklists.mdexamples.mdworkflow.md详细介绍
Frappe 代码验证 Agent
根据完整的 61 项技能知识库验证 Frappe/ERPNext 代码,在部署前发现错误。
目的:在部署前而非部署后发现错误
何时使用此 Agent
CODE VALIDATION TRIGGERS
|
+-- Code has been generated and needs review
| "Check this Server Script before I save it"
| --> USE THIS AGENT
|
+-- Code is causing errors
| "Why isn't this working?"
| --> USE THIS AGENT
|
+-- Pre-deployment validation
| "Is this production-ready?"
| --> USE THIS AGENT
|
+-- Code review for best practices
| "Can this be improved?"
| --> USE THIS AGENT
|
+-- Ops/deployment validation
| "Is my bench setup correct?"
| --> USE THIS AGENT
验证工作流
STEP 1: IDENTIFY CODE TYPE
Client Script | Server Script | Controller | hooks.py |
Jinja | Whitelisted | Bench/Ops | DocType JSON
STEP 2: RUN TYPE-SPECIFIC CHECKS
Apply checklist for identified code type
STEP 3: CHECK UNIVERSAL RULES
Error handling | Security | Performance | User feedback
STEP 4: VERIFY VERSION COMPATIBILITY
v14/v15/v16 features | Deprecated patterns
STEP 5: VALIDATE AGAINST SKILL CATALOG
Cross-reference with relevant frappe-* skills
STEP 6: GENERATE VALIDATION REPORT
Critical errors | Warnings | Suggestions | Corrected code
详细步骤请参阅 references/workflow.md。
按代码类型划分的关键检查项
Server Script 检查项
| 检查项 | 严重性 | 模式 | 修复方法 |
|---|---|---|---|
| 导入语句 | 致命 | import X 或 from X import Y | 直接使用 frappe.utils.X() |
| 错误的文档变量 | 致命 | self.field 或 document.field | 使用 doc.field |
| 用途对应的事件错误 | 错误 | 在 on_update 中编写验证代码 | 移至 validate 事件 |
| try/except 代码块 | 警告 | try: ... except: | 验证时使用 frappe.throw() |
| 未进行空值检查 | 警告 | doc.field.lower() | 添加 if doc.field: 保护条件 |
Client Script 检查项
| 检查项 | 严重性 | 模式 | 修复方法 |
|---|---|---|---|
| 调用服务端 API | 致命 | frappe.db.get_value() | 使用 frappe.call() |
| 缺少异步处理 | 致命 | let x = frappe.call() | 使用回调或 async/await |
| set_value 后未刷新 | 错误 | 单独使用 frm.set_value() | 添加 frm.refresh_field() |
| 使用 cur_frm | 警告 | cur_frm.doc.field | 使用 frm 参数 |
| 未检查表单状态 | 警告 | 缺少 __islocal/docstatus | 添加状态保护条件 |
Controller 检查项
| 检查项 | 严重性 | 模式 | 修复方法 |
|---|---|---|---|
| 在 on_update 中使用 self.* | 致命 | 在 on_update 中使用 self.field = X | 使用 self.db_set() |
| 循环保存 | 致命 | 在生命周期钩子中使用 self.save() | 移除 self.save() |
| 缺少 super() | 错误 | 重写方法时未调用 super() | 添加 super().method() |
| v16 extend_doctype_class | 错误 | 混入中缺少 super() | 始终先调用 super() |
| 没有类型注解 | 建议 | 缺少类型提示(v16) | 添加类型注解 |
hooks.py 检查项
| 检查项 | 严重性 | 模式 | 修复方法 |
|---|---|---|---|
| Python 语法无效 | 致命 | 语法错误 | 修复 dict/list 结构 |
| 事件名称错误 | 致命 | 事件名称拼写错误 | 使用正确的事件名称 |
| 函数路径无效 | 致命 | 点分路径错误 | 确认路径存在 |
| 在 v14/v15 中使用仅适用于 v16 的钩子 | 错误 | extend_doctype_class | 改用 doc_events |
| 缺少 required_apps | 警告 | 未声明依赖项 | 添加所有依赖项 |
Ops/Bench 检查项
| 检查项 | 严重性 | 模式 | 修复方法 |
|---|---|---|---|
| 修改 hooks 后未迁移 | 致命 | hooks.py 已更改,但未迁移 | 运行 bench migrate |
| bench 命令语法错误 | 错误 | CLI 参数不正确 | 检查 frappe-ops-bench |
| 升级前未备份 | 错误 | 未备份便执行升级 | 始终先备份 |
| 生产环境未使用 supervisor | 警告 | 未使用进程管理器 | 使用 supervisor/systemd |
| 生产环境未配置 SSL | 警告 | 仅使用 HTTP 部署 | 配置 SSL/TLS |
DocType JSON 检查项
| 检查项 | 严重性 | 模式 | 修复方法 |
|---|---|---|---|
| 缺少必填字段 | 错误 | 没有主要标识符 | 添加 name 或 autoname |
| 字段名重复 | 致命 | 同一字段名出现两次 | 使用唯一字段名 |
| 数据类型对应的字段类型错误 | 警告 | 短值使用 Text | 使用 Data/Small Text |
| 未定义权限 | 警告 | 权限列表为空 | 添加角色权限 |
v16 专属验证
extend_doctype_class 模式
# VALIDATE: Mixin class MUST call super()
class CustomSalesInvoice(SalesInvoice):
def validate(self):
super().validate() # REQUIRED - never skip
self.custom_validation()
def on_submit(self):
super().on_submit() # REQUIRED - never skip
self.custom_on_submit()
类型注解(v16 最佳实践)
# v16 recommended pattern
def get_customer_balance(customer: str) -> float:
...
# Validate: type hints on public API methods
@frappe.whitelist()
def process_order(order_name: str, action: str = "approve") -> dict:
...
数据脱敏(v16)
# Validate: sensitive fields should use data masking
# Check if PII fields have mask_with configured in DocType JSON
通用验证规则
安全检查(所有代码类型)
| 检查项 | 严重性 | 描述 |
|---|---|---|
| SQL 注入 | CRITICAL | SQL 中包含未经处理的用户输入 |
| 权限绕过 | CRITICAL | 缺少权限检查 |
| XSS 漏洞 | HIGH | HTML 中包含未经转义的用户输入 |
| 敏感数据泄露 | HIGH | 记录密码 / 令牌 |
| 硬编码凭据 | CRITICAL | 源代码中包含 API 密钥 |
性能检查(所有代码类型)
| 检查项 | 严重性 | 描述 |
|---|---|---|
| 循环中的查询 | HIGH | frappe.db.* 出现在 for 循环中 |
| 无界查询 | MEDIUM | SELECT 未使用 LIMIT |
| 不必要的 get_doc | LOW | get_value 足以满足需求时仍使用 get_doc |
| 缺少索引 | MEDIUM | 对非索引字段进行筛选 |
| 未进行批量提交 | HIGH | 批量操作中每条记录都提交 |
错误处理检查(所有代码类型)
| 检查项 | 严重性 | 描述 |
|---|---|---|
| 静默失败 | HIGH | except: pass 且未记录日志 |
| 缺少用户反馈 | MEDIUM | 未向用户显示错误 |
| 通用错误消息 | LOW | “An error occurred” |
| 失败时未回滚 | HIGH | 出错时留下部分数据 |
验证报告格式
始终按此格式生成报告:
## Code Validation Report
### Code Type: [type]
### Target: [DocType / App / File]
### Event/Trigger: [if applicable]
### CRITICAL ERRORS (Must Fix)
| # | Line | Issue | Fix |
|---|------|-------|-----|
### WARNINGS (Should Fix)
| # | Line | Issue | Recommendation |
|---|------|-------|----------------|
### SUGGESTIONS (Nice to Have)
| # | Line | Suggestion |
|---|------|------------|
### Corrected Code
[If critical errors found, provide corrected version]
### Version Compatibility
| Version | Status | Notes |
|---------|--------|-------|
| v14 | [status] | |
| v15 | [status] | |
| v16 | [status] | |
### Referenced Skills
- frappe-skill-name: [what was validated against]
验证深度级别
| 级别 | 检查项 | 适用场景 |
|---|---|---|
| 快速 | 仅致命错误 | 初始扫描 |
| 标准 | + 警告 + 安全 | 部署前(默认) |
| 深度 | + 建议 + 性能 + 运维 | 生产环境审查 |
技能目录交叉引用
此验证器会根据全部 61 个 frappe-* 技能进行验证:
语法验证(11 项技能)
frappe-syntax-clientscripts、frappe-syntax-serverscripts、frappe-syntax-controllers、frappe-syntax-hooks、frappe-syntax-hooks-events、frappe-syntax-whitelisted、frappe-syntax-jinja、frappe-syntax-scheduler、frappe-syntax-customapp、frappe-syntax-doctypes、frappe-syntax-reports
实现验证(12 项技能)
frappe-impl-clientscripts、frappe-impl-serverscripts、frappe-impl-controllers、frappe-impl-hooks、frappe-impl-whitelisted、frappe-impl-jinja、frappe-impl-scheduler、frappe-impl-customapp、frappe-impl-reports、frappe-impl-workflow、frappe-impl-website、frappe-impl-ui-components、frappe-impl-integrations
错误模式验证(7 项技能)
frappe-errors-clientscripts、frappe-errors-serverscripts、frappe-errors-controllers、frappe-errors-hooks、frappe-errors-api、frappe-errors-permissions、frappe-errors-database
核心模式验证(7 项技能)
frappe-core-database、frappe-core-permissions、frappe-core-api、frappe-core-workflow、frappe-core-notifications、frappe-core-files、frappe-core-cache
运维验证(8 项技能)
frappe-ops-bench、frappe-ops-deployment、frappe-ops-backup、frappe-ops-performance、frappe-ops-upgrades、frappe-ops-cloud、frappe-ops-app-lifecycle、frappe-ops-frontend-build
测试验证(2 项技能)
frappe-testing-unit、frappe-testing-cicd
快速验证命令
服务端脚本:5 点检查
- 是否有
import语句?--> 致命错误 - 是否有
self.引用?--> 致命错误(请使用doc.) - 是否有
try/except?--> 警告(通常不正确) - 是否使用
frappe.throw()进行验证?--> 良好 - 是否使用
doc.field访问?--> 良好
客户端脚本:5 点检查
- 是否调用
frappe.db.*?--> 致命错误 - 是否调用
frappe.get_doc()?--> 致命错误 frappe.call()是否未提供回调?--> 致命错误- 是否使用
frm.doc.field访问?--> 良好 - 更改后是否使用
frm.refresh_field()?--> 良好
控制器:5 点检查
- 是否在
on_update中修改self.*?--> 致命错误 - 是否缺少
super().method()调用?--> 错误 - 是否在生命周期钩子中调用
self.save()?--> 致命错误 - 文件顶部是否有导入语句?--> 良好
- 是否对外部调用进行错误处理?--> 良好
hooks.py:5 项检查
- Python 语法有效?--> 检查
- 函数路径存在?--> 检查
- 仅限 v16 的钩子已标记?--> 检查
- required_apps 完整?--> 检查
- Fixture 过滤器已添加?--> 检查
Bench/Ops:5 项检查
- 更改后运行
bench migrate?--> 必须 - 执行破坏性操作前备份?--> 必须
- 已启用调度器?--> 检查
- 工作进程正在运行?--> 检查
- 已配置 SSL(生产环境)?--> 检查
完整检查清单请参阅 references/checklists.md。 验证示例请参阅 references/examples.md。