Files
everything-is-suitable/docs/plans/2026-03-09-product-launch-readiness-fix.md
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

16 KiB

产品上线准备修复计划

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: 系统性解决所有阻塞上线的问题,使产品达到上线标准

Architecture: 采用三阶段修复策略:先解决P0阻塞性问题(服务启动),再提升P1质量问题(测试稳定性),最后优化P2技术债务(测试覆盖率)

Tech Stack: Spring Boot 4.0.1, Vue 3 + Vite, Uniapp, Playwright, Vitest, pytest, Woodpecker CI


阶段一:P0问题修复(预计1-2天)

Task 1: 修复API服务JacksonConfig配置冲突

问题: io.destiny.base.config.JacksonConfigio.destiny.common.config.JacksonConfig 冲突导致Spring Boot无法启动

Files:

  • Modify: everything-is-suitable-api/everything-is-suitable-base/src/main/java/io/destiny/base/config/JacksonConfig.java
  • Modify: everything-is-suitable-api/everything-is-suitable-common/src/main/java/io/destiny/common/config/JacksonConfig.java (如果存在)
  • Test: 启动API服务验证

Step 1: 检查是否存在重复的JacksonConfig

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable
find everything-is-suitable-api -name "JacksonConfig.java" -type f

Expected: 找到重复的配置文件

Step 2: 分析JacksonConfig内容

# 检查base模块的JacksonConfig
cat everything-is-suitable-api/everything-is-suitable-base/src/main/java/io/destiny/base/config/JacksonConfig.java

# 检查common模块的JacksonConfig(如果存在)
find everything-is-suitable-api/everything-is-suitable-common -name "JacksonConfig.java" -exec cat {} \;

Expected: 确认配置内容和功能

Step 3: 删除或合并重复配置

策略:保留一个JacksonConfig,删除另一个

# 如果base模块的JacksonConfig更完整,删除common模块的
# 或者合并两个配置到一个文件中
rm everything-is-suitable-api/everything-is-suitable-common/src/main/java/io/destiny/common/config/JacksonConfig.java

Step 4: 验证API服务启动

cd everything-is-suitable-api/everything-is-suitable-app
mvn spring-boot:run

Expected: 服务成功启动,无配置冲突错误

Step 5: 提交修复

git add .
git commit -m "fix: resolve JacksonConfig conflict in API service"

Task 2: 恢复Uniapp项目package.json配置

问题: Uniapp项目缺少package.json,无法执行npm命令

Files:

  • Create: everything-is-suitable-uniapp/package.json
  • Test: 验证npm命令可执行

Step 1: 检查Uniapp项目结构

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-uniapp
ls -la | grep -E "package|manifest"

Expected: 确认缺少package.json

Step 2: 创建package.json

{
  "name": "everything-is-suitable-uniapp",
  "version": "1.0.0",
  "description": "Uniapp移动端应用",
  "scripts": {
    "dev:h5": "uni -p h5",
    "build:h5": "uni build -p h5",
    "dev:mp-weixin": "uni -p mp-weixin",
    "build:mp-weixin": "uni build -p mp-weixin",
    "test": "vitest",
    "test:e2e": "playwright test"
  },
  "dependencies": {
    "vue": "^3.5.26",
    "vue-router": "^4.6.4",
    "pinia": "^3.0.4",
    "lunar-javascript": "^1.6.12"
  },
  "devDependencies": {
    "@dcloudio/uni-cli-shared": "^3.0.0",
    "@dcloudio/vite-plugin-uni": "^3.0.0",
    "@playwright/test": "^1.40.1",
    "vitest": "^4.0.16",
    "typescript": "^5.9.3",
    "vite": "^7.3.1"
  }
}

Step 3: 安装依赖

npm install

Expected: 依赖安装成功

Step 4: 验证Uniapp服务启动

npm run dev:h5

Expected: H5开发服务器成功启动

Step 5: 提交修复

git add package.json package-lock.json
git commit -m "fix: restore package.json for uniapp project"

Task 3: 验证所有服务启动状态

Files:

  • Test: 验证三个服务均可正常启动

Step 1: 启动API服务

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-api/everything-is-suitable-app
mvn spring-boot:run &

