task-h.5.3

This commit is contained in:
phaichayon
2026-06-19 17:15:28 +07:00
parent fd01ebf7c7
commit 51d67ef7c2
35 changed files with 4301 additions and 633 deletions

View File

@@ -1,16 +1,198 @@
{
"generatedAt": "2026-06-19T07:44:58.283Z",
"overallStatus": "WARNING",
"generatedAt": "2026-06-19T10:12:54.188Z",
"overallStatus": "PASS",
"quotationCode": "QT-H5-AUDIT",
"expectedFixtureCode": "QT-H5-AUDIT",
"template": {
"templateName": "ALLA Quotation Standard",
"version": "1.0",
"versionId": "4ac3e91c-8320-4f41-81cd-5068cc9b5768",
"fieldCount": 46,
"version": "1.1",
"versionId": "bd6713d5-a731-482f-a5bb-0dea9d766301",
"fieldCount": 44,
"previousVersion": "1.0",
"deletedFields": [
"exclusion_data",
"exclusion_label"
],
"newFields": [],
"duplicateFields": [],
"unknownFields": [
"line"
"unknownFields": [],
"classifications": [
{
"name": "company1",
"classification": "system field"
},
{
"name": "company2",
"classification": "system field"
},
{
"name": "company_addr1",
"classification": "system field"
},
{
"name": "company_addr2",
"classification": "system field"
},
{
"name": "company_tel",
"classification": "system field"
},
{
"name": "company_email",
"classification": "system field"
},
{
"name": "company_tax",
"classification": "system field"
},
{
"name": "line",
"classification": "readonly/static visual field"
},
{
"name": "customer_name",
"classification": "static input field"
},
{
"name": "customer_addr",
"classification": "static input field"
},
{
"name": "customer_tel",
"classification": "static input field"
},
{
"name": "customer_email",
"classification": "static input field"
},
{
"name": "dear_sirs",
"classification": "readonly/static visual field"
},
{
"name": "quotation_price_data",
"classification": "static input field"
},
{
"name": "quotation_date_labe",
"classification": "readonly/static visual field"
},
{
"name": "quotation_date_data",
"classification": "static input field"
},
{
"name": "quotation_code_lable",
"classification": "readonly/static visual field"
},
{
"name": "quotation_code_data",
"classification": "static input field"
},
{
"name": "customer_att",
"classification": "static input field"
},
{
"name": "project_name",
"classification": "static input field"
},
{
"name": "site_location",
"classification": "static input field"
},
{
"name": "colon",
"classification": "readonly/static visual field"
},
{
"name": "colon copy",
"classification": "readonly/static visual field"
},
{
"name": "colon_tel",
"classification": "readonly/static visual field"
},
{
"name": "colon_fax",
"classification": "readonly/static visual field"
},
{
"name": "colon_email",
"classification": "readonly/static visual field"
},
{
"name": "colon_att",
"classification": "readonly/static visual field"
},
{
"name": "colon_project",
"classification": "readonly/static visual field"
},
{
"name": "colon_site",
"classification": "readonly/static visual field"
},
{
"name": "tel_label",
"classification": "static input field"
},
{
"name": "email_label",
"classification": "static input field"
},
{
"name": "att_label",
"classification": "static input field"
},
{
"name": "project_label",
"classification": "static input field"
},
{
"name": "site_label",
"classification": "static input field"
},
{
"name": "topic",
"classification": "dynamic topic template"
},
{
"name": "data_topic",
"classification": "dynamic topic template"
},
{
"name": "Please_do_not",
"classification": "system field"
},
{
"name": "yours_faithfuly",
"classification": "system field"
},
{
"name": "app1",
"classification": "static input field"
},
{
"name": "app1_position",
"classification": "static input field"
},
{
"name": "app2",
"classification": "static input field"
},
{
"name": "app2_position",
"classification": "static input field"
},
{
"name": "app3",
"classification": "static input field"
},
{
"name": "app3_position",
"classification": "static input field"
}
]
},
"metrics": {
@@ -19,47 +201,27 @@
"partyCount": 3,
"dynamicTopicFieldCount": 5,
"dynamicTopicItemFieldCount": 5,
"mappingCount": 19
"mappingCount": 23
},
"mappingCoverage": {
"placeholderTokenCount": 13,
"placeholderTokenCount": 12,
"unmappedTokens": [],
"orphanMappings": [],
"itemTableColumns": [
{
"columnName": "Item",
"sourceField": "itemNumber"
},
{
"columnName": "Description",
"sourceField": "description"
},
{
"columnName": "Qty",
"sourceField": "quantity"
},
{
"columnName": "Unit",
"sourceField": "unitLabel"
},
{
"columnName": "Unit Price",
"sourceField": "unitPrice"
},
{
"columnName": "Total",
"sourceField": "totalPrice"
}
]
"priceTableMapping": {
"sourcePath": "pdfme.quotation_price_data",
"dataType": "table"
},
"itemTableColumns": []
},
"runtimePayload": {
"templateInputKeys": 31,
"topicInputKeys": 10
"templateInputKeys": 35,
"topicInputKeys": 10,
"priceTableRows": 1
},
"consistency": {
"status": "WARNING",
"approvedSnapshotAvailable": false,
"approvedArtifactReference": null,
"status": "PASS",
"approvedSnapshotAvailable": true,
"approvedArtifactReference": "artifact:a1fd951d-f0b4-4e5b-be88-073596b3829d",
"inconsistentKeys": []
},
"integritySummary": {

View File

@@ -1,27 +1,28 @@
# PDF Audit Report
- Generated At: 2026-06-19T07:44:58.283Z
- Overall Status: WARNING
- Generated At: 2026-06-19T10:12:54.188Z
- Overall Status: PASS
- Quotation Code: QT-H5-AUDIT
- Template: ALLA Quotation Standard v1.0
- Template: ALLA Quotation Standard v1.1
- Previous Version: 1.0
## Metrics
- Topic Count: 5
- Item Count: 3
- Project Party Count: 3
- Mapping Count: 19
- Mapping Count: 23
## Mapping Coverage
- Placeholder Tokens: 13
- Placeholder Tokens: 12
- Unmapped Tokens: None
- Orphan Mappings: None
## Visual / Consistency
- Approved Snapshot Available: No
- Consistency Status: WARNING
- Approved Snapshot Available: Yes
- Consistency Status: PASS
- Inconsistent Keys: None
## Integrity Layer

View File

@@ -34,3 +34,9 @@
- approved snapshot parity remains a warning when the target quotation has never generated an approved PDF artifact
- the audit suite validates business payload parity, not pixel-perfect PDF screenshots
- manual review is still needed when template designers move static labels or brand blocks
## H.5.3 Follow-up
- template JSON revisions now flow through a dedicated version-remap step instead of patching `1.0` in place
- static labels such as `tel_label`, `email_label`, `att_label`, `project_label`, and `site_label` are now runtime-mapped rather than tolerated as blank designer placeholders
- deleted fields from the previous version, notably `exclusion_data` and `exclusion_label`, are explicitly classified and removed from the active mapping set

View File

@@ -38,3 +38,14 @@
- stored approved snapshot parity still depends on generating a real approved PDF artifact for `QT-H5-AUDIT`
- template field `line` is still treated as a tolerated designer-owned oddity rather than a normalized mapping field
- the audit stack validates payload integrity and runtime parity, not screenshot-level pixel parity
## Follow-on Freeze Note
- `quotation_price_data` is now treated as the canonical PDFME table field for quotation price rendering
- `quotation_price` and `currency` remain supported only as scalar compatibility fields
## H.5.3 Versioning Note
- integrity checks now accept retained inactive template versions as valid historical references for approved snapshots
- the active-version audit also verifies that the active DB schema matches the latest JSON source file for each organization template
- runtime payload integrity now includes explicit static-label checks so blank `tel_label`/`email_label`/`att_label`/`project_label`/`site_label` values fail the suite

View File

@@ -0,0 +1,33 @@
# Task H.5.3: PDF Template Version Remap + Static Labels
## Outcome
- created active `1.1` quotation PDF template versions for both `ALLA` and `ONVALLA`
- retained historical `1.0` versions as inactive records
- rebuilt active mappings from the current template inventory instead of copying the old version wholesale
- restored runtime values for `tel_label`, `email_label`, `att_label`, `project_label`, and `site_label`
## Field Inventory Result
- deleted from previous version: `exclusion_data`, `exclusion_label`
- new active templates keep dynamic topic bases `topic` and `data_topic`
- designer-owned static visuals such as `line`, `quotation_date_labe`, and `quotation_code_lable` remain classified but unmapped
- compatibility tokens `quotation_price` and `currency` remain mapped because the active price table still embeds those placeholders
## Seed / Remap Flow
- `npm run seed:pdf-template-version` reads the latest JSON from `src/pdfme_template/*.json`
- if the schema already exists in DB, it re-activates and reconciles mappings idempotently
- if the schema is new, it creates the next minor version, activates it, and deactivates the previous active version
- mappings are rebuilt only for fields or tokens still present in that target version
## Verification
- `npx tsc --noEmit` passed
- `npm run seed:pdf-template-version` passed
- `npm run audit:pdf` passed with overall status `PASS`
## Remaining Risks
- active templates still rely on compatibility tokens `quotation_price` and `currency` inside the table content; those should be removed only in a future controlled template revision
- the audit fixture now points to active `1.1`; production-approved historical quotations still need operator discipline so their stored template version is never rewritten manually

View File

@@ -207,13 +207,28 @@ Current:
- payment, warranty, delivery, and extra topic sections now flow through the dynamic `topic` / `data_topic` engine on page 2 instead of fixed placeholder fields
- approval signature placeholders now resolve through the H.3 signature strategy and `crm_job_title` position lookup
- `quotation_price_data` is now the canonical runtime table input for the price row, while active template JSON still embeds nested `{quotation_price}` and `{currency}` cells inside that table field
Future:
- keep validating pagination and closing-block placement against production designer expectations for large topic sets
- add fixture-backed end-to-end PDF generation verification in CI once a stable runtime path is available
- remove nested price-table placeholders in a controlled template revision once design change windows allow it
- decide whether static template field `line` should remain a tolerated designer-only artifact or be normalized in future audits
### Template version remap operations
Current:
- template version remap is now handled by `npm run seed:pdf-template-version`, not by the base foundation seed
- active `1.1` mappings intentionally preserve historical `1.0` versions for snapshot integrity
Future:
- decide whether template version promotion needs an operator-facing review/approve workflow
- add artifacting or changelog snapshots for template-schema diffs before activation
- decide whether the remap command should write a persistent audit history table instead of JSON-only artifacts
## After Task I
### Storage provider production rollout