# Task P.4.3.1 - PDF Runtime Regression Stabilization ## Objective Stabilize the Task P.4.3 section-based PDF runtime refactor before moving to Product Item implementation. This task fixes regression only. Do NOT add new Product Item pages. Do NOT create new template JSON files. Do NOT change database schema. Do NOT change CRM Template UI. Do NOT introduce new user-facing behavior. --- # Background After Task P.4.3, runtime audit still fails. Observed audit result: ```text overallStatus = FAIL staticLabelsStatus = FAIL quotationCode = QT2606-1126 templateName = ALLA Quotation Standard templateVersion = 1.0 ``` Most runtime payloads pass, including: * documentData * quotation data * customer data * item rows * topic inputs * signatures * quotation price data * items_table However static label inputs are missing from `templateInput`. Failing fields: ```text templateInput.tel_label templateInput.email_label templateInput.att_label templateInput.project_label templateInput.site_label ``` Expected values: ```text tel_label = Tel email_label = Email att_label = Att project_label = Project site_label = Location ``` --- # Root Cause Hypothesis The refactored section-based runtime likely preserved business data and dynamic section inputs, but dropped legacy/default static inputs during template input assembly. The missing values still exist in source document data: ```text documentData.pdfme.labels.tel documentData.pdfme.labels.email documentData.pdfme.labels.att documentData.pdfme.labels.project documentData.pdfme.labels.location ``` but they are not merged into final `templateInput`. This indicates a regression in one of: * mapping resolver * static input resolver * render context construction * section composer input merge * template assembler input merge --- # Scope Included: * Restore static label input compatibility * Verify final `templateInput` contains all legacy static inputs * Ensure new runtime preserves all old runtime input keys * Strengthen audit/regression coverage * Confirm ALLA and ONVALLA pass runtime audit Excluded: * Product Item page rendering * Product Item template creation * Template version publishing * Render Policy UI * New section visibility configuration * Database changes * API changes --- # Required Investigation Before fixing, inspect the old and new runtime input construction path. Compare: ## Old Runtime * how `tel_label` * `email_label` * `att_label` * `project_label` * `site_label` were added to `templateInput` ## New Runtime * where `templateInput` is initialized * where mapping output is merged * where section inputs are merged * where static/default inputs are merged or lost Produce a short root-cause note before applying fixes. --- # Implementation Requirements ## 1. Introduce or Restore Static Input Resolution Ensure final `templateInput` always includes legacy static inputs. At minimum: ```ts { tel_label: 'Tel', email_label: 'Email', att_label: 'Att', project_label: 'Project', site_label: 'Location' } ``` Preferred source: ```text documentData.pdfme.labels ``` Fallback source: ```text hardcoded legacy defaults ``` The resolver must not duplicate dynamic mapping logic. --- ## 2. Recommended Component Add or restore a dedicated component: ```text StaticInputResolver ``` Responsibilities: * resolve static labels * resolve legacy fixed inputs * normalize alias fields * provide fallback defaults * return template input patch It should run before final template assembly. Suggested pipeline: ```text Document Data -> Template Resolver -> Mapping Resolver -> Compatibility Adapter -> Page Resolver -> Render Policy Resolver -> Static Input Resolver -> Section Composer -> Template Assembler -> PDF Generator ``` --- ## 3. Preserve Legacy Input Contract The final `templateInput` must preserve all keys expected by legacy templates. Minimum required keys: ```text customer_name customer_addr customer_tel customer_email customer_att project_name site_location quotation_date quotation_date_data quotation_code quotation_code_data quotation_price quotation_price_data currency exclusion_data app1 app1_position app2 app2_position app3 app3_position tel_label email_label att_label project_label site_label topic_* item_topic_* items_table ``` --- ## 4. Template Assembler Merge Rule The assembler must merge template inputs in deterministic order. Recommended order: ```text base mapped input static input patch section input patches diagnostic/debug input patch if any ``` Later patches may override earlier patches only when explicitly intended. No accidental null overwrite is allowed. --- ## 5. Null-safe Merge If a patch contains `null` or `undefined`, it must not overwrite a populated existing value unless explicitly allowed. Example rule: ```text Do not overwrite "Tel" with null. Do not overwrite populated static labels with empty values. ``` --- # Regression Requirements Run audit for at least: ## ALLA * approved quotation fixture * quotation with topics * quotation with items ## ONVALLA * active quotation fixture * quotation with topics * quotation with items Verify: ```text overallStatus = PASS staticLabelsStatus = PASS findingCount = 0 FAIL ``` --- # Verification Matrix ## Runtime Payload Confirm final `templateInput` contains: ```text tel_label = Tel email_label = Email att_label = Att project_label = Project site_label = Location ``` ## Existing Dynamic Inputs Confirm no regression for: ```text quotation_price_data exclusion_data topic_* item_topic_* items_table app1 app1_position app2 app2_position app3 app3_position ``` ## Routes Verify unchanged behavior for: ```text GET /api/crm/quotations/[id]/document-preview GET /api/crm/quotations/[id]/pdf-preview GET /api/crm/quotations/[id]/pdf-download GET /api/crm/quotations/[id]/approved-pdf ``` --- # Testing Requirements Run: ```bash npm exec tsc --noEmit npm run build npm run audit:pdf ``` If project has targeted PDF audit commands, run those as well. --- # Acceptance Criteria * Static label regression is fixed. * `overallStatus = PASS`. * `staticLabelsStatus = PASS`. * No failing runtime audit findings remain. * Legacy templates render as before. * ALLA and ONVALLA remain compatible. * Section-based runtime architecture from P.4.3 remains intact. * No Product Item feature implementation is introduced. * Runtime is safe to proceed to Task P.4.4. --- # Out of Scope The following belongs to later tasks: ## Task P.4.4 * Product Item Engine * Product Item pagination * Product Item page rendering ## Task P.4.5 * New Product Item template versions * New template JSON files * Template seed/reseed support ## Task P.4.6 * CRM Template integration and activation flow ## Task P.4.7 * User-selectable render options * Optional section UI * Organization/customer render preferences --- # Final Success Condition Task P.4.3.1 is complete only when the refactored section-based runtime produces a passing runtime audit with zero legacy input regressions. After this task passes, continue to Task P.4.4. ## Additional Fix - Quotation Date Consistency Runtime audit still fails because `quotation_date` and `quotation_date_data` are inconsistent with the approved snapshot. Investigate the source and formatter for: - templateInput.quotation_date - templateInput.quotation_date_data - approved snapshot quotation date values - documentData.pdfme.quotation_date Ensure both keys are generated from the same canonical source and formatter. Required rule: - `quotation_date` - `quotation_date_data` must always be identical unless a template explicitly maps them differently. Preferred fix: Create or reuse a single canonical PDFMe date formatter and assign both keys from the same value. Do not patch one key independently. Do not change approved artifact retrieval behavior. Do not modify template JSON. Acceptance: - consistency.status = PASS - inconsistentKeys = [] - overallStatus = PASS