优化现有目录结构

This commit is contained in:
wh
2026-04-14 14:59:46 +08:00
parent c524fb08e1
commit ceaac48051
21 changed files with 1181 additions and 39 deletions

View File

@@ -0,0 +1,528 @@
# label_backend 标准目录扁平化 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:**`com.label.module.*``com.label.common.aop/common.config` 迁移到规范要求的扁平目录,保证行为不变。
**Architecture:** 先写迁移守卫测试,再按 `基础设施 -> 数据层 -> 服务层 -> 控制层 -> 清理回归` 的顺序做 `git mv` 和导包修正,每阶段都用最小测试集验证。
**Tech Stack:** Java 21、Spring Boot 3.1.5、MyBatis-Plus、Shiro、JUnit 5、AssertJ、Maven
---
## 目标目录
- `src/main/java/com/label/annotation`
- `src/main/java/com/label/aspect`
- `src/main/java/com/label/config`
- `src/main/java/com/label/controller`
- `src/main/java/com/label/dto`
- `src/main/java/com/label/entity`
- `src/main/java/com/label/event`
- `src/main/java/com/label/listener`
- `src/main/java/com/label/mapper`
- `src/main/java/com/label/service`
- `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
---
### Task 1: 锁定基础设施迁移目标
**Files:**
- Create: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- Modify: `src/main/java/com/label/common/aop/OperationLog.java`
- Modify: `src/main/java/com/label/common/aop/AuditAspect.java`
- Modify: `src/main/java/com/label/common/config/MybatisPlusConfig.java`
- Modify: `src/main/java/com/label/common/config/OpenApiConfig.java`
- Modify: `src/main/java/com/label/common/config/RedisConfig.java`
- Modify: `src/main/java/com/label/module/annotation/event/ExtractionApprovedEvent.java`
- Modify: `src/main/java/com/label/module/annotation/service/ExtractionApprovedEventListener.java`
- Modify: `src/main/java/com/label/module/annotation/service/ExtractionService.java`
- Test: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- [ ] **Step 1: 写失败测试**
```java
package com.label.unit;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@DisplayName("标准目录扁平化迁移守卫测试")
class PackageStructureMigrationTest {
@Test
@DisplayName("基础设施类已迁移到目标目录")
void infrastructureTypesMoved() {
assertClassExists("com.label.annotation.OperationLog");
assertClassExists("com.label.aspect.AuditAspect");
assertClassExists("com.label.config.MybatisPlusConfig");
assertClassExists("com.label.config.OpenApiConfig");
assertClassExists("com.label.config.RedisConfig");
assertClassExists("com.label.event.ExtractionApprovedEvent");
assertClassExists("com.label.listener.ExtractionApprovedEventListener");
assertClassMissing("com.label.common.aop.OperationLog");
assertClassMissing("com.label.common.aop.AuditAspect");
assertClassMissing("com.label.common.config.MybatisPlusConfig");
assertClassMissing("com.label.common.config.OpenApiConfig");
assertClassMissing("com.label.common.config.RedisConfig");
assertClassMissing("com.label.module.annotation.event.ExtractionApprovedEvent");
assertClassMissing("com.label.module.annotation.service.ExtractionApprovedEventListener");
}
private static void assertClassExists(String fqcn) {
assertThatCode(() -> Class.forName(fqcn)).doesNotThrowAnyException();
}
private static void assertClassMissing(String fqcn) {
assertThatThrownBy(() -> Class.forName(fqcn)).isInstanceOf(ClassNotFoundException.class);
}
}
```
- [ ] **Step 2: 跑红**
Run: `mvn -q "-Dtest=PackageStructureMigrationTest#infrastructureTypesMoved" test`
Expected: FAIL提示新包类不存在。
- [ ] **Step 3: 最小实现**
先执行迁移:
```powershell
git mv src/main/java/com/label/common/aop/OperationLog.java src/main/java/com/label/annotation/OperationLog.java
git mv src/main/java/com/label/common/aop/AuditAspect.java src/main/java/com/label/aspect/AuditAspect.java
git mv src/main/java/com/label/common/config/MybatisPlusConfig.java src/main/java/com/label/config/MybatisPlusConfig.java
git mv src/main/java/com/label/common/config/OpenApiConfig.java src/main/java/com/label/config/OpenApiConfig.java
git mv src/main/java/com/label/common/config/RedisConfig.java src/main/java/com/label/config/RedisConfig.java
git mv src/main/java/com/label/module/annotation/event/ExtractionApprovedEvent.java src/main/java/com/label/event/ExtractionApprovedEvent.java
git mv src/main/java/com/label/module/annotation/service/ExtractionApprovedEventListener.java src/main/java/com/label/listener/ExtractionApprovedEventListener.java
```
再做精确替换:
```java
// OperationLog.java
package com.label.annotation;
// AuditAspect.java
package com.label.aspect;
import com.label.annotation.OperationLog;
// MybatisPlusConfig.java / OpenApiConfig.java / RedisConfig.java
package com.label.config;
// ExtractionApprovedEvent.java
package com.label.event;
// ExtractionApprovedEventListener.java
package com.label.listener;
import com.label.event.ExtractionApprovedEvent;
import com.label.module.annotation.entity.TrainingDataset;
import com.label.module.annotation.mapper.AnnotationResultMapper;
import com.label.module.annotation.mapper.TrainingDatasetMapper;
import com.label.module.source.entity.SourceData;
import com.label.module.source.mapper.SourceDataMapper;
import com.label.module.task.service.TaskService;
```
并把 `src/main/java/com/label/module/annotation/service/ExtractionService.java` 中事件 import 改成 `com.label.event.ExtractionApprovedEvent`
- [ ] **Step 4: 跑绿**
Run:
- `mvn -q "-Dtest=PackageStructureMigrationTest#infrastructureTypesMoved" test`
- `mvn -q -DskipTests compile`
Expected: 两条命令都 `BUILD SUCCESS`
- [ ] **Step 5: Commit**
```powershell
git add src/test/java/com/label/unit/PackageStructureMigrationTest.java src/main/java/com/label/annotation src/main/java/com/label/aspect src/main/java/com/label/config src/main/java/com/label/event src/main/java/com/label/listener src/main/java/com/label/module/annotation/service/ExtractionService.java
git commit -m "refactor: flatten infrastructure packages"
```
---
### Task 2: 迁移 DTO、Entity、Mapper
**Files:**
- Modify: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- Modify: `src/test/java/com/label/unit/OpenApiAnnotationTest.java`
- Modify: `src/test/java/com/label/integration/AuthIntegrationTest.java`
- Modify: `src/test/java/com/label/integration/ExtractionApprovalIntegrationTest.java`
- Modify: `src/test/java/com/label/integration/QaApprovalIntegrationTest.java`
- Modify: `src/test/java/com/label/integration/UserManagementIntegrationTest.java`
- Modify: `src/main/java/com/label/module/annotation/service/ExtractionService.java`
- Modify: `src/main/java/com/label/module/annotation/service/QaService.java`
- Modify: `src/main/java/com/label/module/config/service/SysConfigService.java`
- Modify: `src/main/java/com/label/module/config/controller/SysConfigController.java`
- Modify: `src/main/java/com/label/module/export/service/ExportService.java`
- Modify: `src/main/java/com/label/module/export/service/FinetuneService.java`
- Modify: `src/main/java/com/label/module/export/controller/ExportController.java`
- Modify: `src/main/java/com/label/module/source/service/SourceService.java`
- Modify: `src/main/java/com/label/module/source/controller/SourceController.java`
- Modify: `src/main/java/com/label/module/task/service/TaskClaimService.java`
- Modify: `src/main/java/com/label/module/task/service/TaskService.java`
- Modify: `src/main/java/com/label/module/task/controller/TaskController.java`
- Modify: `src/main/java/com/label/module/user/service/AuthService.java`
- Modify: `src/main/java/com/label/module/user/service/UserService.java`
- Modify: `src/main/java/com/label/module/user/controller/AuthController.java`
- Modify: `src/main/java/com/label/module/user/controller/UserController.java`
- Modify: `src/main/java/com/label/module/video/service/VideoProcessService.java`
- Modify: `src/main/java/com/label/module/video/controller/VideoController.java`
- Test: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- [ ] **Step 1: 写失败测试**
`PackageStructureMigrationTest.java` 里追加:
```java
@Test
@DisplayName("DTO、实体、Mapper 已迁移到扁平数据层")
void dataTypesMoved() {
for (String fqcn : java.util.List.of(
"com.label.dto.LoginRequest", "com.label.dto.LoginResponse", "com.label.dto.UserInfoResponse",
"com.label.dto.TaskResponse", "com.label.dto.SourceResponse",
"com.label.entity.AnnotationResult", "com.label.entity.TrainingDataset", "com.label.entity.SysConfig",
"com.label.entity.ExportBatch", "com.label.entity.SourceData", "com.label.entity.AnnotationTask",
"com.label.entity.AnnotationTaskHistory", "com.label.entity.SysCompany", "com.label.entity.SysUser",
"com.label.entity.VideoProcessJob",
"com.label.mapper.AnnotationResultMapper", "com.label.mapper.TrainingDatasetMapper",
"com.label.mapper.SysConfigMapper", "com.label.mapper.ExportBatchMapper", "com.label.mapper.SourceDataMapper",
"com.label.mapper.AnnotationTaskMapper", "com.label.mapper.TaskHistoryMapper",
"com.label.mapper.SysCompanyMapper", "com.label.mapper.SysUserMapper", "com.label.mapper.VideoProcessJobMapper")) {
assertClassExists(fqcn);
}
}
```
- [ ] **Step 2: 跑红**
Run: `mvn -q "-Dtest=PackageStructureMigrationTest#dataTypesMoved" test`
Expected: FAIL提示 `com.label.dto.LoginRequest` 等不存在。
- [ ] **Step 3: 最小实现**
执行迁移:
```powershell
git mv src/main/java/com/label/module/user/dto/LoginRequest.java src/main/java/com/label/dto/LoginRequest.java
git mv src/main/java/com/label/module/user/dto/LoginResponse.java src/main/java/com/label/dto/LoginResponse.java
git mv src/main/java/com/label/module/user/dto/UserInfoResponse.java src/main/java/com/label/dto/UserInfoResponse.java
git mv src/main/java/com/label/module/task/dto/TaskResponse.java src/main/java/com/label/dto/TaskResponse.java
git mv src/main/java/com/label/module/source/dto/SourceResponse.java src/main/java/com/label/dto/SourceResponse.java
git mv src/main/java/com/label/module/annotation/entity/AnnotationResult.java src/main/java/com/label/entity/AnnotationResult.java
git mv src/main/java/com/label/module/annotation/entity/TrainingDataset.java src/main/java/com/label/entity/TrainingDataset.java
git mv src/main/java/com/label/module/config/entity/SysConfig.java src/main/java/com/label/entity/SysConfig.java
git mv src/main/java/com/label/module/export/entity/ExportBatch.java src/main/java/com/label/entity/ExportBatch.java
git mv src/main/java/com/label/module/source/entity/SourceData.java src/main/java/com/label/entity/SourceData.java
git mv src/main/java/com/label/module/task/entity/AnnotationTask.java src/main/java/com/label/entity/AnnotationTask.java
git mv src/main/java/com/label/module/task/entity/AnnotationTaskHistory.java src/main/java/com/label/entity/AnnotationTaskHistory.java
git mv src/main/java/com/label/module/user/entity/SysCompany.java src/main/java/com/label/entity/SysCompany.java
git mv src/main/java/com/label/module/user/entity/SysUser.java src/main/java/com/label/entity/SysUser.java
git mv src/main/java/com/label/module/video/entity/VideoProcessJob.java src/main/java/com/label/entity/VideoProcessJob.java
git mv src/main/java/com/label/module/annotation/mapper/AnnotationResultMapper.java src/main/java/com/label/mapper/AnnotationResultMapper.java
git mv src/main/java/com/label/module/annotation/mapper/TrainingDatasetMapper.java src/main/java/com/label/mapper/TrainingDatasetMapper.java
git mv src/main/java/com/label/module/config/mapper/SysConfigMapper.java src/main/java/com/label/mapper/SysConfigMapper.java
git mv src/main/java/com/label/module/export/mapper/ExportBatchMapper.java src/main/java/com/label/mapper/ExportBatchMapper.java
git mv src/main/java/com/label/module/source/mapper/SourceDataMapper.java src/main/java/com/label/mapper/SourceDataMapper.java
git mv src/main/java/com/label/module/task/mapper/AnnotationTaskMapper.java src/main/java/com/label/mapper/AnnotationTaskMapper.java
git mv src/main/java/com/label/module/task/mapper/TaskHistoryMapper.java src/main/java/com/label/mapper/TaskHistoryMapper.java
git mv src/main/java/com/label/module/user/mapper/SysCompanyMapper.java src/main/java/com/label/mapper/SysCompanyMapper.java
git mv src/main/java/com/label/module/user/mapper/SysUserMapper.java src/main/java/com/label/mapper/SysUserMapper.java
git mv src/main/java/com/label/module/video/mapper/VideoProcessJobMapper.java src/main/java/com/label/mapper/VideoProcessJobMapper.java
```
统一替换包声明:
```java
package com.label.dto;
package com.label.entity;
package com.label.mapper;
```
然后把上面 `Files` 列表中的旧 `com.label.module.*.(dto|entity|mapper)` import 全部改到新包。
- [ ] **Step 4: 跑绿**
Run:
- `mvn -q "-Dtest=PackageStructureMigrationTest#dataTypesMoved,OpenApiAnnotationTest,AuthIntegrationTest,ExtractionApprovalIntegrationTest,QaApprovalIntegrationTest,UserManagementIntegrationTest" test`
Expected: PASS。
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/label/dto src/main/java/com/label/entity src/main/java/com/label/mapper src/test/java/com/label/unit/PackageStructureMigrationTest.java src/test/java/com/label/unit/OpenApiAnnotationTest.java src/test/java/com/label/integration/AuthIntegrationTest.java src/test/java/com/label/integration/ExtractionApprovalIntegrationTest.java src/test/java/com/label/integration/QaApprovalIntegrationTest.java src/test/java/com/label/integration/UserManagementIntegrationTest.java src/main/java/com/label/module
git commit -m "refactor: flatten dto entity and mapper packages"
```
---
### Task 3: 迁移业务服务层
**Files:**
- Modify: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- Modify: `src/main/java/com/label/module/annotation/controller/ExtractionController.java`
- Modify: `src/main/java/com/label/module/annotation/controller/QaController.java`
- Modify: `src/main/java/com/label/module/config/controller/SysConfigController.java`
- Modify: `src/main/java/com/label/module/export/controller/ExportController.java`
- Modify: `src/main/java/com/label/module/source/controller/SourceController.java`
- Modify: `src/main/java/com/label/module/task/controller/TaskController.java`
- Modify: `src/main/java/com/label/module/user/controller/AuthController.java`
- Modify: `src/main/java/com/label/module/user/controller/UserController.java`
- Modify: `src/main/java/com/label/module/video/controller/VideoController.java`
- Test: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- [ ] **Step 1: 写失败测试**
```java
@Test
@DisplayName("服务类已迁移到扁平 service 目录")
void serviceTypesMoved() {
for (String fqcn : java.util.List.of(
"com.label.service.ExtractionService", "com.label.service.QaService",
"com.label.service.SysConfigService", "com.label.service.ExportService",
"com.label.service.FinetuneService", "com.label.service.SourceService",
"com.label.service.TaskClaimService", "com.label.service.TaskService",
"com.label.service.AuthService", "com.label.service.UserService",
"com.label.service.VideoProcessService")) {
assertClassExists(fqcn);
}
}
```
- [ ] **Step 2: 跑红**
Run: `mvn -q "-Dtest=PackageStructureMigrationTest#serviceTypesMoved" test`
Expected: FAIL提示 `com.label.service.*` 不存在。
- [ ] **Step 3: 最小实现**
执行迁移:
```powershell
git mv src/main/java/com/label/module/annotation/service/ExtractionService.java src/main/java/com/label/service/ExtractionService.java
git mv src/main/java/com/label/module/annotation/service/QaService.java src/main/java/com/label/service/QaService.java
git mv src/main/java/com/label/module/config/service/SysConfigService.java src/main/java/com/label/service/SysConfigService.java
git mv src/main/java/com/label/module/export/service/ExportService.java src/main/java/com/label/service/ExportService.java
git mv src/main/java/com/label/module/export/service/FinetuneService.java src/main/java/com/label/service/FinetuneService.java
git mv src/main/java/com/label/module/source/service/SourceService.java src/main/java/com/label/service/SourceService.java
git mv src/main/java/com/label/module/task/service/TaskClaimService.java src/main/java/com/label/service/TaskClaimService.java
git mv src/main/java/com/label/module/task/service/TaskService.java src/main/java/com/label/service/TaskService.java
git mv src/main/java/com/label/module/user/service/AuthService.java src/main/java/com/label/service/AuthService.java
git mv src/main/java/com/label/module/user/service/UserService.java src/main/java/com/label/service/UserService.java
git mv src/main/java/com/label/module/video/service/VideoProcessService.java src/main/java/com/label/service/VideoProcessService.java
```
统一替换:
```java
package com.label.service;
```
并把 `ExtractionController``QaController``SysConfigController``ExportController``SourceController``TaskController``AuthController``UserController``VideoController` 的服务导包改到 `com.label.service.*`
- [ ] **Step 4: 跑绿**
Run:
- `mvn -q "-Dtest=PackageStructureMigrationTest#serviceTypesMoved" test`
- `mvn -q -DskipTests compile`
Expected: PASS。
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/label/service src/main/java/com/label/module/annotation/controller/ExtractionController.java src/main/java/com/label/module/annotation/controller/QaController.java src/main/java/com/label/module/config/controller/SysConfigController.java src/main/java/com/label/module/export/controller/ExportController.java src/main/java/com/label/module/source/controller/SourceController.java src/main/java/com/label/module/task/controller/TaskController.java src/main/java/com/label/module/user/controller/AuthController.java src/main/java/com/label/module/user/controller/UserController.java src/main/java/com/label/module/video/controller/VideoController.java src/test/java/com/label/unit/PackageStructureMigrationTest.java
git commit -m "refactor: flatten service packages"
```
---
### Task 4: 迁移控制器并收敛 OpenAPI 测试
**Files:**
- Modify: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- Modify: `src/test/java/com/label/unit/OpenApiAnnotationTest.java`
- Test: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- Test: `src/test/java/com/label/unit/OpenApiAnnotationTest.java`
- [ ] **Step 1: 写失败测试**
```java
@Test
@DisplayName("控制器已迁移到扁平 controller 目录")
void controllerTypesMoved() {
for (String fqcn : java.util.List.of(
"com.label.controller.AuthController", "com.label.controller.UserController",
"com.label.controller.SourceController", "com.label.controller.TaskController",
"com.label.controller.ExtractionController", "com.label.controller.QaController",
"com.label.controller.ExportController", "com.label.controller.SysConfigController",
"com.label.controller.VideoController")) {
assertClassExists(fqcn);
}
}
```
- [ ] **Step 2: 跑红**
Run: `mvn -q "-Dtest=PackageStructureMigrationTest#controllerTypesMoved" test`
Expected: FAIL提示 `com.label.controller.*` 不存在。
- [ ] **Step 3: 最小实现**
执行迁移:
```powershell
git mv src/main/java/com/label/module/annotation/controller/ExtractionController.java src/main/java/com/label/controller/ExtractionController.java
git mv src/main/java/com/label/module/annotation/controller/QaController.java src/main/java/com/label/controller/QaController.java
git mv src/main/java/com/label/module/config/controller/SysConfigController.java src/main/java/com/label/controller/SysConfigController.java
git mv src/main/java/com/label/module/export/controller/ExportController.java src/main/java/com/label/controller/ExportController.java
git mv src/main/java/com/label/module/source/controller/SourceController.java src/main/java/com/label/controller/SourceController.java
git mv src/main/java/com/label/module/task/controller/TaskController.java src/main/java/com/label/controller/TaskController.java
git mv src/main/java/com/label/module/user/controller/AuthController.java src/main/java/com/label/controller/AuthController.java
git mv src/main/java/com/label/module/user/controller/UserController.java src/main/java/com/label/controller/UserController.java
git mv src/main/java/com/label/module/video/controller/VideoController.java src/main/java/com/label/controller/VideoController.java
```
统一替换:
```java
package com.label.controller;
```
并把 `OpenApiAnnotationTest.java` 的 import 替换成:
```java
import com.label.controller.AuthController;
import com.label.controller.UserController;
import com.label.controller.SourceController;
import com.label.controller.TaskController;
import com.label.controller.ExtractionController;
import com.label.controller.QaController;
import com.label.controller.ExportController;
import com.label.controller.SysConfigController;
import com.label.controller.VideoController;
import com.label.dto.LoginRequest;
import com.label.dto.LoginResponse;
import com.label.dto.UserInfoResponse;
import com.label.dto.TaskResponse;
import com.label.dto.SourceResponse;
```
- [ ] **Step 4: 跑绿**
Run: `mvn -q "-Dtest=PackageStructureMigrationTest#controllerTypesMoved,OpenApiAnnotationTest" test`
Expected: PASS。
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/label/controller src/test/java/com/label/unit/PackageStructureMigrationTest.java src/test/java/com/label/unit/OpenApiAnnotationTest.java
git commit -m "refactor: flatten controller packages"
```
---
### Task 5: 清理旧包残留并做全量回归
**Files:**
- Modify: `src/test/java/com/label/unit/PackageStructureMigrationTest.java`
- Test: `src/test/java/com/label/LabelBackendApplicationTests.java`
- Test: `src/test/java/com/label/unit/ApplicationConfigTest.java`
- Test: `src/test/java/com/label/unit/ShiroConfigTest.java`
- Test: `src/test/java/com/label/unit/StateMachineTest.java`
- Test: `src/test/java/com/label/unit/TokenFilterTest.java`
- Test: `src/test/java/com/label/integration/AuthIntegrationTest.java`
- Test: `src/test/java/com/label/integration/ExportIntegrationTest.java`
- Test: `src/test/java/com/label/integration/ExtractionApprovalIntegrationTest.java`
- Test: `src/test/java/com/label/integration/MultiTenantIsolationTest.java`
- Test: `src/test/java/com/label/integration/QaApprovalIntegrationTest.java`
- Test: `src/test/java/com/label/integration/ShiroFilterIntegrationTest.java`
- Test: `src/test/java/com/label/integration/SourceIntegrationTest.java`
- Test: `src/test/java/com/label/integration/SysConfigIntegrationTest.java`
- Test: `src/test/java/com/label/integration/TaskClaimConcurrencyTest.java`
- Test: `src/test/java/com/label/integration/UserManagementIntegrationTest.java`
- Test: `src/test/java/com/label/integration/VideoCallbackIdempotencyTest.java`
- [ ] **Step 1: 写最终守卫测试**
`PackageStructureMigrationTest.java` 中补充:
```java
@Test
@DisplayName("源码中不再引用旧的 module、common.aop、common.config 包")
void sourceTreeHasNoLegacyPackageReferences() throws Exception {
try (java.util.stream.Stream<java.nio.file.Path> paths = java.nio.file.Files.walk(java.nio.file.Path.of("src"))) {
java.util.List<String> violations = paths
.filter(path -> path.toString().endsWith(".java"))
.map(path -> {
try {
String text = java.nio.file.Files.readString(path);
boolean legacy = text.contains("com.label.module.")
|| text.contains("com.label.common.aop")
|| text.contains("com.label.common.config");
return legacy ? path.toString() : null;
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.filter(java.util.Objects::nonNull)
.toList();
org.assertj.core.api.Assertions.assertThat(violations).isEmpty();
}
}
```
- [ ] **Step 2: 跑红并定位残留**
Run:
- `mvn -q "-Dtest=PackageStructureMigrationTest#sourceTreeHasNoLegacyPackageReferences" test`
- `rg -n "com\.label\.module\.|com\.label\.common\.aop|com\.label\.common\.config" src/main/java src/test/java`
Expected: 初次 FAIL并列出残留文件。
- [ ] **Step 3: 清理残留并确认旧目录为空**
Run:
```powershell
Get-ChildItem -Path src/main/java/com/label/module -Recurse
```
Expected: 没有 Java 文件残留;确认后删除空目录。
- [ ] **Step 4: 全量回归**
Run: `mvn clean test`
Expected: `BUILD SUCCESS`
- [ ] **Step 5: Commit**
```powershell
git add src/main/java src/test/java
git commit -m "refactor: complete backend directory flattening"
```
---
## 自检
- 覆盖了 `annotation / aspect / config / event / listener / dto / entity / mapper / service / controller`
- 没有引入 `service.impl`
- 没有拆分 `dto/request``dto/response`
- 最终门槛是 `mvn clean test`