后端业务开发
业务代码放在应用的 server/app,平台实现由 github.com/igwen6w/modu/server 提供。完整的业务示例(商品与物料附件、货币管理、员工报销与审批)已迁入独立示例插件仓库 igwen6w/modu-example-plugin,通过 Manifest app.module/example 接入;开始新模块时,可参考该插件的 Go 包 github.com/igwen6w/modu-example-plugin/server(导出 exampleplugin.Options())与前端包 @igwen6w/modu-example-web。默认 starter 只包含内置扩展,不含示例插件。
bootstrap.Options 装配
Section titled “bootstrap.Options 装配”server/application/options.go 是应用唯一装配入口:
| 字段 | 注册内容 |
|---|---|
Configure | 应用配置覆盖 |
Routes、Menus | 业务 API、菜单与权限声明 |
Authorization、AuthorizationDefaults | 统一授权的资源、能力与来源声明,以及默认安装项(仅首次安装生效) |
Migrations、Seeders | 应用表结构与初始化数据 |
DataTransfers | 数据交换合同 |
AttachmentFields | 业务附件字段 |
Resources、FakeScenarios | Agent 资源与开发测试场景 |
Deployment | 部署维护声明(访问策略与就绪要求) |
Extensions | 应用自有扩展声明及惰性注册 |
应用只追加自己的能力。核心自动提供平台内置扩展,无需复制注册清单。
声明 API 路由
Section titled “声明 API 路由”下面是示例插件中货币模块列表与创建路由的写法:
func Routes() []sdk.Route { c := NewCurrencyController() return []sdk.Route{ { Method: "GET", Path: "currencies", Permission: "example:currency:list", Handler: c.Index, }, { Method: "POST", Path: "currencies", Permission: "example:currency:create", Handler: c.Store, }, }}此代码位于示例插件的货币 package(server/app/example/currency),导入 github.com/igwen6w/modu/server/sdk。路径相对 /api/v1,实际地址为 /api/v1/currencies。权限码在权限控制台中归属于「示例 / 货币」「示例 / 报销」等分组,写法可参考示例插件 server/app/example/currency/authorization.go 与 expense/authorization.go 的授权声明。普通业务路由必须有非空权限,统一继承 JWT、操作日志与权限检查。
装配阶段拒绝核心、应用及扩展之间的路由冲突。不要另开绕过装配的业务入口。
控制器与服务
Section titled “控制器与服务”控制器负责校验输入、获取当前用户和返回统一响应;服务负责查询、事务和业务规则。常用 SDK 包括:
sdk.CurrentUserID(ctx):读取已认证的当前用户。sdk.Pagination(ctx):读取page与pageSize。sdk.Success、sdk.Error:返回统一响应。- 统一授权投影:可见拥有者与记录边界由授权投影与强制边界统一计算,不在业务代码中手工拼装拥有者集合。
数据访问范围在业务服务中显式应用。列表筛选、详情、更新、删除和批量操作均应检查边界,不能只过滤列表。
数据交换与业务附件
Section titled “数据交换与业务附件”带文件的数据交换通过 sdk.DataTransfer* 合同声明,并在 bootstrap.Options.DataTransfers 中注册;业务附件字段通过 sdk.AttachmentField 与 sdk.AttachmentContext 声明,写入时使用 sdk.ReplaceAttachments 整体替换附件集合,避免部分更新导致的数据不一致。
菜单、迁移与资源
Section titled “菜单、迁移与资源”通过同一 Options 注册 sdk.Menu、迁移和种子。页面路径以父目录路径为前缀,业务权限码与路由声明一致。
Agent 业务通过 sdk.ResourceDescriptor 注册,并可通过 ResourceDescriptor.PrepareCreate 提供创建前的回调(供 Agent 场景校验或补全字段)。HTTP 与 Agent 复用同一个业务用例,保持权限、数据范围、字段规则与幂等行为一致。Agent 侧的可选资源通过 sdk.AuthorizationResourceSelector 暴露给授权选择器。
普通业务依赖 Goravel 公开 contracts、facades 与核心 sdk。应用装配使用 bootstrap,扩展使用公开扩展合同。
不导入核心 app/models、app/services 或 Goravel 内部实现包。缺少必要接口时,在核心定义窄接口并通过新包版本交付,避免业务与核心源码重新耦合。