# Playwright PDF Generator 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:** Replace the default exam-sprint PDF generator with Playwright Java as the sole supported PDF generation engine.

**Architecture:** Keep `ExamSprintReportPdfGenerator` unchanged. Add a Spring-managed `PlaywrightExamSprintReportPdfGenerator` in the infrastructure PDF package and let application/runtime code continue consuming the domain interface. The first version reuses one Chromium browser and serializes Playwright calls to avoid unsafe concurrent access.

**Tech Stack:** Java 17, Spring Boot 3.3.5, Maven, Playwright Java, Chromium, JUnit 5, AssertJ, PDFBox test utilities.

---

## File Structure

- Modify `abilities/exam-sprint/infrastructure/pom.xml`: add `com.microsoft.playwright:playwright` and keep PDF test utilities explicit.
- Create `abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGenerator.java`: default PDF generator using Playwright Chromium.
- Create `abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGeneratorTest.java`: targeted Playwright generator coverage.
- Modify `abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportWarmupResourceIntegrationTest.java`: exercise Playwright in the existing warmup resource integration path.

## Tasks

### Task 1: Add Playwright Dependency

**Files:**
- Modify: `abilities/exam-sprint/infrastructure/pom.xml`

- [ ] Add this dependency to the infrastructure module:

```xml
<dependency>
    <groupId>com.microsoft.playwright</groupId>
    <artifactId>playwright</artifactId>
    <version>1.58.0</version>
</dependency>
```

- [ ] Run compile for the infrastructure module:

```bash
mvn -pl abilities/exam-sprint/infrastructure -am -DskipTests compile
```

Expected: compile succeeds or fails only because the new Playwright implementation has not been added yet if this task is executed independently.

### Task 2: Implement Playwright PDF Generator

**Files:**
- Create: `abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGenerator.java`

- [ ] Create `PlaywrightExamSprintReportPdfGenerator` with these behaviors:
  - Implements `ExamSprintReportPdfGenerator`.
  - Is annotated with `@Component`.
  - Lazily creates one headless Chromium `Browser` during the first `generate()` call so Spring context startup does not require Chromium to launch.
  - Serializes Playwright calls using a private lock.
  - Creates and closes a fresh `BrowserContext` per PDF.
  - Relies on the runtime Docker image installing MiSans as a system font so Chromium can resolve the report font stack (`'MiSans VF', MiSans, ReportFont, sans-serif`).
  - Waits for `document.fonts.ready` before `page.pdf()`.
  - Uses A4, print media, CSS page size preference, and background printing.
  - Wraps generation failures in `IllegalStateException("Failed to generate PDF", exception)`.
  - Closes browser and Playwright from `destroy()`/`close()`.

### Task 3: Add Playwright Generator Tests

**Files:**
- Create: `abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGeneratorTest.java`

- [ ] Add tests that create one generator for the class and close it after all tests.
- [ ] Verify simple Chinese HTML returns bytes whose first four ISO-8859-1 chars are `%PDF`.
- [ ] Verify inline SVG Chinese text renders without failure.
- [ ] Verify full Outlook and Achievement templates generate readable PDFs with at least one page.

### Task 4: Update Warmup Resource Integration Test

**Files:**
- Modify: `abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportWarmupResourceIntegrationTest.java`

- [ ] Use direct construction of `PlaywrightExamSprintReportPdfGenerator` in the warmup resource integration test.
- [ ] Close the generator at the end of the test using try-with-resources.

### Task 5: Verification

**Files:**
- No source file changes.

- [ ] If Chromium is not installed for Playwright, run this command before PDF tests:

```bash
mvn -pl abilities/exam-sprint/infrastructure exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install chromium"
```

- [ ] Run targeted infrastructure tests:

```bash
mvn -pl abilities/exam-sprint/infrastructure -am -Dtest=PlaywrightExamSprintReportPdfGeneratorTest test
```

- [ ] Run the application warmup resource integration test:

```bash
mvn -pl abilities/exam-sprint/application -am -Dtest=ExamSprintReportWarmupResourceIntegrationTest test
```

- [ ] Run runtime configuration test to ensure the default Spring wiring still accepts a single PDF generator bean:

```bash
mvn -pl ability-center-runtime -am -Dtest=ExamSprintReportRuntimeConfigurationTest test
```

## Self-Review

- Spec coverage: The plan directly implements default Playwright switching and validates both the new generator and warmup resource path.
- Placeholder scan: No task relies on TBD/TODO wording; all files and commands are explicit.
- Type consistency: The plan keeps `ExamSprintReportPdfGenerator.generate(String): byte[]` unchanged and introduces only infrastructure-level Playwright classes.
- Commit policy: No commit step is included because this session has not received an explicit request to create a git commit.
