Files
alla-allaos-fullstack/plans/task-h.5.3.md
phaichayon 51d67ef7c2 task-h.5.3
2026-06-19 17:15:28 +07:00

8.8 KiB

Task H.5.3: PDFME Template Version Remap + Static Label Mapping Fix

Goal

รองรับการแก้ไข PDFME template version ใหม่ทั้งหมด หลังจากมีการลบ/เพิ่ม/เปลี่ยน field ใน template

พร้อมแก้ปัญหา static label เช่น:

Tel
Email
Att
Project
Location

ไม่แสดงใน PDF


Background

Current issue:

Template แสดงค่าฝั่งข้อมูล เช่น:

02-000-1000
demo-customer@local.test
Task H.1 Contact
Task H.5 Audit Fixture
Bangkok HQ

แต่ label ฝั่งซ้ายไม่แสดง:

Tel
Email
Att
Project
Location

Cause:

Field label เช่น:

tel_label
email_label
att_label
project_label
site_label

ยังไม่มี runtime input / mapping ที่ตรงกับ template version ใหม่

อีกทั้ง template มีการลบ field แล้ว จึงต้อง remap ใหม่ทั้ง version


Important Rule

Do NOT patch the old template version in-place.

Create a new template version.

Example:

ALLA Quotation Standard v1.0
→
ALLA Quotation Standard v1.1

Approved PDF เดิมต้องยังอ้าง version เดิมได้


Must Read

docs/business/pdf-mapping-registry.md
docs/business/pdf-placeholder-registry.md
docs/adr/0013-pdf-visual-parity-strategy.md
docs/implementation/task-h5-pdf-mapping-audit-visual-parity.md
docs/implementation/task-h51-pdf-integrity-audit.md

