2026-04-30-achievement-report-mastery-hit-rate.md 6.4 KB

Achievement Report Mastery Hit Rate Implementation Plan

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

Goal: Rename the achievement-report metric from 真题生词命中率 to 试卷掌握度命中率, and derive its displayed value from 试卷熟词提升 ÷ 词汇量提升, rounded to 1 decimal place as a percentage, with 0% when 词汇量提升 = 0.

Architecture: Keep the existing report DTO/placeholder shape intact and change only the application-layer mapping logic plus presentation text. Compute the percentage inside AchievementReportContentMapper from the existing delta fields so infrastructure rendering continues to consume the same unknownWordHitRateText placeholders without contract changes.

Tech Stack: Java, Maven, JUnit 5, AssertJ, HTML template rendering.


Task 1: Replace payload-driven metric with derived mastery hit rate

Files:

  • Modify: abilities/exam-sprint/application/src/main/java/cn/yunzhixue/ability/center/examsprint/application/report/AchievementReportContentMapper.java
  • Test: abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/AchievementReportContentMapperTest.java
  • Test: abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportApplicationServiceTest.java

Step 1: Write the failing tests

  • Update mapper/service expectations so the metric is derived from TestPaperImprovedWordCount ÷ StudentImproveWordCount instead of PaperMasteryHitRate.
  • Use the existing sample payload to expect 4 ÷ 19 = 21.1%.
  • Add a zero-denominator case expecting 0% when StudentImproveWordCount = 0.
  • Make at least one test keep PaperMasteryHitRate at a deliberately mismatched value so RED proves the old field is no longer the source.

Step 2: Run tests to verify they fail

Run:

mvn -pl abilities/exam-sprint/application -am -Dtest=AchievementReportContentMapperTest,ExamSprintReportApplicationServiceTest test

Expected: FAIL because the mapper still uses PaperMasteryHitRate and formats 1.93% instead of 21.1% / 0%.

Step 3: Write the minimal implementation

  • Add a small helper in AchievementReportContentMapper that:
    • reads payload.testPaperImprovedWordCount() as numerator
    • reads payload.studentImproveWordCount() as denominator
    • returns "0%" when denominator is zero
    • otherwise computes (numerator / denominator) * 100
    • rounds half up to 1 decimal place
    • formats non-zero denominator results with exactly 1 decimal place so 20% becomes 20.0% while 21.1% stays 21.1%
  • Reuse the computed string for both summaryMetrics.unknownWordHitRateText and examUnknownWordsHitStatus.unknownWordHitRateText.

Step 4: Run tests to verify they pass

Run:

mvn -pl abilities/exam-sprint/application -am -Dtest=AchievementReportContentMapperTest,ExamSprintReportApplicationServiceTest test

Expected: PASS.

Step 5: Do not commit

  • Leave changes uncommitted unless the user explicitly asks for a commit.

Task 2: Rename the displayed metric label everywhere in achievement report outputs

Files:

  • Modify: abilities/exam-sprint/infrastructure/src/main/resources/templates/achievement-exam-sprint-report-template.html
  • Test: abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/rendering/achievement/ClasspathAchievementExamSprintReportRendererTest.java
  • Test: abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGeneratorTest.java

Step 1: Write the failing tests

  • Update assertions from 真题生词命中率 to 试卷掌握度命中率.
  • Update rendered value expectations from 1.93% to 21.1% based on the shared sample payload.

Step 2: Run tests to verify they fail

Run:

mvn -pl abilities/exam-sprint/infrastructure -am -Dtest=ClasspathAchievementExamSprintReportRendererTest,PlaywrightExamSprintReportPdfGeneratorTest test

Expected: FAIL because the template still shows the old label and existing fixture-derived values still render 1.93%.

Step 3: Write the minimal implementation

  • Change the two achievement-template labels from 真题生词命中率 to 试卷掌握度命中率.
  • Keep placeholder names unchanged.

Step 4: Run tests to verify they pass

Run:

mvn -pl abilities/exam-sprint/infrastructure -am -Dtest=ClasspathAchievementExamSprintReportRendererTest,PlaywrightExamSprintReportPdfGeneratorTest test

Expected: PASS.

Step 5: Do not commit

  • Leave changes uncommitted unless the user explicitly asks for a commit.

Task 3: End-to-end verification of the final achievement report behavior

Files:

  • Verify only: no new files expected

Step 1: Run the combined verification suite

Run:

mvn -pl abilities/exam-sprint/infrastructure,abilities/exam-sprint/application -am -Dtest=AchievementReportContentMapperTest,ExamSprintReportApplicationServiceTest,ClasspathAchievementExamSprintReportRendererTest,PlaywrightExamSprintReportPdfGeneratorTest test

Expected: PASS with zero failures.

Step 2: Inspect the final diff

Run:

git diff -- abilities/exam-sprint/application/src/main/java/cn/yunzhixue/ability/center/examsprint/application/report/AchievementReportContentMapper.java abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/AchievementReportContentMapperTest.java abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportApplicationServiceTest.java abilities/exam-sprint/infrastructure/src/main/resources/templates/achievement-exam-sprint-report-template.html abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/rendering/achievement/ClasspathAchievementExamSprintReportRendererTest.java abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGeneratorTest.java

Expected: Only the derived-metric logic, renamed labels, and directly related test updates appear.

Step 3: Do not commit

  • Stop after reporting verification evidence unless the user explicitly asks for a commit.