You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dianshang-qianduan/docs/superpowers/plans/2026-08-07-product-developm...

222 lines
9.8 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 产品开发关键因素第 3 步 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:** 为学生端产品开发关键因素实训实现第 3 步商业化及市场反馈分析、服务端校验与只保存进入第 4 步的流程。
**Architecture:** 前端在现有 `product-development-factors.vue` 中增加固定三行的第 3 步表格,并把数据独立写入 `step3Answer`。后端按前两步的分层模式新增 DTO、服务及控制器入口严格验证学生身份、三项固定维度及六个非空分析字段。
**Tech Stack:** Vue 3 Composition API、Element Plus、现有 request APISpring Boot、JUnit 5、Mockito、Maven。
## Global Constraints
- 仅修改学生端页面及学生答案校验接口;不调整教师端或任务配置。
- 不新增数据库表或字段,使用既有答案记录的 `step3Answer``currentStep`
- 第 3 步保存固定使用 `SAVE`、`submitted: false`、`currentStep: 4`,不得提交任务。
- 保存前必须通过正式或演示模式的一致校验:三个固定维度、六个分析字段全部非空。
---
### Task 1: 第 3 步后端校验服务
**Files:**
- Create: `src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationRequest.java`
- Create: `src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationResult.java`
- Create: `src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepThreeService.java`
- Create: `src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImpl.java`
- Test: `src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImplTest.java`
**Interfaces:**
- Consumes: `JwtUser`、`ServiceException`、Spring HTTP status conventions。
- Produces: `ProductDevelopmentFactorsStepThreeService#validate(ProductDevelopmentFactorsStepThreeValidationRequest, JwtUser)`,返回 `{ valid, message }`
- [ ] **Step 1: 写失败服务测试**
```java
@Test void acceptsCompleteStudentAnalyses() {
assertTrue(new ProductDevelopmentFactorsStepThreeServiceImpl().validate(valid(), student()).isValid());
}
@Test void rejectsBlankOrForgedAnalyses() {
ProductDevelopmentFactorsStepThreeValidationRequest blank = valid();
blank.getFactors().get(2).setFailedAnalysis(" ");
assertThrows(ServiceException.class, () -> service.validate(blank, student()));
ProductDevelopmentFactorsStepThreeValidationRequest forged = valid();
forged.getFactors().get(2).setDimension("伪造维度");
assertThrows(ServiceException.class, () -> service.validate(forged, student()));
}
```
- [ ] **Step 2: 运行测试确认失败**
Run: `mvn -B -Dtest=ProductDevelopmentFactorsStepThreeServiceImplTest test`
Expected: FAIL因为 DTO 和服务尚不存在。
- [ ] **Step 3: 实现最小服务**
```java
private static final Set<String> DIMENSIONS = new LinkedHashSet<>(Arrays.asList(
"供应链与成本控制", "商业模式", "市场反馈"));
if (user == null || StringUtils.isBlank(user.getUserId())) throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再提交");
if (user.getRoleId() != 4) throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可提交实训答案");
```
校验 `factors` 数量为 3、每个维度只出现一次且属于 `DIMENSIONS`,并要求每个 `successAnalysis`、`failedAnalysis` 均非空;合法时返回 `valid=true`、`message="校验通过"`。
- [ ] **Step 4: 运行服务测试确认通过**
Run: `mvn -B -Dtest=ProductDevelopmentFactorsStepThreeServiceImplTest test`
Expected: PASS覆盖合法、空值、伪造维度和非学生身份。
- [ ] **Step 5: 提交后端服务**
```bash
git add src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationRequest.java src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationResult.java src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepThreeService.java src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImpl.java src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImplTest.java
git commit -m "feat: validate product factors step three"
```
### Task 2: 第 3 步校验控制器入口
**Files:**
- Modify: `src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java`
- Modify: `src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java`
**Interfaces:**
- Consumes: Task 1 的 `ProductDevelopmentFactorsStepThreeService`
- Produces: `POST /api/student-training-answers/product-development-factors/step-3/validate`
- [ ] **Step 1: 写失败控制器测试**
```java
@Test void validateProductDevelopmentFactorsStepThreeUsesTheAuthenticatedStudentAndReturnsTheValidationResult() {
ProductDevelopmentFactorsStepThreeService service = mock(ProductDevelopmentFactorsStepThreeService.class);
ReflectionTestUtils.setField(controller, "productDevelopmentFactorsStepThreeService", service);
when(service.validate(any(ProductDevelopmentFactorsStepThreeValidationRequest.class), any(JwtUser.class))).thenReturn(validation);
ResultEntity<ProductDevelopmentFactorsStepThreeValidationResult> result = controller.validateProductDevelopmentFactorsStepThree(new ProductDevelopmentFactorsStepThreeValidationRequest(), authenticatedStudentRequest());
assertEquals(HttpStatus.OK, result.getStatusCode());
}
```
- [ ] **Step 2: 运行测试确认失败**
Run: `mvn -B -Dtest=StudentTrainingAnswerControllerTest test`
Expected: FAIL因为第 3 步服务注入字段和控制器方法尚不存在。
- [ ] **Step 3: 增加路由与转发**
```java
@PostMapping("/product-development-factors/step-3/validate")
public ResultEntity<ProductDevelopmentFactorsStepThreeValidationResult> validateProductDevelopmentFactorsStepThree(
@RequestBody ProductDevelopmentFactorsStepThreeValidationRequest request,
HttpServletRequest servletRequest) {
return ResultEntity.ok(productDevelopmentFactorsStepThreeService.validate(request, getJwtUser(servletRequest)));
}
```
- [ ] **Step 4: 运行控制器测试确认通过**
Run: `mvn -B -Dtest=StudentTrainingAnswerControllerTest,ProductDevelopmentFactorsStepThreeServiceImplTest test`
Expected: PASS。
- [ ] **Step 5: 提交控制器**
```bash
git add src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java
git commit -m "feat: expose product factors step three validation"
```
### Task 3: 第 3 步学生页面、草稿和 API
**Files:**
- Modify: `src/views/foundation/product-development-factors.vue`
- Modify: `src/api/studentTrainingAnswer.js`
- Modify: `tests/product-development-factors-step-one.static.test.cjs`
**Interfaces:**
- Consumes: Task 2 的正式校验 URL、既有 `saveStudentTrainingAnswer`、`getStudentTrainingAnswer`。
- Produces: 第 3 步固定三行分析页面;`step3Answer`、`currentStep: 4`、`checkProductDevelopmentFactorsStepThree(payload)`。
- [ ] **Step 1: 先扩展前端静态契约测试**
```js
assert.match(pageSource, /STEP_THREE_FACTOR_ROWS/);
assert.match(pageSource, /供应链与成本控制/);
assert.match(pageSource, /商业模式/);
assert.match(pageSource, /市场反馈/);
assert.match(pageSource, /step3Answer/);
assert.match(pageSource, /saveAndGoToStepFour/);
assert.match(apiSource, /product-development-factors\/step-3\/validate/);
```
- [ ] **Step 2: 运行静态测试确认失败**
Run: `node tests/product-development-factors-step-one.static.test.cjs`
Expected: FAIL因为第 3 步常量、保存函数和 API 尚不存在。
- [ ] **Step 3: 实现前端最小改动**
`currentStep === 2` 增加表格;建立 `STEP_THREE_FACTOR_ROWS`、`createStepThreeRows`、`stepThreeRows`,并扩展草稿、答案恢复、导出与清空。
```js
function buildStepThreeAnswerPayload(saveAction = "SAVE", persistedStep = 4) {
return {
step3Answer: JSON.stringify(buildStepThreeOutcome()),
currentStep: persistedStep,
submitted: false,
saveAction,
};
}
```
实现正式 API 和演示模式的一致校验;`saveAndGoToStepFour` 成功后清理草稿并在第 4 步存在时将 `currentStep` 设为 `3`,否则显示已保存但未配置第 4 步的提示。
- [ ] **Step 4: 运行前端测试与生产构建**
Run: `node tests/product-development-factors-step-one.static.test.cjs; npm run build:prod`
Expected: 静态契约测试与生产构建均 PASS。
- [ ] **Step 5: 提交前端改动**
```bash
git add src/views/foundation/product-development-factors.vue src/api/studentTrainingAnswer.js tests/product-development-factors-step-one.static.test.cjs
git commit -m "feat: add product factors step three analysis"
```
### Task 4: 全量回归与交付检查
**Files:**
- Verify only: 前后端工作树的已提交变更。
**Interfaces:**
- Consumes: Tasks 13。
- Produces: 经过完整回归验证的前后端功能分支。
- [ ] **Step 1: 运行后端全量测试**
Run: `mvn -B test`
Expected: BUILD SUCCESS所有测试通过。
- [ ] **Step 2: 运行前端完整验证**
Run: `node tests/product-development-factors-step-one.static.test.cjs; npm run build:prod`
Expected: 静态契约测试和生产构建成功。
- [ ] **Step 3: 审查工作树**
Run: `git status --short; git log --oneline -3`
Expected: 仅本功能的预期提交;不纳入主工作区已有未跟踪文件。
- [ ] **Step 4: 汇报并等待集成指令**
报告功能、提交和验证结果,等待用户明确指示合并、推送或发布。