# PDF Parity Checklist ## Header | Area | Expectation | Status | | --- | --- | --- | | Company block | Static company branding and contact text render from template | Partial | | Customer block | `customer_name`, `customer_addr`, `customer_tel`, `customer_email`, `customer_att` render from mapping registry | Match | | Document references | `quotation_code`, `quotation_date`, `project_name`, `site_location` render from live quotation data | Match | ## Commercial Body | Area | Expectation | Status | | --- | --- | --- | | Items | `items_table` columns stay aligned with quotation item rows and totals | Match | | Topics | Dynamic topic engine expands `topic_*` / `item_topic_*` in order | Match | | Exclusion block | `exclusion_data` renders as `string[][]` table payload | Match | | Price summary | `quotation_price` and `currency` use formatted runtime values | Match | ## Approval / Footer | Area | Expectation | Status | | --- | --- | --- | | Signatures | `app1/app2/app3` map to prepared/approved/authorized blocks | Match | | Signature placement | Closing block stays together after dynamic topic pagination | Partial | | Footer copy | Static footer text and closing statement remain template-owned | Match | ## Visual Parity Rules - `Match` means the current PDF runtime has a verified mapping path and auditable payload. - `Partial` means the business data path is correct but final pixel-perfect comparison still needs manual screenshot review against the legacy CRM PDF. - `Missing` should only be used when a field or section has no runtime path. ## Integrity Freeze - `npm run audit:pdf` is the integrity gate for template, placeholder, payload, topic runtime, and snapshot parity. - `QT-H5-AUDIT` is the preferred fixture for repeatable PDF audits.