Expected: API服务在8080端口启动成功

Step 2: 启动Admin服务

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-admin
npm run dev:local &

Expected: Admin服务在5173端口启动成功

Step 3: 启动Uniapp服务

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-uniapp
npm run dev:h5 &

Expected: Uniapp H5服务启动成功

Step 4: 验证服务健康状态

# 检查API健康
curl http://localhost:8080/actuator/health

# 检查Admin服务
curl http://localhost:5173

# 检查Uniapp服务(根据实际端口)
curl http://localhost:5174

Expected: 所有服务返回正常响应

Step 5: 记录验证结果

echo "✅ P0问题修复完成 - 所有服务正常启动" >> /Users/zhangxiang/Codes/Gitee/everything-is-suitable/docs/reports/p0-fix-report.md

阶段二:测试质量提升(预计3-5天)

Task 4: 创建测试数据工厂

问题: 测试数据重复导致"duplicate key error"

Files:

  • Create: everything-is-suitable-admin/src/test/utils/test-data-factory.ts
  • Modify: everything-is-suitable-admin/src/services/__tests__/user.service.management.test.ts

Step 1: 创建测试数据工厂

// everything-is-suitable-admin/src/test/utils/test-data-factory.ts
export class TestDataFactory {
  private static counter = 0;

  static generateUniqueUsername(): string {
    return `test_user_${Date.now()}_${++this.counter}`;
  }

  static generateUniqueEmail(): string {
    return `test_${Date.now()}_${++this.counter}@example.com`;
  }

  static createUserData(overrides: Partial<any> = {}) {
    return {
      username: this.generateUniqueUsername(),
      email: this.generateUniqueEmail(),
      password: 'Test@123456',
      ...overrides
    };
  }

  static reset() {
    this.counter = 0;
  }
}

Step 2: 重构用户服务测试使用数据工厂

// everything-is-suitable-admin/src/services/__tests__/user.service.management.test.ts
import { TestDataFactory } from '@/test/utils/test-data-factory';

describe('UserService', () => {
  beforeEach(() => {
    TestDataFactory.reset();
  });

  it('should create user with unique data', async () => {
    const userData = TestDataFactory.createUserData();
    const result = await userService.createUser(userData);
    expect(result.username).toBe(userData.username);
  });
});

Step 3: 运行测试验证

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-admin
npm test -- user.service.management.test.ts

Expected: 测试通过,无重复数据错误

Step 4: 应用到其他测试文件

# 查找所有需要修改的测试文件
grep -r "duplicate key" src/

Step 5: 提交改进

git add src/test/utils/test-data-factory.ts
git commit -m "feat: add test data factory to avoid duplicate data errors"

Task 5: 实现测试隔离机制

问题: 测试间相互影响,状态污染

Files:

  • Create: everything-is-suitable-admin/src/test/setup/test-isolation.ts
  • Modify: everything-is-suitable-admin/vitest.setup.ts

Step 1: 创建测试隔离工具

// everything-is-suitable-admin/src/test/setup/test-isolation.ts
import { beforeEach, afterEach } from 'vitest';

export function setupTestIsolation() {
  beforeEach(async () => {
    // 清理数据库
    await cleanDatabase();
    // 重置Mock状态
    resetMockState();
    // 清理本地存储
    localStorage.clear();
    sessionStorage.clear();
  });

  afterEach(async () => {
    // 清理测试数据
    await cleanupTestData();
    // 验证无残留状态
    await verifyCleanState();
  });
}

async function cleanDatabase() {
  // 实现数据库清理逻辑
}

function resetMockState() {
  // 重置所有Mock状态
}

async function cleanupTestData() {
  // 清理测试创建的数据
}

async function verifyCleanState() {
  // 验证环境干净
}

Step 2: 更新vitest配置

// everything-is-suitable-admin/vitest.setup.ts
import { setupTestIsolation } from './src/test/setup/test-isolation';

setupTestIsolation();

Step 3: 运行测试验证隔离

npm test

Expected: 测试通过,无状态污染

Step 4: 提交改进

git add src/test/setup/test-isolation.ts vitest.setup.ts
git commit -m "feat: implement test isolation mechanism"

