Context
Surfaced by the fallow pass in batch #400 (PR #421), deferred as non-blocking (reviewer-verified safe to defer).
src/lib/pdf/render-ats-pdf.ts and src/lib/pdf/render-audit-report.ts share a ~104-line clone family (page setup, pdf-lib font/layout scaffolding). They were left un-DRY on purpose in #343: the two renderers have genuinely diverged needs — the résumé PDF uses Poppins and a résumé layout, the audit report uses Helvetica and a report layout — so extracting a shared helper now would over-couple them.
Scope
Revisit once a third consumer or a concrete shared-layout need appears. Extract only the parts that are genuinely identical (e.g. a withPdfDoc / lazy-pdf-lib bootstrap + a page-cursor helper), leaving font/layout choices per-renderer. Do not force a shared template that both have to bend around.
Acceptance
Refs #400, #343.
Lower priority than the other two #400 follow-ups — only act when a third consumer lands or the duplication actually causes a bug.
Context
Surfaced by the fallow pass in batch #400 (PR #421), deferred as non-blocking (reviewer-verified safe to defer).
src/lib/pdf/render-ats-pdf.tsandsrc/lib/pdf/render-audit-report.tsshare a ~104-line clone family (page setup, pdf-lib font/layout scaffolding). They were left un-DRY on purpose in #343: the two renderers have genuinely diverged needs — the résumé PDF uses Poppins and a résumé layout, the audit report uses Helvetica and a report layout — so extracting a shared helper now would over-couple them.Scope
Revisit once a third consumer or a concrete shared-layout need appears. Extract only the parts that are genuinely identical (e.g. a
withPdfDoc/ lazy-pdf-lib bootstrap + a page-cursor helper), leaving font/layout choices per-renderer. Do not force a shared template that both have to bend around.Acceptance
Refs #400, #343.