task-p.4.4

This commit is contained in:
phaichayon
2026-06-29 14:47:24 +07:00
parent 39bcfe2817
commit aa73b9aed2
11 changed files with 1143 additions and 45 deletions

388
plans/task-p.4.4.md Normal file
View File

@@ -0,0 +1,388 @@
# Task P.4.4 - Product Item Engine
## Objective
Implement the Product Item Engine for the new section-based PDF runtime.
The Product Item Engine is responsible only for transforming quotation items into a PDFMe-compatible table model.
This task does **not** create or modify PDF templates.
This task does **not** insert Product Item pages.
This task prepares the runtime for Task P.4.5.
---
# Prerequisites
Completed
* P.4 Discovery
* P.4.1 Runtime Verification
* P.4.2 Runtime Architecture Design
* P.4.3 Runtime Refactoring
* P.4.3.1 Runtime Regression Stabilization
Runtime audit must already pass before implementation begins.
---
# Scope
Included
* Product Item Engine
* Product Item Builder
* Product Item Mapping
* PDFMe Table Model
* Pagination Model
* Runtime Contracts
* Unit Tests
Excluded
* PDF template JSON
* CRM Template UI
* Template Version
* Page insertion
* Product Item page rendering
* User render options
---
# Architecture
The runtime shall use the existing section-based architecture.
```text
Quotation Document
Render Context
Section Composer
Product Item Engine
BuiltSection
Template Assembler
```
The engine must be completely isolated from
* Topic Engine
* Signature Resolver
* Customer Section
---
# Responsibilities
The Product Item Engine shall
* read quotation items
* normalize data
* format values
* build PDFMe table rows
* calculate row metadata
* estimate pagination
* return a BuiltSection
The engine must not know
* page indexes
* template layouts
* template JSON
* page insertion
* section ordering
---
# Input
Primary source
```text
documentData.items
```
The engine shall not query the database.
It receives all data from RenderContext.
---
# Output
Return
```ts
interface ProductItemSection extends BuiltSection {
role: SectionRole.ProductItems;
rows: ProductItemRow[];
pagination: PaginationModel;
tableModel: PdfmeTableModel;
}
```
The output must be renderer-independent.
---
# Product Item Mapping
Support at minimum
| Column | Source |
| ----------- | ----------- |
| Item | itemNumber |
| Description | description |
| Qty | quantity |
| Unit | unitLabel |
| Unit Price | unitPrice |
| Discount | discount |
| Total | totalPrice |
If additional fields exist they should be supported when available.
Examples
* productCode
* specification
* remark
* model
* brand
Missing optional fields must not fail rendering.
---
# Value Formatting
Use centralized formatters.
Never format inside templates.
Support
* currency
* decimal quantity
* percentage
* empty value normalization
Formatting must remain locale-aware.
---
# PDFMe Table Model
Generate a canonical table model independent of template layout.
Example
```ts
interface PdfmeTableModel {
headers;
rows;
columnWidths;
alignments;
}
```
The template consumes this model later.
The engine must not know where the table is rendered.
---
# Pagination Model
Implement pagination metadata.
The engine shall estimate
* row count
* page count
* header repetition
* orphan row prevention
* available content height
Do not insert pages.
Return only metadata.
Example
```ts
interface PaginationModel {
estimatedPages;
rowsPerPage;
headerRows;
footerRows;
}
```
---
# Empty State
When quotation has zero items
Return an empty Product Item section.
Do not throw an exception.
Runtime decides whether the section is rendered.
---
# Error Handling
Generate Runtime Issues for
* invalid quantity
* invalid price
* missing mandatory description
* invalid totals
Do not stop rendering because of one invalid row.
---
# Product Item Builder
Create a dedicated builder.
Responsibilities
* invoke Product Item Engine
* produce BuiltSection
* register itself in Section Registry
The builder must not manipulate templates.
---
# Unit Tests
Cover
* 0 items
* 1 item
* 10 items
* 100 items
* long descriptions
* missing optional fields
* currency formatting
* decimal quantities
* zero discount
* non-zero discount
---
# Integration Tests
Verify
* Section Composer accepts Product Item Builder
* BuiltSection returned correctly
* Runtime diagnostics preserved
* Existing sections unaffected
No template rendering yet.
---
# Performance Requirements
Support
* 500 quotation items
without significant performance degradation.
Avoid unnecessary cloning.
Avoid repeated formatting.
---
# Code Quality
* Single Responsibility Principle
* Strong typing
* Immutable outputs
* No duplicated mapping logic
* Shared formatter usage
* Shared runtime contracts
* Builder registration through Section Registry
---
# Deliverables
* Product Item Engine
* Product Item Builder
* Product Item Mapping
* PDFMe Table Model
* Pagination Model
* Runtime diagnostics
* Unit tests
* Integration tests
---
# Acceptance Criteria
* Product Item Engine is independent from template layout.
* Engine produces canonical PDFMe table model.
* Engine does not manipulate templates.
* Engine does not insert pages.
* Engine returns pagination metadata only.
* Existing runtime regression tests remain PASS.
* Runtime audit continues to pass.
* Product Item Engine is ready for Task P.4.5.
---
# Out of Scope
## Task P.4.5
* New PDF template
* Product Item page
* PDFMe table rendering
* Page insertion
* Header repetition in rendered PDF
## Task P.4.6
* CRM Template integration
* Template version management
* Preview integration
## Task P.4.7
* Render Policy UI
* Optional section configuration
* User-selectable Product Item visibility
---
# Final Success Condition
At the end of Task P.4.4, the runtime is capable of producing a fully normalized Product Item section and PDFMe table model, ready to be rendered by a future template, while the existing PDF output remains unchanged.