src/features/foundation/document-template/**
src/features/foundation/pdf-generator/**
src/features/crm/quotations/document/**
src/db/seeds/foundation.seed.ts
scripts/audit-pdf-template-inventory.ts
scripts/audit-pdf-mapping-coverage.ts
scripts/audit-pdf-runtime-payload.ts
scripts/generate-pdf-integrity-report.ts

Scope H5.3.1 Template Version Ingestion

Add support to ingest/register new PDFME template JSON as a new version.

Required behavior:

  • read latest ALLA / ONVALLA template JSON
  • create new crm_document_template_versions
  • mark new version active
  • deactivate previous active version for same template
  • do not delete old version
  • preserve approved snapshots that reference old version

Rules:

one active version per template
approved snapshots remain immutable

Scope H5.3.2 Full Field Inventory From New Template

For the new template version, scan all schema names.

Classify fields into:

static input field
dynamic topic template
readonly/static visual field
system field
unknown field
deleted field from previous version
new field

Special handling:

Dynamic topic template fields:

topic
data_topic

must not become static mappings.

Runtime generated fields:

topic_*
item_topic_*

must not be stored in DB mapping.


Scope H5.3.3 Full Mapping Rebuild For New Version

For the new template version:

  1. create mappings only for fields that exist in the new template
  2. do not copy orphan mappings from old version
  3. do not map deleted fields
  4. use pdf-placeholder-registry.md and actual field inventory
  5. create missing mappings for valid fields
  6. mark unsupported fields as warning, not silent pass

Mapping categories:

Static Label Fields

tel_label       -> pdfme.labels.tel
email_label     -> pdfme.labels.email
att_label       -> pdfme.labels.att
project_label   -> pdfme.labels.project
site_label      -> pdfme.labels.location

Expected values:

Tel
Email
Att
Project
Location

or Thai labels if configured:

โทร
อีเมล
เรียน
โครงการ
สถานที่

Customer Fields

customer_name   -> customer.name
customer_addr   -> customer.address
customer_tel    -> customer.phone
customer_email  -> customer.email
customer_att    -> quotation.attention

Project / Quotation Fields

project_name       -> quotation.projectName
site_location      -> quotation.projectLocation
quotation_code     -> quotation.code
quotation_code_data -> quotation.code
quotation_date     -> pdfme.quotation_date
quotation_date_data -> pdfme.quotation_date

Price Table

Canonical:

quotation_price_data -> pdfme.quotation_price_data

Keep compatibility if template still has scalar placeholders:

quotation_price -> pdfme.quotation_price
currency        -> pdfme.currency

Exclusion

exclusion_data -> pdfme.exclusion_data

Signature

app1          -> signatures.preparedBy.name
app1_position -> signatures.preparedBy.position
app2          -> signatures.approvedBy.name
app2_position -> signatures.approvedBy.position
app3          -> signatures.authorizedBy.name
app3_position -> signatures.authorizedBy.position

Scope H5.3.4 Runtime Document Data Update

Update:

src/features/crm/quotations/document/server/service.ts

Ensure documentData.pdfme.labels exists:

pdfme: {
  labels: {
    tel: "Tel";
    email: "Email";
    att: "Att";
    project: "Project";
    location: "Location";
  }
}

Optional Thai mode:

pdfme: {
  labels: {
    tel: "โทร";
    email: "อีเมล";
    att: "เรียน";
    project: "โครงการ";
    location: "สถานที่";
  }
}

Rules:

  • never return undefined
  • label values should be controlled by terminology/config later
  • for now default to current PDF language
  • do not hardcode in template only

Scope H5.3.5 Resolver Safety

Update mapping resolver to:

  • resolve nested paths such as pdfme.labels.tel
  • fallback to mapping.defaultValue
  • fallback to "-" if still empty
  • preserve table values as string[][]
  • not stringify table input

Scope H5.3.6 Audit Update

Update audit scripts to support version remap.

Checks:

new version active
old version inactive but retained
deleted fields removed from mapping
new fields mapped or classified
label fields resolved
price table present
dynamic topics still valid
signature fields still valid
approved snapshot parity still pass for newly generated artifact

Special check:

tel_label
email_label
att_label
project_label
site_label

must be non-empty.


Scope H5.3.7 Seed / Migration Strategy

Update:

src/db/seeds/foundation.seed.ts

or create a dedicated script:

scripts/reseed-pdf-template-version.ts

Recommended:

Use dedicated script for remap:

npm run seed:pdf-template-version

because template version remap is operationally different from foundation seed.

Rules:

  • no hardcoded organizationId
  • handles every organization
  • handles ALLA / ONVALLA branch template
  • idempotent per template version
  • no duplicate active versions

Scope H5.3.8 Approved Snapshot Rule

Existing approved artifacts:

  • keep using old template version
  • do not regenerate automatically
  • do not update old snapshot mapping

New approved artifacts:

  • use new active template version
  • use new mappings
  • pass parity audit

Scope H5.3.9 Verification

Run:

npm run seed:pdf-template-version
npm run audit:pdf

Expected:

Overall Status: PASS
Template Version: PASS
Placeholder Integrity: PASS
Payload Parity: PASS
Topic Runtime: PASS
Approved Snapshot Parity: PASS
Price Table: PASS
Static Labels: PASS

Visual check:

Tel      : 02-000-1000
Email    : demo-customer@local.test
Att      : Task H.1 Contact
Project  : Task H.5 Audit Fixture
Location : Bangkok HQ

Scope H5.3.10 Documentation

Update:

docs/business/pdf-mapping-registry.md
docs/business/pdf-placeholder-registry.md
docs/implementation/task-h5-pdf-mapping-audit-visual-parity.md
docs/implementation/technical-debt.md

Add:

Template version remap process
Static label mapping strategy
Deleted field handling
Dynamic topic reserved fields
Approved snapshot immutability rule

Explicit Non-Scope

Do NOT implement:

visual template designer
signature image / draw signature
digital signature
currency exchange calculation
report center
permission center

Output

After completion, summarize:

  1. Files Added
  2. Files Modified
  3. New Template Version Created
  4. Deleted Fields Detected
  5. New Field Inventory
  6. Mappings Rebuilt
  7. Static Labels Fixed
  8. Audit Result
  9. Remaining Risks

Definition of Done

Task H.5.3 passes when:

  • new template version is created
  • old template version is retained
  • old mappings are not blindly copied
  • deleted fields do not remain as active mappings
  • new fields are mapped or classified
  • tel_label renders
  • email_label renders
  • att_label renders
  • project_label renders
  • site_label renders
  • price table still renders
  • dynamic topics still render
  • signatures still render
  • approved snapshot parity passes for newly generated approved PDF
  • npm run audit:pdf returns Overall Status PASS