games-development-ai/.agents/skills/add-business-module.md
lili a207cb8d65
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
docs(agents): skill 规范化双层收口 + 席位context skill 新增 + W-NSTAR/W-TPL/W-GENLOG 设计波落档
- .agents/skills 25 件全量 frontmatter 规范化与评审修入(含 prompt-governance 大修);.claude/skills 7 件薄壳按双层方案①落位
- 新增 skill:agentic-seat-context-design(agentic 席位与 context 工程设计基线,2026-07-05 探索蒸馏)
- 设计波三件落档:复杂游戏北极星件(W-NSTAR 终审稿待拍)/黄金模板规格件(W-TPL 定稿待批)/生成侧过程蒸馏回路(W-GENLOG 骨架)
- protocol/在飞板/作战清单/数据飞轮 SoT/契约 prompts 索引同步;breakout 九门证据刷新
- .gitignore 补 /localagents.md 真实忽略行(该文件自声明绝不提交,此前声明未被机器执行)
- 刻意不入库:nacos-data/ 与 _tier2-gen、c2v-*、amgen-* 生成产物(可重生成,忽略行格式待拍)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 05:32:56 -07:00

15 KiB
Raw Blame History

name, description
name description
add-business-module 当在 game-cloud 后端新增一个 game-module 业务模块时使用:-api 契约 + -server 实现的双 Maven 结构、controller/service/dal 分层、错误码独占段、Flyway 迁移、两处装配、单测/集成测试与契约同步的标准步骤及踩坑表。

新增业务模块操作手册add-business-module

