# 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