338 lines
6.8 KiB
Markdown
338 lines
6.8 KiB
Markdown
# 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
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
src/pdfme_template/ALLA_template_pdfme_fainal3.json
|
|
src/pdfme_template/ONVALLA_template_pdfme_fainal3.json
|
|
```
|
|
|
|
Expected static placeholders:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
topic
|
|
data_topic
|
|
```
|
|
|
|
Signature placeholders, if present:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
soft delete / delete / skip
|
|
```
|
|
|
|
according to current template mapping service convention.
|
|
|
|
---
|
|
|
|
# Scope H2.1.4: Signature Mapping Decision
|
|
|
|
If current template contains signature placeholders:
|
|
|
|
```txt
|
|
app1
|
|
app1_position
|
|
app2
|
|
app2_position
|
|
app3
|
|
app3_position
|
|
```
|
|
|
|
For this task:
|
|
|
|
Option A recommended:
|
|
|
|
Seed them with safe placeholder values:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
scripts/audit-pdfme-runtime.ts
|
|
```
|
|
|
|
Expected result:
|
|
|
|
Static template placeholders:
|
|
|
|
```txt
|
|
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:
|
|
|
|
```txt
|
|
topic mappingExists = false, dynamicTemplate = true
|
|
data_topic mappingExists = false, dynamicTemplate = true
|
|
item_topic mappingExists = false, legacyContentToken = true
|
|
```
|
|
|
|
PDFME input should contain runtime keys:
|
|
|
|
```txt
|
|
topic_*
|
|
item_topic_*
|
|
```
|
|
|
|
but these must come from Dynamic Topic Engine, not DB mappings.
|
|
|
|
---
|
|
|
|
# Scope H2.1.7: Documentation
|
|
|
|
Update:
|
|
|
|
```txt
|
|
docs/implementation/task-h2-pdfme-mapping-transform-hotfix.md
|
|
```
|
|
|
|
Add section:
|
|
|
|
```txt
|
|
Seed Mapping Strategy After Dynamic Topic Engine
|
|
```
|
|
|
|
Also update:
|
|
|
|
```txt
|
|
docs/implementation/technical-debt.md
|
|
```
|
|
|
|
Add note:
|
|
|
|
```txt
|
|
Signature placeholders app1/app2/app3 still need Task H.3 strategy if not fully mapped.
|
|
```
|
|
|
|
---
|
|
|
|
# Explicit Non-Scope
|
|
|
|
Do NOT implement:
|
|
|
|
```txt
|
|
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
|