蒸馏来源:docs/architecture/架构/README.md§2 后端模块地图 / §4.1 编码规范 / §11 模块开发 Checklistdocs/architecture/架构/README.md§7.10 扩展性 / SPI。 适用:在 game-cloud 后端新增一个 game-module-{name} 业务模块(如 pay / trade / community / ip / biz / ad或后续新模块。 配套:工程规范见 ../rules/engineering-conventions.md;可靠性/数据隔离红线见 ../rules/security-and-reliability.md;模块全景见 ../knowledge/product-and-architecture.md;契约先行见 ./contract-first-development.md;任务协议见 ../workflows/ai-development-protocol.md


目标

把一个新业务能力沉淀为标准 Huijing 风格的双 Maven 模块(-api + -server),可被 huijing-server 单体加载、对外暴露 /app-api/**/admin-api/** 接口、有库表迁移与测试、契约同步给前端。产出后即可被前端联调、被其他模块通过 Feign 调用。

样板game-module-project 是已编译+单测验证的活样板,照抄它(结构/分层/注释/错误码/单测)即可。 全局接线已就绪HuijingServerApplication 的组件扫描 + @MapperScan + application.yaml 的 type-aliases 已通配覆盖整个 com.wanxiang.huijing.game.module新模块无需改 Application/yaml,只需在 huijing-server/pom.xml 加本模块 -server 依赖(步骤 5。端前缀 /app-api·/admin-api 由框架按 controller.app·controller.admin 包名自动添加Controller 里 @RequestMapping 只写 /{模块}

前置

  • 已读 ../knowledge/product-and-architecture.md,确认该能力确实需要新模块(多数 MVP 需求在既有模块加子包即可,见模块架构文档 §4 遗漏分析的判断方式)。
  • 中间件MySQL/Redis/Nacos/RocketMQ已自托管 mini-infra连接信息见 docs/内网凭据与端点.md;本地跑 Flyway 与集成测试的 Testcontainers 仍依赖 Docker。
  • 已在模块速查表(开发团队版 §2.2)与错误码段位表(开发团队版 §4.1)为新模块预留了模块编号错误码段。(两版《系统概要设计》——"开发团队版"/"技术决策版"——已归档 _archive,节号按历史读;现行规范见 ../rules/engineering-conventions.mddocs/architecture/README.md

模块物理结构(以 project 为样板)

新模块拆成两个 Maven 子模块:-api(契约,被别人引用)与 -server(实现,只本模块用)。

game-module-{name}/
├── game-module-{name}-api/                 # 契约层:可被其他模块依赖
│   └── src/main/java/com/wanxiang/huijing/game/module/{name}/
│       ├── api/                            #   Feign 接口(供别的模块同步调用)
│       ├── dto/                           #   模块间传输对象 DTO
│       ├── enums/                         #   枚举(状态/类型)
│       └── enums/ErrorCodeConstants.java  #   本模块错误码常量(独占一段)
│
└── game-module-{name}-server/                 # 实现层:只本模块内部使用
    └── src/main/java/com/wanxiang/huijing/game/module/{name}/
        ├── controller/admin/              #   后台接口(运营/管理员,/admin/{name}/**
        │   └── vo/                        #     admin 端 VOReqVO/RespVO/PageReqVO
        ├── controller/app/                #   产品端接口(创作者/玩家,/app/{name}/**
        │   └── vo/                        #     app 端 VO
        ├── service/                       #   业务逻辑(@Transactional 只加这里)
        ├── dal/mysql/                     #   Mapper 接口 + DO数据库映射对象
        ├── dal/dataobject/                #   DO与表字段一一对应
        ├── convert/                       #   DO ↔ VO/DTO 转换器MapStruct
        ├── job/                           #   定时任务(如对账/聚合/清理)
        └── mq/consumer/                   #   RocketMQ 消费者(幂等消费)—— RocketMQ 已自托管 mini-infra单体内跨模块通知仍优先同进程 -api notify-push真跨进程/异步才上 RocketMQ见下方坑表
    └── src/main/resources/
        └── db/migration/                  #   Flyway 迁移脚本 V{x.y.z}__{desc}.sql
    └── src/test/java/...                  #   单元测试 + 集成测试

包名固定 com.wanxiang.huijing.game.module.{name}.{层}(开发团队版 §4.1)。-api 只放契约,禁止放实现/DO/Mapper-server 禁止被其他业务模块依赖。


步骤清单(照做)

# 步骤 关键动作 验证
1 建模块 复制 project 的 -api/-server 两个 pom 改 artifactId-server 依赖本模块 -api + 需要的他模块 -api mvn -pl game-module-{name}-server compile 通过
2 -api 定义契约 写 DTO/枚举/Feign 接口/ErrorCodeConstants先于 -server 完成,前端据此定义 TS 类型 契约同步进 contracts/api-schemas/{name}.yaml
3 -server 实现分层 按 controller(admin/app)→service→dal(DO+Mapper)→convert 落地MQ/job 按需加 单元测试覆盖 service
4 Flyway 迁移 -serverdb/migration/ 下新建 V{x.y.z}__{desc}.sql,如 V1.0.0__create_game_{name}.sql;只新增不改旧文件 mvn flyway:migrate -pl game-module-{name}-server 成功
5 装配=两处(缺任一 compile/启动失败Wave4 实测) ① root game-cloud/pom.xml<modules><module>game-module-{name}</module>(聚合定义,缺则 mvn -pl game-module-{name} … 报「找不到父 pom 聚合」);huijing-server/pom.xmlgame-module-{name}-server 依赖(单体把模块编进 JAR缺则启动无此模块、Swagger 无分组) mvn -pl huijing-server -am compile 通过 + 启动后 Swagger 见分组
6 模块配置Nacos 已部署 mini-infra 如有模块级配置(开关/阈值/外部 API keyNacos 已自托管 mini-infra模块级配置可入 Nacos 配置集;简单静态项也可走本地配置文件/环境变量。 Nacos 控制台可见 / 配置项生效
7 单元测试Service XxxServiceImplTest 继承 BaseMockitoUnitTest(纯 Mockito无需 DB/Docker照抄 project 的 ProjectServiceImplTest);需真实 DB 才用 BaseDbUnitTest(集成阶段)。注意mock/verify BaseMapper.insert/updateByIdany(XxxDO.class) 消歧,裸 any() 会因重载报错;verify(...).updateById(argThat(...)) 须显式标 lambda 参数类型 argThat((XxxDO d) -> …),否则同样重载歧义致 testCompile 失败Wave4 biz 实测踩坑) mvn -pl game-module-{name}/game-module-{name}-server test 绿
8 集成测试Controller+DB XxxServiceIntegrationTestTestcontainers 自动起 MySQL/Redis覆盖核心 API mvn verify -pl game-module-{name}-server -Pintegration 绿
9 Swagger/Knife4j 验证 启动 huijing-server,开 http://localhost:48080/doc.html 确认接口与字段自动生成正确 doc.html 可见新模块分组
10 更新文档 更新开发团队版 §2.2 模块速查表 + ../knowledge/product-and-architecture.md 模块清单/依赖 文档与代码一致
11 通知前端 给前端 Swagger 地址 + 示例 curl含鉴权头契约变更走 ./contract-first-development.md 前端可联调

API 路径规范/{端前缀}/{模块}/{资源}/{动作},端前缀框架自动加。/app-api/** 走用户 Token/admin-api/** 走管理员权限。Controller 里 @RequestMapping("/{name}") 只写模块名,最终对外即 POST /app-api/{name}/xxxGET /admin-api/{name}/page


错误码段位规则

每个模块独占一段 9 位错误码,避免冲突(详见 ../rules/engineering-conventions.md)。已分配段(开发团队版 §4.1

段位 模块
1-001-xxx-xxx system
1-002-xxx-xxx infra
1-100-xxx-xxx project
1-101-xxx-xxx aigc
1-102-xxx-xxx runtime
1-103-xxx-xxx feed
1-104~1-112 续段telemetry/ad/trade/studio/compliance…+ Wave4community=1-107、biz=1-110(已落地);完整映射以 engineering-conventions.md / contracts/README.md §四 为权威

错误码常量集中写在 -apiErrorCodeConstants.java,用 Huijing ServiceException + 错误码枚举抛出(不要裸抛 RuntimeException


完整 Checklist可勾选

  • 已确认确需新模块(而非在既有模块加子包)
  • 创建 game-module-{name}-apigame-module-{name}-server 两个 Maven 模块
  • -api 中定义 VO/DTO 入口、枚举、Feign 接口、ErrorCodeConstants(独占错误码段)
  • -server 中建 controller/admin/ + controller/app/ + service/ + dal/mysql/ + convert/(按需 job/mq/consumer/
  • 编写 Flyway 迁移 V{x.y.z}__{desc}.sql(只新增,不改旧迁移)
  • 装配两处root game-cloud/pom.xml <modules> 注册 <module> + huijing-server/pom.xml 引入 -server 依赖
  • 模块级配置如有Nacos 已自托管 mini-infra可入 Nacos 配置集;简单静态项也可走本地配置/环境变量
  • 单元测试Service 层)通过
  • 集成测试Controller + DBTestcontainers通过
  • SwaggerKnife4jdoc.html 验证 API 文档自动生成
  • 更新开发团队版 §2.2 模块速查表 + ../knowledge/product-and-architecture.md
  • 通知前端:附 Swagger 地址 + 示例 curl
  • 契约文件 contracts/api-schemas/{name}.yaml 已同步并提交 git

常见坑

后果 正确做法
改 Huijing framework 层源码 升级 Huijing 时冲突、不可维护 不改 framework 层,走 SPI/扩展点(如 PayChannel/AdProvider/ConversionAdapter SPI见技术决策版 §7.10
自己写 SQL 做数据隔离 创作者能看到别人的项目/资产 用 Huijing DataPermission(数据权限)做隔离,"创作者只看自己的"(技术决策版 §7.4
审核流自己写状态流转 流程僵硬、无法可视化配置 审核/发布/下架走 bpmFlowable 工作流驱动(开发团队版 §2.2 project 依赖 bpm
-server 被别的模块依赖 编译耦合、循环依赖 跨模块只依赖对方 -api单体装配下注入 -api 接口实际走提供方 -server 内的 @RestController @Primary 本地实现 = 同进程调用、与调用方同一 @TransactionalB2 实证telemetry 统计→quality→feed.upsertRank 同事务原子,异常整批回滚);拆微服务后退化为 Feign 远程调用、事务边界改变,须按 rules 补幂等/补偿;异步用 RocketMQ
单体装配下 -api@FeignClient 代理与本地实现 bean 二义性 Spring 启动失败OpenFeign 默认注册 primary bean与本地 @Primary 实现冲突) 提供方本地实现标 @RestController @Primary个别仍冲突的M1 实证4 个 CommonApi@FeignClientprimary = false(修法见 commit d7fac90
跨模块「通知/事件」直接上 MQ 单体内过度设计、调试链路长、RocketMQ 重依赖 MVP 单体内跨模块通知优先「同进程 -api notify-push」Wave4 community 范式):通知方建 XxxNotifyApi(@Primary 本地实现),上游在本地事务提交后调用 + try-catch 吞异常仅记 error log通知失败不回滚业务/不中断循环);通知由无鉴权线程(定时任务/回调)触发写库时,入口注入 LoginUser(id=0)+finally clearContext 防审计列 NOT NULL 撞 500范本 telemetry/community。真异步/跨进程才上 MQ
@Transactional 加在 Controller 或范围过大 长事务、锁竞争 只加在 Service 层,范围尽量小(开发团队版 §4.1
修改已存在的 Flyway 迁移文件 flyway validate 失败、CI 阻断 新建迁移补偿,绝不改旧文件(开发团队版 §9
单元测试连真实 DB 测试慢、不稳定 业务逻辑用 Mock真需要 DB 用集成测试 + Testcontainers
select * / 大表无索引查询 慢查询、性能事故 必须指定字段;大表查询必须命中索引(开发团队版 §4.1
「运营赋值类」资金admin 赋余额/补偿)混进业务收益流水表 污染营收报表 gross/net 聚合 + 破坏对账锚点 另建专用流水表trade U2game_trade_grant,独立 uk_biz_no 幂等行),账户余额仍走原子增(balance += amount, total_income += amount 守恒 balance+frozen+total_withdraw=total_income);流水写入 + 余额增同 @Transactional先写流水行uk 防并发)再增余额,余额增 0 行抛错回滚(禁「流水已记、余额未增」半态)。范本 AccountServiceImpl.grant
「一用户一态」聚合域(订阅/会员)按每次操作建新行 uk_user 撞键 / 状态分散难查 一行一用户 upsertuk_user,首建 insert / 已有 CAS 续期);幂等键内联在行last_grant_biz_no,同 bizNo 不重复延长 = 重试安全),区别于流水域的独立 uk_biz_no 行;续期叠加 新到期=max(now,旧expire)+时长(不丢未用时长,已过期从 now 起算CASWHERE expire_time=读时快照)防并发 lost-updatemiss 回查重试有限轮次(禁死循环)。范本 SubscriptionServiceImpl
「有效期/过期态」依赖定时 job 物化 status 列 无 cron / 定时 job 未接时过期态不准 有效性以 expire_time>now 查询时实时回算effectiveStatus/active 在 Convert 层算),落库 status 仅初始态 + 后续物化预留;不依赖定时 job 也能正确反映过期。范本 TradeConvert.toSubscriptionVO