Story 3-1: Create PDF Generation API Route
- Add server/api/resume/pdf.get.ts with Puppeteer integration
- Support both dev (puppeteer) and prod (puppeteer-core + chromium)
- Navigate to /resume?print=true for WYSIWYG capture
- Return PDF with proper headers (Content-Type, Content-Disposition)
- Add error handling with 500 status and JSON response
- Update vercel.json with function config (memory: 1024, maxDuration: 10)
Story 3-2: Create PDF Download Composable
- Add app/composables/useResumePdf.ts
- Implement isGenerating ref for loading state
- Implement downloadPdf() with blob handling
- Add toast notifications for errors
- Revoke object URL to prevent memory leaks
Story 3-3: Connect Download Button to PDF Generation
- Update ResumeDownloadButton.vue to use useResumePdf()
- Bind :loading and :disabled to isGenerating
- Connect @click to downloadPdf
- Remove placeholder handler
Dependencies Added:
- puppeteer ^24.31.0
- puppeteer-core ^24.31.0
- @sparticuz/chromium ^141.0.0
Closes Epic 3
Closes Story 3-1, 3-2, 3-3
- Create app/components/resume/ResumePreview.vue with single-column layout
- Implement A4 container (210mm × 297mm) with 24px margins
- Add all resume sections: Header, Summary, Experience, Education, Additional Info
- Apply blue (#2563eb) and white color scheme with Inter typography
- Add print styles with .no-print class and break-inside-avoid
- Integrate useResumeData() composable for reactive data
- Update pages/resume.vue to use ResumePreview component
Closes Story 2-2