# Task H.2: PDFME Dynamic Topic Engine + Mapping Hotfix ## Files Added - `src/features/crm/quotations/document/server/pdfme-transforms.ts` - `src/features/crm/quotations/document/server/pdf-topic.type.ts` - `src/features/crm/quotations/document/server/pdf-topic-engine.ts` - `src/features/crm/quotations/document/server/topic-mapping.ts` - `docs/implementation/task-h2-pdfme-mapping-transform-hotfix.md` ## Files Modified - `src/features/crm/quotations/document/server/service.ts` - `src/features/crm/quotations/document/types.ts` - `src/features/crm/quotations/components/quotation-document-preview.tsx` - `src/features/foundation/document-template/server/service.ts` - `src/db/seeds/foundation.seed.ts` - `scripts/verify-task-h1.js` - `scripts/audit-pdfme-runtime.ts` - `docs/implementation/technical-debt.md` ## Transform Utilities Added - `formatPdfDate()` - `formatPdfCurrency()` - `formatTopicItems()` - `normalizePdfmeTable()` ## Dynamic Topic Engine Added - page-2 `topic` and `data_topic` schemas are now treated as dynamic templates instead of static mappings - topic blocks are cloned into runtime keys like `topic_1_0` and `item_topic_1_0` - topic rows are normalized into `string[][]` - the closing/signature block is kept together and pushed to the next page when remaining space is too small - long topic lists can expand page 2 into multiple generated pages ## Product Topic Mapping Added - product-type-aware topic mapping with `crane`, `dockdoor`, `solarcell`, and `default` fallbacks - alias matching allows current simplified option codes and legacy-style topic codes to resolve into PDFME-ready sections ## Template Mappings Fixed - `customer_att -> quotation.attention` - `quotation_date -> pdfme.quotation_date` - `quotation_price -> pdfme.quotation_price` - `exclusion_data -> pdfme.exclusion_data` - legacy `item_topic` mapping is now explicitly retired from foundation seed data because dynamic topics are schema-driven ## Seed Mapping Strategy After Dynamic Topic Engine - default PDFME seed mappings now keep only static runtime fields plus safe signature placeholders - `quotation_date` and `quotation_price` are seeded against the preformatted `pdfme.*` fields with no extra format mask - `topic`, `data_topic`, `item_topic`, and wildcard runtime keys such as `topic_*` / `item_topic_*` are retired from DB mappings - signature placeholders `app1/app2/app3` and position fields are seeded with safe `defaultValue: "-"` until Task H.3 defines the real approval-signature strategy ## PDF Generator Integration - quotation preview data now returns a render-ready PDFME schema with injected topic pages - `templateInput` now merges dynamic topic inputs with normal mapped fields - approved snapshot generation now captures the same merged topic input set used by PDF generation - the existing PDF generator flow now consumes the render-ready schema returned by the preview service ## Verification Result - `npx tsc --noEmit` passed - `scripts/verify-task-h1.js` now asserts: - formatted `quotation_price` - formatted `quotation_date` - non-empty `exclusion_data` - generated dynamic topic keys in preview payload - `documentData.pdfme.topic_inputs` - no unresolved `{exclusion_data}`, `{quotation_price}`, and `{item_topic}` in approved PDF text - inline `tsx` smoke testing for the new engine was inconclusive because the local script loader exposed the module as a default-only object even though project typecheck succeeded - full `verify:task-h1` end-to-end execution was not run in this turn because it depends on a live app server and fixture database state ## Remaining PDFME Gaps - approval signature placeholders are still not mapped to real approver names/positions - pixel-perfect parity with the legacy layout has not been regression-tested automatically - `scripts/audit-pdfme-runtime.ts` still needs a stable standalone runtime strategy if we want to use it outside the Next.js execution context ## Task K Readiness - dynamic server-side topic rendering now exists, so follow-on PDF tasks can build on runtime schema generation instead of adding more fixed placeholders - seed data and template mapping are aligned with the current ALLA / ONVALLA templates - the next safe step is end-to-end fixture verification against a running app plus any remaining signature-field strategy