Task 6: 完善错误处理机制

问题: 未处理的Promise拒绝和异常

Files:

  • Create: everything-is-suitable-admin/src/test/utils/error-handler.ts
  • Modify: everything-is-suitable-admin/src/test/setup/global-error-handler.ts

Step 1: 创建全局错误处理器

// everything-is-suitable-admin/src/test/setup/global-error-handler.ts
export function setupGlobalErrorHandler() {
  process.on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled Rejection at:', promise, 'reason:', reason);
    // 记录到测试报告
    throw new Error(`Unhandled Promise Rejection: ${reason}`);
  });

  process.on('uncaughtException', (error) => {
    console.error('Uncaught Exception:', error);
    throw error;
  });
}

Step 2: 在测试中使用错误处理

// everything-is-suitable-admin/vitest.setup.ts
import { setupGlobalErrorHandler } from './src/test/setup/global-error-handler';

setupGlobalErrorHandler();

Step 3: 运行测试验证

npm test 2>&1 | grep -i "unhandled"

Expected: 无未处理的异常输出

Step 4: 提交改进

git add src/test/setup/global-error-handler.ts
git commit -m "feat: add global error handler for tests"

Task 7: 修复失败的测试用例

问题: 231个测试失败

Files:

  • Modify: 多个测试文件(根据失败列表)

Step 1: 获取失败测试列表

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-admin
npm test 2>&1 | grep "FAIL" > /tmp/failed-tests.txt
cat /tmp/failed-tests.txt

Expected: 获取完整的失败测试列表

Step 2: 分类失败原因

# 统计失败原因
npm test 2>&1 | grep -E "(duplicate|timeout|assertion)" | sort | uniq -c

Step 3: 批量修复重复数据问题

# 应用Task 4的数据工厂到所有相关测试
find src -name "*.test.ts" -exec sed -i '' 's/test_user_/TestDataFactory.generateUniqueUsername()/g' {} \;

Step 4: 逐个修复其他失败测试

# 运行单个测试文件
npm test -- specific-test-file.test.ts

# 查看详细错误
npm test -- --reporter=verbose specific-test-file.test.ts

Step 5: 验证修复效果

npm test

Expected: 测试失败率降至<5%

Step 6: 提交修复

git add .
git commit -m "fix: resolve failing test cases"

阶段三:测试覆盖率提升(预计2-3天)

Task 8: 补充service层单元测试

问题: service层覆盖率0%

Files:

  • Create: everything-is-suitable-api/everything-is-suitable-biz/src/test/java/io/destiny/biz/service/impl/*Test.java

Step 1: 识别未测试的服务类

cd /Users/zhangxiang/Codes/Gitee/everything-is-suitable/everything-is-suitable-api/everything-is-suitable-biz
find src/main/java -name "*ServiceImpl.java" | while read f; do
  testfile=$(echo $f | sed 's|src/main/java|src/test/java|; s|\.java|Test.java|')
  if [ ! -f "$testfile" ]; then
    echo "Missing test: $testfile"
  fi
done

Step 2: 创建ZiweiChartServiceImplTest

// everything-is-suitable-api/everything-is-suitable-biz/src/test/java/io/destiny/biz/service/impl/ZiweiChartServiceImplTest.java
package io.destiny.biz.service.impl;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import static org.junit.jupiter.api.Assertions.*;

class ZiweiChartServiceImplTest {
    
    private ZiweiChartServiceImpl service;
    
    @BeforeEach
    void setUp() {
        service = new ZiweiChartServiceImpl();
    }
    
    @Test
    void shouldGenerateZiweiChart() {
        BirthInfo birthInfo = new BirthInfo(/* 参数 */);
        ZiweiChart chart = service.generateChart(birthInfo);
        
        assertNotNull(chart);
        assertNotNull(chart.getPalaces());
        assertTrue(chart.getPalaces().size() > 0);
    }
}

Step 3: 运行测试

mvn test -Dtest=ZiweiChartServiceImplTest

Expected: 测试通过

Step 4: 为所有service创建测试

重复Step 2-3,为所有service创建单元测试

