11 KiB
New Product Survey Step Four 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: Deliver the student-only fourth step that collects three AI application-value analyses and blocks final task submission until all are filled.
Architecture: Keep the existing StudentTrainingAnswer.step4Answer JSON persistence and add a stateless student-only validation endpoint. The Vue page retains a local draft and calls the validation endpoint only on final submission; the demo client enforces the same non-empty rule locally.
Tech Stack: Vue 3 Composition API, Element Plus, Vite, Spring Boot, Java 8, JUnit 5, Mockito.
Global Constraints
- Only change the student
new-product-surveypage and its supporting student validation API; do not change teacher, admin, table schema, prior steps, or material download behavior. - Persist
{ coreValue, tangibleValue, extendedValue }in the existingstep4Answerfield. - A value is valid only when
trim()leaves non-empty text; validation does not score analysis quality. - Saving a draft remains allowed with empty fields; final
SUBMITis guarded by validation. - Keep legacy fourth-step JSON restoration compatible.
- Do not start the backend automatically; the user starts it manually.
Task 1: Add server-side fourth-step validation
Files:
- Create:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/main/java/com/sztzjy/linkCommerce/entity/dto/NewProductSurveyStepFourValidationRequest.java - Create:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/main/java/com/sztzjy/linkCommerce/entity/dto/NewProductSurveyStepFourValidationResult.java - Create:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/main/java/com/sztzjy/linkCommerce/service/NewProductSurveyStepFourService.java - Create:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/main/java/com/sztzjy/linkCommerce/service/impl/NewProductSurveyStepFourServiceImpl.java - Modify:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java - Test:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/test/java/com/sztzjy/linkCommerce/service/impl/NewProductSurveyStepFourServiceImplTest.java - Test:
E:/workspace/dianshang/link_commerce/.worktrees/new-product-survey-step3/src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java
Interfaces:
-
Consumes: authenticated
JwtUserandNewProductSurveyStepFourValidationRequest { String coreValue, String tangibleValue, String extendedValue }. -
Produces:
NewProductSurveyStepFourValidationResult { boolean valid, String message }fromPOST /api/student-training-answers/new-product-survey/step-4/validate. -
Step 1: Write the failing service tests
@Test
void acceptsStudentWithAllThreeNonBlankValues() {
NewProductSurveyStepFourValidationRequest request = request("核心分析", "有形分析", "延伸分析");
assertTrue(service.validate(request, student()).isValid());
}
@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {" ", "\t"})
void rejectsBlankCoreValue(String value) {
assertThrows(ServiceException.class, () -> service.validate(request(value, "有形", "延伸"), student()));
}
@Test
void rejectsNonStudent() {
assertThrows(ServiceException.class, () -> service.validate(request("核心", "有形", "延伸"), teacher()));
}
- Step 2: Run the service test to verify it fails
Run: mvn -B '-Dtest=NewProductSurveyStepFourServiceImplTest' test
Expected: FAIL because fourth-step request and service types do not exist.
- Step 3: Implement DTOs and service
public interface NewProductSurveyStepFourService {
NewProductSurveyStepFourValidationResult validate(NewProductSurveyStepFourValidationRequest request, JwtUser user);
}
private void requireNonBlank(String value, String message) {
if (StringUtils.isBlank(value)) {
throw new ServiceException(HttpStatus.BAD_REQUEST, message);
}
}
Require the existing student role and user id, then require coreValue, tangibleValue, and extendedValue after trimming. Return valid=true and 校验通过 on success.
- Step 4: Run the service test to verify it passes
Run: mvn -B '-Dtest=NewProductSurveyStepFourServiceImplTest' test
Expected: PASS with nonblank, blank, and authorization behavior covered.
- Step 5: Write the failing controller test
@Test
void validateStepFourUsesAuthenticatedStudentAndReturnsValidationResult() {
NewProductSurveyStepFourValidationResult result = new NewProductSurveyStepFourValidationResult(true, "校验通过");
when(newProductSurveyStepFourService.validate(any(), any())).thenReturn(result);
ResultEntity<NewProductSurveyStepFourValidationResult> response = controller
.validateNewProductSurveyStepFour(request("核心", "有形", "延伸"), authenticatedRequest());
assertEquals(HttpStatus.OK, response.getCode());
assertSame(result, response.getData());
}
- Step 6: Run the controller test to verify it fails
Run: mvn -B '-Dtest=StudentTrainingAnswerControllerTest' test
Expected: FAIL because validateNewProductSurveyStepFour does not exist.
- Step 7: Add the controller endpoint
@PostMapping("/new-product-survey/step-4/validate")
public ResultEntity<NewProductSurveyStepFourValidationResult> validateNewProductSurveyStepFour(
@RequestBody NewProductSurveyStepFourValidationRequest answer, HttpServletRequest request) {
try {
return new ResultEntity<>(HttpStatus.OK, "校验通过",
newProductSurveyStepFourService.validate(answer, TokenProvider.getJWTUser(request)));
} catch (ServiceException e) {
return new ResultEntity<>(e.getCode(), e.getMessage());
}
}
- Step 8: Run focused server tests
Run: mvn -B '-Dtest=NewProductSurveyStepFourServiceImplTest,StudentTrainingAnswerControllerTest' test
Expected: PASS with fourth-step service behavior and endpoint delegation covered.
- Step 9: Commit server validation
git add src/main/java/com/sztzjy/linkCommerce/entity/dto/NewProductSurveyStepFourValidationRequest.java src/main/java/com/sztzjy/linkCommerce/entity/dto/NewProductSurveyStepFourValidationResult.java src/main/java/com/sztzjy/linkCommerce/service/NewProductSurveyStepFourService.java src/main/java/com/sztzjy/linkCommerce/service/impl/NewProductSurveyStepFourServiceImpl.java src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java src/test/java/com/sztzjy/linkCommerce/service/impl/NewProductSurveyStepFourServiceImplTest.java src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java
git commit -m "feat: validate new product survey step four"
Task 2: Update the fourth-step student UI and submission flow
Files:
- Modify:
E:/workspace/dianshang/e-commerce-internet/.worktrees/new-product-survey-step3/src/api/studentTrainingAnswer.js - Modify:
E:/workspace/dianshang/e-commerce-internet/.worktrees/new-product-survey-step3/src/views/foundation/new-product-survey.vue - Modify:
E:/workspace/dianshang/e-commerce-internet/.worktrees/new-product-survey-step3/tests/new-product-survey-step-one.static.test.cjs
Interfaces:
-
Consumes:
checkNewProductSurveyStepFour(payload)returning{ code: 200, data: { valid: true, message: "校验通过" } }. -
Produces: guarded
submitTask()that savesstep4Answeronly after successful validation. -
Step 1: Add failing static source assertions
assert.match(page, /AI技术是否实现产品功能突破?是否形成差异化卖点?/, "step four must show the core-layer prototype question");
assert.match(page, /AI技术是否影响产品形态?如产品外形包装、电商主图设计、参数配置、价格带定位。/, "step four must show the tangible-layer prototype question");
assert.match(page, /AI技术如何通过服务升级、内容更新提升用户粘性,推动付费服务?/, "step four must show the extended-layer prototype question");
assert.match(page, /checkNewProductSurveyStepFour\(step4Form\.value\)/, "step four must validate before submission");
assert.match(api, /new-product-survey\/step-4\/validate/, "the API must expose the step-four validation route");
- Step 2: Run the static test to verify it fails
Run: & 'E:\Program Files\nodejs\node.exe' tests\new-product-survey-step-one.static.test.cjs
Expected: FAIL because the fourth-step question copy and validation call are absent.
- Step 3: Implement client validation and prototype-aligned form
function validateNewProductSurveyStepFourDemo(form) {
const value = form || {};
for (const [field, label] of [["coreValue", "核心层"], ["tangibleValue", "有形层"], ["extendedValue", "延伸层"]]) {
if (!String(value[field] || "").trim()) throw new Error(`请填写${label}AI应用价值分析`);
}
return { valid: true, message: "校验通过" };
}
async function submitTask() {
checking.value = true;
try {
await checkNewProductSurveyStepFour(step4Form.value);
await saveAnswer("SUBMITTED");
} catch (error) {
proxy?.$modal?.msgWarning(error?.message || "请完成三层次AI应用价值分析");
} finally {
checking.value = false;
}
}
Replace the existing generic field labels with the three prototype questions, keep their bindings as coreValue, tangibleValue, and extendedValue, and preserve draft saving and restoration.
- Step 4: Run the static test to verify it passes
Run: & 'E:\Program Files\nodejs\node.exe' tests\new-product-survey-step-one.static.test.cjs
Expected: PASS with prior step contracts still intact.
- Step 5: Commit student UI and client validation
git add src/api/studentTrainingAnswer.js src/views/foundation/new-product-survey.vue tests/new-product-survey-step-one.static.test.cjs
git commit -m "feat: add new product survey step four"
Task 3: Run full verification
Files:
- Modify: none.
Interfaces:
-
Consumes: both committed fourth-step implementations.
-
Produces: verification evidence before integration; no application process is started.
-
Step 1: Run complete backend tests
Run: mvn -B test
Expected: Maven reports BUILD SUCCESS and zero failures.
- Step 2: Run the frontend source contract
Run: & 'E:\Program Files\nodejs\node.exe' tests\new-product-survey-step-one.static.test.cjs
Expected: new product survey step-one contract passed.
- Step 3: Run the production frontend build
Run: & 'E:\Program Files\nodejs\node.exe' 'E:\workspace\dianshang\e-commerce-internet\node_modules\vite\bin\vite.js' build
Expected: Vite exits with code 0. Existing ::v-deep, unresolved Navbar.vue top1 asset, and large-chunk warnings may remain.
- Step 4: Inspect repository state
Run: git status --short; git log --oneline --max-count=5
Expected: only the intended fourth-step commits are present; do not start the backend.