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-new-product-surv...

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-survey page 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 existing step4Answer field.
  • 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 SUBMIT is 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 JwtUser and NewProductSurveyStepFourValidationRequest { String coreValue, String tangibleValue, String extendedValue }.

  • Produces: NewProductSurveyStepFourValidationResult { boolean valid, String message } from POST /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 saves step4Answer only 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.