Activepieces 服务端后端开发指南:从 Fastify 控制器到数据库迁移的工程规范
Activepieces 服务端后端开发指南从 Fastify 控制器到数据库迁移的工程规范【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepiecesActivepieces 服务端 API 位于packages/server/api是面向 AI 工作流自动化的核心后端服务。本指南以仓库中的服务端 Agent 定义.claude/agents/server.md及其引用的 服务端开发规范 为主体结合packages/server/api的源码实现系统讲解控制器编写、数据库实体与迁移注册、安全访问控制、结构化日志等工程规范帮助你快速上手为 Activepieces 后端贡献代码或理解其架构。技术栈总览Activepieces 服务端采用一套高度聚焦的 TypeScript 技术栈见 packages/server/AGENTS.md关注点选型Web 框架Fastify 5ORM / 数据库TypeORM PostgreSQL社区版另支持 SQLite / PGlite 测试环境作业队列BullMQ基于 Redis缓存 / Redis 客户端ioredis请求校验fastify-type-provider-zodZod schema 驱动可观测性evlog 结构化宽事件Wide Events通过AP_OTEL_ENABLED开启 OTLP 日志导出语言TypeScriptstrict 严格模式一个值得注意的设计是控制器路由的类型校验完全交给 Zod而不是 Fastify 默认的 JSON Schema 或旧的 Typebox 方案。fastify-type-provider-zod会在编译期把 Zod schema 推导为 Fastify 可用的类型请求参数、响应体与运行时校验三者天然一致。服务端代码结构packages/server/api的源码按以下层次组织对应packages/server/AGENTS.md的 Project Structure 章节src/app/— 业务功能模块flows流程、pieces组件、tables表格、authentication认证、webhooksWebhook、agents智能体等每个模块通常由 controller路由、service业务逻辑、entityORM 实体三类文件组成src/app/ee/— 企业版功能SSO、SAML、SCIM、多租户、平台计划计费等严格与社区版CE隔离src/app/database/— TypeORM 连接配置与数据库迁移src/app/helper/— 服务端共享工具系统配置、异常处理、日志等。从 app.ts 可以看到setupApp是服务端装配入口注册 OpenAPISwaggerSchema、内容类型解析器随后逐个app.register(module)注册几十个功能模块。后端开发的五条关键规则服务端 Agent 定义.claude/agents/server.md中给出了五条不易察觉但必须遵守的规则它们是理解这个代码库的钥匙1. 新实体必须注册进getEntities()所有 TypeORM 实体统一在src/app/database/database-connection.ts的getEntities()函数中登记。新增实体后若忘记注册TypeORM 的数据源将无法感知该实体导致建表、查询、关系加载全部失效。当前注册列表database-connection.ts已包含 70 实体覆盖FlowEntity、FlowRunEntity、AppConnectionEntity、AgentEntity、McpServerEntity、TableEntity等并明确按 Enterprise企业版、CLOUD云端分区注释组织。这些实体通过commonProperties.entities注入到 PostgreSQL、SQLite、PGlite 三种数据源。2. 新迁移必须注册进getMigrations()数据库迁移统一注册在src/app/database/postgres-connection.ts的getMigrations()函数中postgres-connection.ts该文件按时间线累积了数百个 TypeORM 迁移类并区分了 Enterprise Only、Community Only、Cloud Only 等来源。连接配置同文件 L891-L897强制const migrationConfig: MigrationConfig { migrationsRun: true, // 启动时自动执行未跑的迁移 migrationsTransactionMode: each, // 每个迁移独立事务 migrations: getMigrations(), synchronize: false, // 严禁 synchronizeschema 变更只能走迁移 }migrationsRun: truesynchronize: false的组合是这套数据库方案的安全基石启动即自动迁移但绝不通过实体自动同步 schema。测试环境的 PGlite 连接pglite-connection.ts则在非测试环境才执行迁移测试时允许synchronize。3. 控制器使用FastifyPluginAsyncZod而非 Typebox所有控制器必须是FastifyPluginAsyncZod类型的 Fastify 插件。以智能体工具的 MCP 校验控制器为例agent-tools-controller.tsimport { FastifyPluginAsyncZod } from fastify-type-provider-zod import { z } from zod import { securityAccess } from ../core/security/authorization/fastify-security export const agentToolsController: FastifyPluginAsyncZod async (app) { app.post(/mcp/validate, ValidateMcpToolRequest, async (req) { return mcpToolValidator.validateAgentMcpTool(req.body) }) } const ValidateMcpToolRequest { config: { security: securityAccess.project([PrincipalType.USER], Permission.WRITE_FLOW, { type: ProjectResourceType.PARAM, }), }, schema: { tags: [agent], description: Probe an external MCP server configured as an agent tool ..., params: z.object({ projectId: ApId }), body: AgentMcpTool, }, }每个路由定义由config.security安全访问控制与schemaZod 校验params / query / body / tags / description构成description会同步进 OpenAPI 文档。4. EE 代码只进src/app/ee/CE 永不 import EE社区版CE代码严禁 import 企业版EE模块企业功能必须隔离在src/app/ee/下。这一点从 app.ts 的导入清单即可印证agentModule、scimModule、platformPlanModule、auditEventModule等企业模块全部来自./ee/...路径而社区模块flows、pieces、authentication则直接位于./flows/...等目录两者在目录层面物理隔离。5. 每个端点都必须配置securityAccess查询必须按projectId/platformId过滤安全是强制性的。securityAccess工厂fastify-security.ts提供了一组声明式访问控制构造器构造器语义securityAccess.project(allowedPrincipals, permission, projectResource)项目级访问从请求的 body / query / param 或数据库表解析projectId校验主体是该项目成员可选校验PermissionsecurityAccess.platformAdminOnly(allowedPrincipals)仅平台管理员securityAccess.publicPlatform(allowedPrincipals, projectResource?)平台级公开路由需认证但无需管理员securityAccess.engine()/securityAccess.worker()仅限 Engine / Worker 内部主体调用均为unscoped特例securityAccess.public()完全公开无需认证securityAccess.unscoped(allowedPrincipals)无平台/项目作用域用于 Worker 等不含platformId的主体projectResource支持ProjectTableResource通过数据库表反查实体所属项目、ProjectQueryResource、ProjectBodyResource、ProjectParamResource四种解析方式最终把解析出的projectId挂到request.projectId上供业务使用。而所有查询必须按projectId/platformId过滤则保证多租户数据永不越界——这是 Activepieces 多项目、多平台架构EE 多租户的数据隔离底线。模块包装器与路由前缀的归属packages/server/AGENTS.md强调了一个重要约定模块包装器*.module.ts拥有路由前缀。app.ts中每个功能只以await app.register(module)注册且不内联prefix前缀定义在模块文件内部。以 agents-module.ts 为例export const agentsModule: FastifyPluginAsyncZod async (app) { await app.register(agentToolsController, { prefix: /v1/projects/:projectId/agent-tools }) }禁止在app.ts中直接带prefix注册控制器应创建薄薄的*.module.ts包装器使路由身份与处理器同处一个文件避免前缀漂移。更多工程约定HTTP 方法、数组列与缓存键HTTP 方法所有创建与更新操作一律使用POST不使用PUT/PATCHTypeORM 数组列必须使用统一模式——{ type: String, array: true, nullable: false }保证跨 PostgreSQL 方言的一致性缓存键版本化通过distributedStore写入的缓存值若改变结构必须在键构造器中升级版本段如platform_plan:billing-overview:v1:${platformId}→:v2:。原因在于滚动部署期间旧代码会读到新结构写入的条目、反之亦然且z.optional(z.nullable(...))会让缺失字段静默通过响应校验造成无报错的降级输出。键必须带 TTLttlInSeconds否则旧条目将永久残留。防止 N1 查询packages/server/AGENTS.md明确禁止先查集合、再循环逐条查详情的 N1 反模式要求用 JOIN、子查询或IN子句把过滤与富化压进单条 SQL跨关联行判断条件时如是否有任意成员拥有权限 X在 SQL 侧 JOIN 后过滤而不是把行全部载入 JS 内存再过滤列表端点富化关联数据时优先leftJoinAndSelect/innerJoin或IN (:...ids)批量查询避免在Promise.all/.map()中逐条查库。结构化日志字段规范evlog服务端所有结构化日志经由logger.{info,warn,error,debug}({ fields }, msg)与wideEvent输出字段键是仪表盘、告警与 OTLP 数据管道的可查询 Schema必须遵守一个概念 一条路径按实体分组实体自身的 id 放在组内id字段禁止顶层裸runId/flowRunId/id——例如流程运行记作flowRun: { id }扁平化为flowRun.id。历史上同一运行 id 曾分别记作runId、flowRunId、id三种形式导致关联查询全部失效属性与 id 同组{ jobId, jobType }→job: { id, type }错误统一用errorap-logger.ts会把err归一化为error单位作为叶子键后缀时长durationMs、字节Bytes、计数Count/复数保留键禁写service、version、level、msg、timestamp、requestId、traceId、method、path等由框架自动填充。规范中还给出了权威分组清单flowRun: { id, status, environment }、flow: { id, version }、project: { id }、job: { id, type }、piece: { name, version }、webhook: { id, requestId, mode, flowFound, responseStatus }、tool: { name, callId, phase, durationMs }等。注意日志元数据才需要分组数据模型与线上字段保持扁平如JobData.runId、resumeFromWaitpoint({ flowRunId })。版本检测与滚动部署安全apVersionUtilapVersionUtil.getCurrentRelease()从process.cwd()/package.json读取运行版本以 cwd 为基准而非模块路径打包产物中__dirname不可用。读取失败时记 warn 并返回哨兵值UNKNOWN_VERSION0.0.0。App 与 Worker 之间的版本调度门禁通过apVersionUtil.versionsAreCompatible()做**失败关闭fail-closed**判定任一侧为undefined旧版无门禁的 Worker→ 不兼容任一侧为0.0.0读取失败→ 不兼容即使两侧都是0.0.0也一样——都读失败不等于同一版本两个不同构建可能同时报0.0.0相等判断会让版本错配的 Worker 静默跑坏流程其余情况 → 两侧真实版本相等才兼容。两个进程都在启动阶段前置调用assertReleaseReadable暴露读取失败App 在appPostBootapp.ts、Worker 在worker.start()读取失败以error级别记日志该状态不会随部署完成自愈需人工介入。版本与 Worker 错配信息还通过GET /v1/health/system的release块展示在平台健康页。该行为由packages/server/utils/test/ap-version.test.ts固化修改哨兵值、读取策略或兼容规则时必须同步更新测试。其他服务端细则邮件模板位于src/assets/emails/采用左对齐 F 型布局、白色卡片、白标变量{{fullLogoUrl}}、{{primaryColor}}、{{platformName}}禁用硬编码品牌名兼容 Outlook!--[if mso]覆盖不依赖外部样式表修改前先读规范服务端 Agent 要求动手前先阅读 packages/server/AGENTS.md涉及任一模块时先阅读brain/area/name.md知识文档数据库 schema 变更必须走迁移不得直接改实体优先复用既有端点新增端点会复制校验、缓存、安全配置、文档与测试面且平行端点易漂移过滤器、缓存策略、响应形状不一致只有现有路由无法满足场景时才新增。以上约定共同构成了 Activepieces 服务端的开发心智模型Zod 驱动的类型安全路由、声明式安全访问控制、迁移优先的数据库演进、实体分组的宽事件日志以及面向滚动部署的失败关闭版本门禁。无论是新增一个端点、一张表还是排查一个线上问题这五条规则与配套的模块组织方式都是绕不开的起点。【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →