From e3c796da27677a9731e048c4eb4f939ab728acc1 Mon Sep 17 00:00:00 2001 From: wh Date: Tue, 14 Apr 2026 12:41:46 +0800 Subject: [PATCH] docs: add backend directory flattening design --- ...bel-backend-directory-flattening-design.md | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-14-label-backend-directory-flattening-design.md diff --git a/docs/superpowers/specs/2026-04-14-label-backend-directory-flattening-design.md b/docs/superpowers/specs/2026-04-14-label-backend-directory-flattening-design.md new file mode 100644 index 0000000..83d4aee --- /dev/null +++ b/docs/superpowers/specs/2026-04-14-label-backend-directory-flattening-design.md @@ -0,0 +1,244 @@ +# label_backend 标准目录扁平化设计 + +**日期**: 2026-04-14 +**范围**: `label_backend` 主工程 Java 包结构调整 +**目标**: 将当前按业务域分层的 `com.label.module.*` 结构重组为符合《微服务开发规范文档》的扁平标准目录结构,同时保持现有业务行为不变。 + +--- + +## 1. 背景与现状 + +当前项目主代码位于 `src/main/java/com/label`,整体结构分为两部分: + +- `com.label.common.*`:放置公共能力,如配置、异常、AOP、鉴权、Redis、状态机、存储与 AI 客户端 +- `com.label.module.*`:按业务域划分的模块目录,如 `user`、`task`、`source`、`annotation`、`export`、`config`、`video` + +现有结构具备一定领域边界,但与《微服务开发规范文档》中规定的标准扁平目录结构不一致。后续如果继续沿用两套组织方式,会增加新代码接入成本,也会让公共能力与业务层级的归属变得不稳定。 + +--- + +## 2. 设计目标 + +本次调整目标如下: + +- 将主代码目录统一调整为规范文档中的扁平结构 +- 保持包职责清晰,按“层级职责”而不是“业务模块”组织类 +- 在不改变业务逻辑和接口行为的前提下完成迁移 +- 规范包归属与少量命名,不引入新的技术分层 +- 为后续新增功能提供统一、可预测的目录组织方式 + +--- + +## 3. 明确不做的事情 + +为控制改造范围,本次不包含以下内容: + +- 不新增 `service.impl` +- 不将 `dto` 拆分为 `request`、`response`、`common` +- 不主动修改接口 URL、接口契约或返回结构 +- 不进行与目录调整无关的业务重构 +- 不改造数据库结构、SQL 文件或资源文件布局 + +--- + +## 4. 目标目录结构 + +目标结构定义如下: + +```text +src/main/java/com/label/ +├── annotation/ +├── aspect/ +├── common/ +│ ├── ai/ +│ ├── context/ +│ ├── exception/ +│ ├── redis/ +│ ├── result/ +│ ├── shiro/ +│ ├── statemachine/ +│ └── storage/ +├── config/ +├── constant/ +├── controller/ +├── dto/ +├── entity/ +├── event/ +├── feign/ +├── listener/ +├── mapper/ +├── scheduled/ +├── service/ +├── typehandler/ +├── util/ +└── LabelBackendApplication.java +``` + +说明: + +- `common` 只保留真正跨业务复用的基础能力 +- `config` 从原 `common.config` 提升到顶层 +- `annotation` 与 `aspect` 从原 `common.aop` 中拆分 +- `event` 与 `listener` 分离,避免事件定义与监听逻辑混放 +- `controller`、`service`、`mapper`、`entity`、`dto` 全部收敛为顶层扁平结构 + +--- + +## 5. 包迁移规则 + +### 5.1 顶层迁移规则 + +- `com.label.module.*.controller` -> `com.label.controller` +- `com.label.module.*.service` -> `com.label.service` +- `com.label.module.*.mapper` -> `com.label.mapper` +- `com.label.module.*.entity` -> `com.label.entity` +- `com.label.module.*.dto` -> `com.label.dto` +- `com.label.module.annotation.event` -> `com.label.event` +- 事件监听类 -> `com.label.listener` +- `com.label.common.config` -> `com.label.config` +- `com.label.common.aop` 中注解类 -> `com.label.annotation` +- `com.label.common.aop` 中切面类 -> `com.label.aspect` + +### 5.2 典型映射示例 + +- `com.label.module.user.controller.AuthController` -> `com.label.controller.AuthController` +- `com.label.module.user.service.UserService` -> `com.label.service.UserService` +- `com.label.module.task.mapper.AnnotationTaskMapper` -> `com.label.mapper.AnnotationTaskMapper` +- `com.label.module.source.entity.SourceData` -> `com.label.entity.SourceData` +- `com.label.module.user.dto.LoginRequest` -> `com.label.dto.LoginRequest` +- `com.label.common.aop.OperationLog` -> `com.label.annotation.OperationLog` +- `com.label.common.aop.AuditAspect` -> `com.label.aspect.AuditAspect` +- `com.label.module.annotation.event.ExtractionApprovedEvent` -> `com.label.event.ExtractionApprovedEvent` +- `com.label.module.annotation.service.ExtractionApprovedEventListener` -> `com.label.listener.ExtractionApprovedEventListener` +- `com.label.common.config.RedisConfig` -> `com.label.config.RedisConfig` + +### 5.3 命名策略 + +- 以“最小必要变更”为原则,优先迁移包路径,不主动重命名类 +- 仅在类职责与包语义明显不匹配时做必要归位 +- 现阶段主代码类名不存在重名冲突,因此不需要为扁平化提前引入前缀或后缀 + +--- + +## 6. 实施顺序 + +为降低迁移风险,实际执行采用“目标一次性扁平化,操作分阶段迁移”的方式。 + +### 阶段 1:基础公共层归位 + +先迁移以下内容,建立新骨架: + +- `annotation` +- `aspect` +- `config` +- `event` +- `listener` + +目标是先完成最基础的结构纠偏,并尽早暴露切面、配置和事件扫描问题。 + +### 阶段 2:数据承载层迁移 + +再迁移下列包: + +- `entity` +- `dto` +- `mapper` + +这些类依赖通常较窄,适合优先扁平化,也能及早验证 MyBatis 相关扫描与引用是否正常。 + +### 阶段 3:业务服务层迁移 + +迁移所有业务服务类到 `service`,原则如下: + +- 不新增实现层 +- 不调整现有业务编排 +- 只修正导包、注解引用和必要的包路径依赖 + +### 阶段 4:控制层迁移 + +最后迁移全部控制器到 `controller`。控制层依赖最广,放在后面可以减少中间态反复修改。 + +### 阶段 5:启动与扫描校正 + +统一检查并修正以下内容: + +- `@MapperScan` +- 组件扫描隐式路径 +- OpenAPI 相关配置 +- 事件监听与切面装配 +- 测试代码中的旧包引用 + +### 阶段 6:编译与回归验证 + +迁移完成后进行全量编译与测试回归,确认结构调整没有引入行为回归。 + +--- + +## 7. 风险与控制策略 + +### 风险 1:导包失效 + +大量类迁移后,主代码和测试代码中的 import 会同时失效。 + +控制策略: + +- 按阶段迁移并同步修复引用 +- 每个阶段结束后至少执行一次编译检查 + +### 风险 2:Spring 扫描路径异常 + +若配置类、切面、监听器或 Mapper 的扫描路径与旧包结构耦合,迁移后可能导致 Bean 缺失。 + +控制策略: + +- 显式检查启动类与配置类中的扫描配置 +- 将路径校正作为独立阶段处理 + +### 风险 3:事件监听失效 + +监听器从 `service` 拆到 `listener` 后,若注解或组件扫描不正确,会导致事件未被消费。 + +控制策略: + +- 迁移时同步校验事件类与监听器依赖关系 +- 通过现有集成测试覆盖事件链路 + +### 风险 4:测试回归失败 + +测试代码同样引用旧包名,若只改主代码,会造成测试集整体失效。 + +控制策略: + +- 测试代码与主代码同步迁移 +- 将 `mvn test` 作为最终验收门槛 + +--- + +## 8. 验收标准 + +本次结构调整完成后,应满足以下标准: + +1. `src/main/java/com/label/module` 目录被完全移除 +2. 主代码包结构符合标准扁平目录规范 +3. 项目能够成功编译 +4. 现有测试能够通过,至少覆盖当前可运行的启动测试、单元测试和集成测试 +5. 调整范围内不存在残留旧包引用 + +--- + +## 9. 实现原则 + +执行本设计时应遵循以下原则: + +- 先保证结构归位,再追求风格统一 +- 先保证行为不变,再做命名优化 +- 所有改动以“目录标准化”为中心,不引入额外架构决策 +- 每次修改都要让工程更接近规范,而不是制造新的混合结构 + +--- + +## 10. 结论 + +本次改造将 `label_backend` 从“按业务域分层 + 公共包混合”的现状,统一整理为规范文档定义的扁平标准目录结构。该调整不会改变系统能力边界,但会显著提升代码组织一致性、后续开发可预测性以及新成员理解成本。 + +实施时采用“目标结构一次确定、操作按阶段推进”的方式,以降低大规模包迁移带来的编译与装配风险。