Files
alla-allaos-fullstack/plans/task-h.2.1.md
2026-06-18 08:58:01 +07:00

6.8 KiB

Task H.2.1: Reseed PDFME Template Mappings for Dynamic Topic Engine

Goal

ปรับ seed data ของ PDFME template mappings ให้สอดคล้องกับ Task H.2

หลัง H.2 ระบบใช้ Dynamic Topic Engine แล้ว ดังนั้น topic, data_topic, และ dynamic topic input keys ไม่ควรถูกจัดการผ่าน crm_document_template_mappings แบบ static อีกต่อไป


Background

Task H.2 เพิ่ม:

  • PDFME transform utilities
  • Dynamic Topic Engine
  • Product topic mapping
  • pdfme section ใน quotation document data
  • runtime topic inputs
  • server-side schema cloning สำหรับ topic และ data_topic

ดังนั้น seed mappings ต้องถูก cleanup ให้ตรงกับ model ใหม่


Must Read

docs/implementation/task-h2-pdfme-mapping-transform-hotfix.md
docs/implementation/pdfme-runtime-audit.md
docs/implementation/pdfme-legacy-audit.md

src/db/seeds/foundation.seed.ts
src/features/foundation/document-template/**
src/features/crm/quotations/document/server/**
src/pdfme_template/**

Scope H2.1.1: Inspect Current Template Placeholders

Extract placeholders from current default templates:

src/pdfme_template/ALLA_template_pdfme_fainal3.json
src/pdfme_template/ONVALLA_template_pdfme_fainal3.json

Expected static placeholders:

customer_name
customer_addr
customer_tel
customer_email
customer_att
project_name
site_location
quotation_date
quotation_code
quotation_price
currency
exclusion_data

Dynamic topic template schemas:

topic
data_topic

Signature placeholders, if present:

app1
app1_position
app2
app2_position
app3
app3_position

Scope H2.1.2: Static Mapping Seed

Update foundation.seed.ts so default pdfme mapping contains only static runtime placeholders:

customer_name        -> customer.name
customer_addr        -> customer.address
customer_tel         -> customer.phone
customer_email       -> customer.email
customer_att         -> quotation.attention
project_name         -> quotation.projectName
site_location        -> quotation.projectLocation
quotation_date       -> pdfme.quotation_date
quotation_code       -> quotation.code
quotation_price      -> pdfme.quotation_price
currency             -> quotation.currency
exclusion_data       -> pdfme.exclusion_data

Recommended metadata:

quotation_date:
  dataType = scalar
  formatMask = null
  sourcePath = pdfme.quotation_date

quotation_price:
  dataType = scalar
  formatMask = null
  sourcePath = pdfme.quotation_price

exclusion_data:
  dataType = table
  sourcePath = pdfme.exclusion_data

Reason:

  • date/currency are already formatted in pdfme section from H.2
  • do not format twice in mapping resolver

Scope H2.1.3: Retire Invalid Static Topic Mappings

Ensure seed removes or deactivates mappings for:

topic
data_topic
item_topic
data_topic_*
topic_*
item_topic_*

Rules:

  • topic and data_topic are schema templates, not data placeholders
  • item_topic is legacy content placeholder inside data_topic, not a DB mapping
  • dynamic keys such as topic_1_0 and item_topic_1_0 are generated at runtime
  • do not store generated dynamic keys in DB

Implementation guidance:

If mappings exist from old seed:

soft delete / delete / skip

according to current template mapping service convention.


Scope H2.1.4: Signature Mapping Decision

If current template contains signature placeholders:

app1
app1_position
app2
app2_position
app3
app3_position

For this task:

Option A recommended:

Seed them with safe placeholder values:

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

But only if documentData.signatures exists.

If not available yet:

  • do not break PDF
  • use defaultValue = "-"
  • document as pending Task H.3

Rules:

  • no approval signature business logic in this task
  • no new approval mapping strategy in this task

Scope H2.1.5: Seed Idempotency

Seed must be idempotent:

  • run repeatedly without duplicate mappings
  • update existing wrong sourcePath
  • update existing wrong dataType
  • remove/retire invalid mappings
  • no hardcoded organizationId
  • apply for every organization
  • apply for both ALLA and ONVALLA templates if seeded

Scope H2.1.6: Runtime Verification

Extend or run audit script:

scripts/audit-pdfme-runtime.ts

Expected result:

Static template placeholders:

customer_name        mappingExists = true
customer_addr        mappingExists = true
customer_tel         mappingExists = true
customer_email       mappingExists = true
customer_att         mappingExists = true
project_name         mappingExists = true
site_location        mappingExists = true
quotation_date       mappingExists = true
quotation_code       mappingExists = true
quotation_price      mappingExists = true
currency             mappingExists = true
exclusion_data       mappingExists = true

Dynamic schemas:

topic                mappingExists = false, dynamicTemplate = true
data_topic           mappingExists = false, dynamicTemplate = true
item_topic           mappingExists = false, legacyContentToken = true

PDFME input should contain runtime keys:

topic_*
item_topic_*

but these must come from Dynamic Topic Engine, not DB mappings.


Scope H2.1.7: Documentation

Update:

docs/implementation/task-h2-pdfme-mapping-transform-hotfix.md

Add section:

Seed Mapping Strategy After Dynamic Topic Engine

Also update:

docs/implementation/technical-debt.md

Add note:

Signature placeholders app1/app2/app3 still need Task H.3 strategy if not fully mapped.

Explicit Non-Scope

Do NOT implement:

Approval signature strategy
Visual template designer
Dynamic topic editor
Changing PDF layout
Pixel-perfect comparison
Report Center
Dashboard changes

Output

After completion, summarize:

  1. Files Modified
  2. Static Mappings Seeded
  3. Invalid Topic Mappings Retired
  4. Signature Placeholder Handling
  5. Runtime Audit Result
  6. Remaining Risks
  7. Task H.3 Readiness

Definition of Done

Task H.2.1 passes when:

  • static PDFME mappings are complete
  • exclusion_data maps to pdfme.exclusion_data
  • quotation_price maps to pdfme.quotation_price
  • quotation_date maps to pdfme.quotation_date
  • topic is not mapped as static DB mapping
  • data_topic is not mapped as static DB mapping
  • item_topic is not mapped as static DB mapping
  • dynamic topic keys are generated at runtime only
  • seed is idempotent
  • runtime audit recognizes topic/data_topic as dynamic templates