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

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