--- name: likei-dev description: Likei Services 项目开发 Skill。接到任何功能需求、Bug 修复、重构任务时触发。执行完整的「需求分析 → 读文件 → 编码 → 提交 → Review → 修复循环 → 汇总」工作流,直到代码无问题为止。适用于 rc-service-other、rc-service-wallet、rc-service-order、rc-auth、rc-inner-api 等模块的开发工作。 --- # Likei Services 开发 Skill ## 核心工作流(每次接到需求必须严格按此顺序执行) ``` 1. 读文件 → 理解现有结构和上下文 2. 设计方案 → 列出改动文件、核心思路,询问用户是否同意,等待确认后再继续 3. 编码 → 按规范写代码 4. git add → 暂存变更(指定文件,禁止 git add .) 5. git commit → 提交(默认不 push,除非用户明确要求) 6. git show → diff review,逐文件检查 7. 发现问题? → 修复 → 追加 commit → 再次 review 8. 无问题 → 输出汇总,询问是否 push ``` **循环终止条件**:git diff review 所有文件均无逻辑漏洞、无原逻辑改动、无字段错误、无 NPE 风险。 > **数据库变更规则**:设计方案中若涉及 MySQL 表结构变更(新增字段、修改索引等)或 MongoDB 索引变更,必须在方案里直接给出可执行的 SQL / MongoDB Shell 语句,不能只描述变更内容。 --- ## 第一步:读文件(禁止跳过) 接到需求后,**先读,不要直接写代码**。 ### 必读文件 - 需求涉及的所有现有业务文件(Controller / ServiceImpl / Cmd / CO 等) - 同模块至少一个 peer 文件,用于对齐命名和代码风格 - 涉及对接文档时,仔细比对每个字段 ### 按需读取的规范文档 | 场景 | 文档 | |------|------| | 工具类、Redis key、MongoDB 操作 | `D:\workspace\likei-services\项目工具类说明.md` | | DDD 分层、模块结构 | `D:\workspace\likei-services\OTHER模块DDD架构说明.md` | | 排行榜 season/cycle 相关 | `D:\workspace\likei-services\ranking-season-cycle.md` | 读完后先说明:**要改哪些文件、改什么**,再动手编码。 --- ## 第二步:编码规范 ### 分层架构(严格遵守,禁止跨层调用) ``` Controller(other-adapter) ↓ 只调用 Service 接口 ServiceImpl(other-application) ↓ 只调用 CmdExe / Gateway / DatabaseService CmdExe / Gateway(other-application / other-infrastructure) ↓ DAO / MongoTemplate / Redis(other-infrastructure) ``` ### 文件路径速查(other 模块) | 类型 | 路径模板 | |------|----------| | Controller | `other-adapter/src/main/java/com/red/circle/other/adapter/app/{模块}/` | | Service 接口 | `other-client/src/main/java/com/red/circle/other/app/service/{模块}/` | | Cmd | `other-client/src/main/java/com/red/circle/other/app/dto/cmd/{模块}/` | | CO | `other-client/src/main/java/com/red/circle/other/app/dto/clientobject/{模块}/` | | CmdExe | `other-application/src/main/java/com/red/circle/other/app/command/{模块}/` | | QryExe | `other-application/src/main/java/com/red/circle/other/app/command/{模块}/query/` | | ServiceImpl | `other-application/src/main/java/com/red/circle/other/app/service/{模块}/` | | DatabaseService | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/` | | DAO | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/` | | Entity | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/` | | Redis Key 枚举 | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/key/{模块}/` | | Inner API 接口 | `rc-inner-api/other-inner/other-inner-api/endpoint/{模块}/` | | Inner Endpoint 实现 | `other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/{模块}/` | ### 命名规范 | 类型 | 命名规则 | |------|----------| | Controller | `{功能}RestController` | | Service 接口 | `{功能}Service` | | ServiceImpl | `{功能}ServiceImpl` | | CmdExe | `{功能}CmdExe` 或 `{功能}Exe` | | QryExe | `{功能}QryExe` | | Cmd(写操作入参) | `{功能}Cmd` | | CO(读操作返回) | `{功能}CO` | | DAO | `{实体名}DAO`,继承 `BaseDAO` | ### 注解规范 ```java // Cmd / CO / DTO:@Data,需要时加 @Builder @NoArgsConstructor @AllArgsConstructor // 校验注解:jakarta.validation.constraints.*(禁止用 javax.validation) // 注入方式:@RequiredArgsConstructor(构造器注入,禁止 @Autowired 字段注入) // 日志:@Slf4j,查询接口不加 log.info,只在关键业务节点记录 // 事务:@Transactional 只加在 public 方法,不加在 private 方法(Spring AOP 限制) // API 文档:@eo.name / @eo.url / @eo.method(不使用 Swagger 注解) // 作者:@author tf // 分页查询 Cmd:继承 PageQueryCmd,不手写分页参数 // 写操作 Cmd:需要时继承 AppExtCommand(含 reqUserId 等公共字段) ``` ### 常用外部工具类(外部 jar,禁止在项目中搜索源码) | 类名 | 包路径 | 用途 | |------|--------|------| | `RedisService` | `com.red.circle.component.redis.service.RedisService` | Redis,含 setIfAbsent/increment/expire | | `IdWorkerUtils` | `com.red.circle.tool.core.sequence.IdWorkerUtils` | 雪花 ID,getId()/getIdStr() | | `ZonedDateTimeUtils` | `com.red.circle.other.infra.utils.ZonedDateTimeUtils` | Riyadh 时区工具 | | `ZonedId` | `com.red.circle.tool.core.date.ZonedId` | 时区枚举,ASIA_RIYADH / ASIA_SHANGHAI | | `ArithmeticUtils` | `com.red.circle.tool.core.num.ArithmeticUtils` | 金额计算 | | `AppExtCommand` | `com.red.circle.common.business.dto.cmd.AppExtCommand` | Cmd 基类 | | `PageQueryCmd` | `com.red.circle.common.business.dto.PageQueryCmd` | 分页查询基类 | | `PageResult` | `com.red.circle.framework.dto.PageResult` | 分页结果封装 | ### 关键业务规则 - **时区**:所有时间统计和调度使用 Asia/Riyadh - **AR 分区判断**:使用 `RegionConstants.AR_REGION_IDS`,分区值为 `"AR"` 或 `"OTHER"` - **Integer 比较**:用 `Objects.equals()` 或 `Integer.valueOf(x).equals(y)`,禁止 `==` - **MQ createTime**:发送时设为 `new Date()`,不用业务时间戳 - **RocketMQ 幂等 key**:在业务执行**成功后**写入 Redis,不能在执行前 - **金额**:使用 `PennyAmount`(以分为单位),展示时用 `getDollarAmount()` - **Response 空检查**:调用外部服务(walletGoldClient / authClient 等)后必须判断 `isSuccess()` 和 `getBody() != null` ### 编码完成后自检清单 - [ ] 命名清晰,无 a、b、tmp 等无意义变量 - [ ] 无跨层调用 - [ ] 所有外部服务返回值有空检查 - [ ] Integer / Long 比较未使用 `==` - [ ] 金额操作有幂等保护(bizNo / requestId / orderId) - [ ] 幂等标记在业务成功后写入 - [ ] 关键业务有 `@Transactional`(public 方法) - [ ] 异常信息有意义,不直接 `new RuntimeException("error")` - [ ] 新代码未破坏原有逻辑 --- ## 第三步:git 操作 ### 环境信息 ``` git 可执行文件:D:\datasource\git\bin\git.exe 项目根目录: D:\workspace\likei-services 工作范围: D:\workspace\likei-services 及其子目录(禁止操作父目录) ``` ### 标准命令模板 ```cmd # add(指定文件路径,禁止 git add .) D:\datasource\git\bin\git.exe -C D:\workspace\likei-services add {相对路径1} {相对路径2} # 查看状态 D:\datasource\git\bin\git.exe -C D:\workspace\likei-services status # 查看最近提交 D:\datasource\git\bin\git.exe -C D:\workspace\likei-services log --oneline -5 # diff review(必须用 git show,不用 git diff HEAD) D:\datasource\git\bin\git.exe -C D:\workspace\likei-services show {hash} # push D:\datasource\git\bin\git.exe -C D:\workspace\likei-services push origin {branch} ``` ### commit 命令(必须用 PowerShell,避免中文解析失败) ```powershell & 'D:\datasource\git\bin\git.exe' -C 'D:\workspace\likei-services' commit -m 'message in english' ``` > commit 后 PowerShell 输出不稳定,**不能直接从 commit 输出中读取 hash**。commit 完成后立即用以下命令确认: > ```cmd > D:\datasource\git\bin\git.exe -C D:\workspace\likei-services log --oneline -1 > ``` ### commit message 规范(英文,禁止中文) | 类型 | 格式 | |------|------| | 新功能 | `feat: add xxx` | | Bug 修复 | `fix: xxx null check` | | 重构 | `refactor: extract xxx` | | 配置变更 | `chore: update xxx config` | --- ## 第四步:Review 检查项(git show 后必须逐文件核对) ### 字段映射 - Cmd 字段与对接文档/需求是否**完全一致**,无遗漏 - CO / 响应字段与文档是否一致 - `@JsonProperty` 是否正确处理下划线命名(如 `game_infos`) - 类型是否正确(`Integer` vs `Long`,`int` vs `long`) ### 原逻辑保护 - 原有业务流程(广播、排行榜、任务、日志等)是否完整保留 - 重构时条件判断位置移动是否导致行为变化(如 type 判断从方法内移到方法外) - 注释掉的代码是否被意外删除 - 原有 error log 是否被移除 ### 空指针防御 - 外部服务返回值是否有 `isSuccess()` + `getBody() != null` 双重检查 - `Integer` / `Long` 类型是否用了 `==` 比较(必须用 `Objects.equals`) - `Optional` 链是否有 `.orElse()` 兜底 - 外部接口返回的集合类型为 `Collection` 时,调用 `subList` / `sort` / `indexOf` 等 `List` 专有方法前必须先转为 `new ArrayList<>(collection)` ### 幂等与并发 - `changeBalance` / 余额变动类接口是否有幂等保护(Redis `setIfAbsent` 或 requestId 标记) - 幂等标记是否在钱包调用**成功后**写入(不是之前) - 幂等 TTL 是否合理(建议 ≥ 600s) - 重复请求命中幂等时的返回值是否正确 ### 架构合规 - 业务逻辑是否在正确的层(Controller 不写逻辑,Infrastructure 不写业务) - 是否有跨层调用 - 公共逻辑是否抽到合适的位置(如 `GameEventService`) ### 发现问题时的处理流程 1. 明确说明:哪个文件、哪行、什么问题、为什么 2. 直接修复代码,不只是建议 3. `git add` 修改的文件 4. 追加 commit(message 说明修复内容) 5. 再次 `git show` review,确认问题消失 6. 重复直到所有问题清零 --- ## 第五步:汇总输出(Review 无问题后输出) ```markdown ## 本次变更汇总 ### 涉及文件 | 文件 | 操作 | 变更内容 | |------|------|----------| | XxxController.java | 修改 | 错误码对齐 v4 协议 | | XxxCmd.java | 新增 | v4 请求字段定义 | ### 关键逻辑说明 - ... ### Commits - {hash} {message} - {hash} {message} ### Review 结论 ✅ 字段映射完整,与文档一致 ✅ 原有业务逻辑完整保留 ✅ 外部服务返回值均有空检查 ✅ Integer 比较已用 Objects.equals ✅ 幂等保护正常,TTL 合理 ✅ 架构分层合规,无跨层调用 ``` 然后询问用户:**是否需要 push 到远端?** --- ## 附:常见问题处理 ### 新建文件 vs 编辑文件 - **新建文件**:必须用 `Filesystem:write_file`,`edit_file` 只能操作已存在的文件,对新路径会报 ENOENT。 - **编辑已有文件**:优先用 `Filesystem:edit_file`;遇到编码匹配失败时改用 `Desktop Commander:write_file`(rewrite 模式,超过 30 行分块写入)。 ### git commit 报错(cmd 下 -m 后内容被拆分为多个参数) **根本原因**:在 cmd 下直接执行 `git commit -m "message with spaces"` 时,cmd 会将双引号内的空格当作参数分隔符,导致 message 被拆成多个 pathspec 参数报错。无论是否含中文,只要 message 含空格就会出错。 **正确做法(必须严格遵守)**: 1. add 用 cmd + 完整 git 路径 + `-C` 指定仓库: ```cmd D:\datasource\git\bin\git.exe -C D:\workspace\likei-services add {相对路径} ``` 2. commit **必须**切换到 PowerShell,用单引号包裹 message,且只用英文: ```powershell & 'D:\datasource\git\bin\git.exe' -C 'D:\workspace\likei-services' commit -m 'feat: add xxx' ``` 3. commit 完成后用 cmd 确认 hash: ```cmd D:\datasource\git\bin\git.exe -C D:\workspace\likei-services log --oneline -1 ``` **禁止行为**: - ❌ 禁止在 cmd 下执行 `git commit -m "有空格的message"` - ❌ 禁止用 `cd /d xxx && git commit`(PATH 中的 git 不保证可用) - ❌ 禁止省略 `-C D:\workspace\likei-services`(依赖 cwd 不可靠) - ✅ commit message 必须用中文,PowerShell 单引号包裹中文没有问题 ### git show 无输出(exit 0) 说明 hash 是最新提交,HEAD 和它相同,改用: ```cmd D:\datasource\git\bin\git.exe -C D:\workspace\likei-services show {完整hash} ``` ### 搜索 Java 文件 使用 `Filesystem:search_files`,必须加 `excludePatterns: ["target"]` 排除构建产物。 ### 批量读文件 优先用 `Filesystem:read_multiple_files` 一次读多个,减少工具调用轮次。 ### 新目录下创建文件 先用 `Filesystem:create_directory` 建目录,再写文件;`impl` 子目录不会自动创建。 ### 文件超长(>100 行)需要写入 用 `Desktop Commander:write_file` 分块写:首块 `mode: rewrite`,后续块 `mode: append`,每块不超过 30 行。