# 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