Step 5: 验证覆盖率

mvn jacoco:report
open target/site/jacoco/index.html

Expected: service层覆盖率>70%

Step 6: 提交测试

git add src/test/java
git commit -m "test: add unit tests for service layer"

Task 9: 补充config层单元测试

问题: config层覆盖率15%

Files:

  • Create: everything-is-suitable-api/everything-is-suitable-biz/src/test/java/io/destiny/biz/config/*Test.java

Step 1: 创建路由配置测试

// everything-is-suitable-api/everything-is-suitable-biz/src/test/java/io/destiny/biz/config/AlmanacRouterTest.java
package io.destiny.biz.config;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AlmanacRouterTest {
    
    @Autowired
    private WebTestClient webTestClient;
    
    @Test
    void shouldRouteAlmanacRequest() {
        webTestClient.get()
            .uri("/api/almanac")
            .exchange()
            .expectStatus().isOk();
    }
}

Step 2: 运行测试

mvn test -Dtest=AlmanacRouterTest

Step 3: 为所有config创建测试

Step 4: 验证覆盖率

mvn jacoco:report

Expected: config层覆盖率>70%

Step 5: 提交测试

git add src/test/java
git commit -m "test: add unit tests for config layer"

Task 10: 最终验收测试

Files:

  • Test: 完整的端到端测试

Step 1: 运行完整测试套件

# 后端测试
cd everything-is-suitable-api
mvn clean test

# Admin前端测试
cd ../everything-is-suitable-admin
npm test

# E2E测试
npm run test:e2e

Expected: 所有测试通过

Step 2: 验证测试覆盖率

# 后端覆盖率
cd everything-is-suitable-api
mvn jacoco:report
cat target/site/jacoco/index.html | grep "Total"

# Admin前端覆盖率
cd ../everything-is-suitable-admin
npm test -- --coverage

Expected:

  • 指令覆盖率≥70%
  • 分支覆盖率≥65%
  • 方法覆盖率≥90%
  • 类覆盖率≥95%

Step 3: 验证服务启动

# 启动所有服务
./scripts/start-all-services.sh

# 验证健康状态
curl http://localhost:8080/actuator/health
curl http://localhost:5173
curl http://localhost:5174

Expected: 所有服务健康

Step 4: 生成验收报告

cat > docs/reports/final-acceptance-report.md << 'EOF'
# 产品上线准备验收报告

## 验收时间
$(date)

## 服务启动状态
- ✅ API服务: 正常启动
- ✅ Admin服务: 正常启动
- ✅ Uniapp服务: 正常启动

## 测试质量
- ✅ 单元测试失败率: <5%
- ✅ 测试覆盖率达标
- ✅ 无未处理异常

## 上线决策
✅ 产品已具备上线条件
EOF

Step 5: 提交验收报告

git add docs/reports/final-acceptance-report.md
git commit -m "docs: add final acceptance report"

验收标准

P0级别(必须100%通过)

  • API服务可正常启动
  • Admin服务可正常启动
  • Uniapp服务可正常启动
  • 无配置冲突错误

P1级别(必须95%以上通过)

  • 单元测试失败率<5%
  • 无未处理的Promise拒绝
  • 无测试数据重复错误
  • 测试隔离机制生效

P2级别(必须80%以上通过)

  • 指令覆盖率≥70%
  • 分支覆盖率≥65%
  • 方法覆盖率≥90%
  • 类覆盖率≥95%

风险与应对

风险1:修复引入新问题

  • 应对: 每个修复后运行完整测试套件
  • 验证: 使用git bisect定位问题

风险2:测试覆盖率提升困难

  • 应对: 优先覆盖核心业务逻辑
  • 验证: 使用jacoco报告指导补充

风险3:时间估算偏差

  • 应对: 每日评估进度,及时调整计划
  • 验证: 使用燃尽图跟踪

执行建议

推荐执行方式: Subagent-Driven Development

  • 每个Task分配给独立的subagent
  • 完成后进行代码审查
  • 快速迭代,及时反馈

预计总时间: 6-10个工作日

  • 阶段一: 1-2天
  • 阶段二: 3-5天
  • 阶段三: 2-3天