关于 espocrm-development
面向 EspoCRM 扩展开发的技能,涵盖模块、实体、服务、钩子和 API。重点规范元数据、EntityManager 与服务层的使用,帮助避免常见架构错误。
主要功能
- 01遵循元数据驱动架构
- 02通过 EntityManager 访问数据
- 03在 Service 中实现业务逻辑
- 04使用接口注册生命周期钩子
- 05覆盖 API、字段与扩展开发
适用场景
- 01开发自定义 EspoCRM 模块
- 02实现实体、关系和 API
- 03为数据操作构建复杂查询
- 04打包和分发扩展
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bobmatnyc/ claude-mpm-skills --skill espocrm-development安装后在 Claude Code 中输入/espocrm-development确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.jsonreferences/api-actions.mdarchitecture.mdcommon-tasks.mdcustom-field-types.mddevelopment-workflow.mdextension-packages.mdfrontend-customization.mdhooks-and-services.mdselect-builder.mdtesting-debugging.md详细介绍
EspoCRM 开发
概览
EspoCRM 是一个由元数据驱动的 CRM 平台,配置存储在 JSON 文件中,业务逻辑归属于 Service,数据访问通过 ORM EntityManager 完成。此技能可强制遵循架构模式,避免传递 Container 依赖、绕过服务层或在 hook 中实现业务逻辑等常见错误。
何时使用此技能
开发自定义 EspoCRM 模块、实体、关系、hook、服务、API 端点或集成时启用。尤其适用于: 使用 ORM(必须使用 EntityManager)、实现业务逻辑(应放在 Service 中)、创建 hook(使用接口)、修改元数据(需要重建缓存)、构建自定义字段类型、使用 SelectBuilder 创建复杂查询、实现自定义 API 操作或打包扩展。
铁律
业务逻辑放在 SERVICE 中,而不是 HOOK 中 | 通过 ENTITYMANAGER 访问数据,绝不直接使用 PDO | 绝不将 CONTAINER 作为依赖传递
直接访问 Container 或在 hook 中编写业务逻辑都违反架构要求。
核心架构原则
- 元数据驱动:实体定义、布局和字段配置都存储在 JSON 中
- 服务层:所有业务逻辑都在 Service 类中实现
- ORM EntityManager:所有数据库操作的中心访问入口
- 依赖注入:通过构造函数注入,绝不传递 Container
- Hook 系统:用于验证和副作用的生命周期事件(不用于业务逻辑)
- Repository 模式:通过 repository 访问实体
快速入门
-
设置开发环境——使用 ext-template,在
src/目录中工作(EspoCRM 7.4+),了解元数据结构:custom/Espo/Modules/{ModuleName}/Resources/metadata/ -
使用 EntityManager 访问数据
use Espo\ORM\EntityManager; public function __construct(private EntityManager $entityManager) {} // Find entity $account = $this->entityManager->getEntityById('Account', $id); // Query with conditions $collection = $this->entityManager ->getRDBRepository('Contact') ->where(['accountId' => $accountId]) ->find(); -
在 Service 中实现业务逻辑
namespace Espo\Modules\MyModule\Services; use Espo\Services\Record; class MyEntity extends Record { public function customAction(string $id, object $data): object { // Business logic here $entity = $this->entityManager->getEntityById($this->entityType, $id); // ... process ... $this->entityManager->saveEntity($entity); return $entity; } } -
为生命周期事件注册 Hook
namespace Espo\Modules\MyModule\Hooks\Account; use Espo\ORM\Entity; use Espo\Core\Hook\Hook\BeforeSave; class MyHook implements BeforeSave { public function beforeSave(Entity $entity, array $options): void { // Validation or side effects only if ($entity->isAttributeChanged('status')) { // React to changes } } } -
更改后重建缓存
bin/command rebuild
Hook 类型(接口)
EspoCRM 提供 7 种 hook 类型——始终使用接口:BeforeSave(保存前验证)、AfterSave(保存后执行副作用)、BeforeRemove(删除前验证)、AfterRemove(删除后清理)、AfterRelate(创建关系)、AfterUnrelate(移除关系)、AfterMassRelate(批量关系操作)。
导航
核心概念
- 架构:元数据系统、ORM、DI 容器、repository 模式和核心架构模式
- 开发工作流:模块创建、自定义实体、字段、API 和扩展开发流程
- Hook 与 Service:服务层实现、hook 类型、依赖注入和业务逻辑模式
高级主题
- SelectBuilder:使用 SelectBuilder 进行高级查询——复杂查询、连接、聚合和查询优化
- API 操作:创建自定义 API 端点——操作处理器、请求/响应模式和身份验证
- 自定义字段类型:构建自定义字段类型——后端、前端、元数据和集成
UI 与集成
质量保证
- 测试与调试:单元测试、调试技巧、性能优化和常见问题
关键模式
正确模式:
✅ Service with injected dependencies
✅ EntityManager for data access
✅ Hooks using interfaces
✅ Type declarations on all methods
✅ Exceptions for error handling
错误模式:
❌ Passing Container as dependency
❌ Direct PDO database access
❌ Business logic in hooks
❌ Hook base classes instead of interfaces
❌ Missing type declarations
常见错误
- 绝不要传递 Container——应注入特定依赖项
- 不要绕过 EntityManager——使用 ORM,而不是原始查询
- 业务逻辑不应放在钩子中——应使用 Services
- 始终重建缓存——修改元数据后执行
bin/command rebuild - 钩子使用接口——不要使用基类
- 所有内容都要指定类型——PHP 7.4+ 要求声明类型
- 抛出异常——不要用布尔值表示错误
与其他技能集成
- systematic-debugging:使用日志和单步调试排查 EspoCRM 问题
- verification-before-completion:声称完成前,务必通过重建缓存进行测试
- test-driven-development:为 Services 和钩子编写单元测试
总之
EspoCRM 采用元数据驱动的服务层架构。
理解元数据系统。使用 EntityManager 处理数据。在 Services 中实现业务逻辑。钩子仅用于生命周期事件。修改后重建缓存。
这就是 EspoCRM 的做法。