# Exam Sprint Outlook Report Adjustments Design

## Goal

Adjust the exam-sprint outlook report so the rendered content follows the new reporting rules for projected strange-word reduction, removes hard-coded personalized hints, removes the `1套/周` planning card, and aligns the past-paper vocabulary chart y-axis ceiling with the total test-paper word count.

## Scope

This change is limited to the outlook report rendering path under `abilities/exam-sprint`:

- payload adaptation in `ClasspathOutlookExamSprintReportRenderer`
- HTML fragment rendering for the past-paper and high-frequency cards
- static study-plan card configuration
- renderer integration tests that lock the new visible output

This change does not alter the request contract, application service flow, PDF generation pipeline, or the overall report template structure unless a minimal layout adjustment is required to keep the existing output stable.

## Recommended Approach

Use the existing template-plus-renderer structure and make the smallest possible behavior changes inside `ClasspathOutlookExamSprintReportRenderer`.

The renderer already owns the output assembly for the affected cards, so the safest approach is to:

1. recalculate the past-paper projected strange-word count during payload adaptation
2. make optional hint paragraphs conditional instead of unconditional
3. shrink the static frequency-plan card set from four cards to three cards
4. derive the past-paper chart axis maximum directly from `testPaperWordCount`

This keeps the report layout stable while changing only the business rules the user requested.

## Business Rules

### Past-paper projected strange-word count

- `unknownWordCountBeforeSprint` continues to come from the incoming past-paper unknown-word count.
- `unknownWordCountAfterSprint` must be recalculated as:

  `round(unknownWordCountBeforeSprint * 0.75)`

- The rendered projected post-sprint strange-word percentage must use the recalculated `unknownWordCountAfterSprint` and the existing `totalWordCount`.
- The percentage display format remains unchanged.

### Removal of hard-coded personalized hints

The following hard-coded hints must no longer appear in the report:

- `先压降真题生词占比。`
- `拉分词是提分核心突破项`

These hints should be removed completely rather than replaced with neutral fallback copy.

### Study-plan frequency cards

The `练习学案频率与提分规划` section must remove the `1套/周` card.

The remaining visible cards should continue to be:

- `2套/周`
- `3套/周`
- `5套/周`

The existing recommendation styling should remain on the current recommended card unless implementation reveals a presentation issue.

### Past-paper chart y-axis rule

The `真题试卷词汇掌握情况` chart y-axis maximum must be aligned directly to `testPaperWordCount`.

- Do not round up to a fixed step such as `250`.
- The axis ceiling should equal the exact total test-paper word count.
- The bar heights should continue to use the existing scaling helper logic, now against the exact total count ceiling.

## Components

### `ClasspathOutlookExamSprintReportRenderer`

#### `adaptPayload(...)`

Update the view-model mapping so that:

- `PastPaperVocabularyChart.unknownWordCountAfterSprint` is computed with `round(before * 0.75)`
- the past-paper recommendation hint is absent
- the high-frequency highlight hint is absent

The implementation should preserve existing DTO usage and avoid changing upstream payload semantics.

#### `renderPastPaperVocabularyChart(...)`

Update rendering so that:

- the chart axis max is derived from `chart.totalWordCount()`
- the rendered `冲刺后生词` count reflects the new rounded value
- the rendered projected percentage reflects the recalculated count
- the recommendation paragraph is only rendered when non-empty

The chart should continue to render as inline SVG and preserve the existing label set and card structure.

#### `renderHighFrequencyVocabularyChart(...)`

Update rendering so that the highlight paragraph is only rendered when non-empty.

No other chart semantics need to change in this task.

#### `staticFrequencyPlan()`

Update the static card list to remove the `1套/周` entry and keep the rest of the recommendation content unchanged unless the reduced card count requires a minimal presentation adjustment.

## Data Flow

1. The renderer deserializes `OutlookExamSprintReportPayload` from the unmodeled report content.
2. `adaptPayload(...)` maps the payload into the internal report view model.
3. During adaptation, the past-paper strange-word projection is recalculated with the new `0.75` multiplier and rounded to the nearest integer.
4. The renderer builds HTML fragments for each report card.
5. Optional hint paragraphs are omitted entirely when their values are blank or absent.
6. The final HTML is injected into `outlook-exam-sprint-report-template.html` and returned for downstream PDF generation.

## Error Handling

The change should preserve the current renderer exception behavior.

- Invalid payloads should still fail through the current deserialization or rendering path.
- Optional hint removal should not introduce null-driven HTML artifacts such as literal `null` output or empty wrapper paragraphs.
- If `testPaperWordCount` is zero, the existing percentage and bar-scaling guards must continue to prevent divide-by-zero or invalid SVG output.

## Testing Strategy

Follow TDD by updating the renderer integration tests first, verifying failure, then implementing the minimal code changes.

### Required test coverage

Update `ClasspathOutlookExamSprintReportRendererTest` to lock the new visible behavior:

- projected strange-word output changes from the old same-count behavior to the new rounded `75%` behavior
- projected percentage is recalculated from the new projected strange-word count
- `先压降真题生词占比。` is absent
- `拉分词是提分核心突破项` is absent
- `1套/周` is absent
- `2套/周` / `3套/周` / `5套/周` remain present
- the past-paper chart axis no longer uses the rounded-up `250` ceiling for the sample payload and instead aligns to the exact test-paper total

### Regression expectations

- Existing SVG font-family assertions should continue to pass.
- Existing PDF-generation smoke coverage should continue to pass if it already depends on the outlook HTML output.
- No tests should rely on removed hint paragraphs being present.

## Acceptance Criteria

- The report shows `冲刺后生词` as `round(冲刺前生词 * 0.75)`.
- The displayed post-sprint strange-word percentage matches the recalculated projected count.
- The two hard-coded personalized hint sentences are not rendered anywhere in the outlook report.
- The `练习学案频率与提分规划` section no longer shows the `1套/周` card.
- The `真题试卷词汇掌握情况` y-axis ceiling matches `TestPaperWordCount` exactly.
- Existing report rendering remains structurally stable outside these requested behavior changes.
