448 lines
7.8 KiB
Markdown
448 lines
7.8 KiB
Markdown
# 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
|