Files
alla-allaos-fullstack/plans/task-p.4.1-verification-report.md
phaichayon 0c0450b152 taks-p.4.3
2026-06-29 11:18:08 +07:00

16 KiB
Raw Permalink Blame History

Task P.4.1 Verification Report

Scope

This report completes the runtime verification requested by task-p.4.1.md.

No production template files were modified. No new rendering pipeline was created. No implementation for Task P.4 has started yet.


1. Verified Runtime Findings

1.1 Current quotation PDF runtime chain

The current quotation document routes do not use separate template pipelines.

Verified route chain:

Verified shared pipeline:

Verified preview builder chain:

  • getQuotationDocumentPreviewData() builds documentData
  • resolves active template and active version
  • resolves version mappings
  • maps documentData to templateInput
  • applies topic page expansion

Reference:

1.2 Same active template/version/mapping pipeline

Confirmed: document-preview, pdf-preview, pdf-download, and approved PDF generation all depend on the same active template/version/mapping pipeline.

Shared resolution calls:

Conclusion:

  • there is one active runtime pipeline for quotation PDF generation
  • there is no separate preview-only template source
  • there is no separate download-only template source
  • approved PDF generation reuses the same active version before persistence

2. Active Template Runtime Source Verification

2.1 Database active versions

Verified against live database:

[
  {
    "organizationName": "ALLA",
    "templateName": "ALLA Quotation Standard",
    "version": "1.0",
    "filePath": "src/pdfme_template/ALLA_template_pdfme_fainal3.json",
    "mappingCount": "20"
  },
  {
    "organizationName": "ONVALLA",
    "templateName": "ONVALLA Quotation Standard",
    "version": "1.0",
    "filePath": "src/pdfme_template/ONVALLA_template_pdfme_fainal3.json",
    "mappingCount": "20"
  }
]

Interpretation:

  • runtime selects active version rows from DB
  • each active version still keeps filePath pointing to the original JSON file source
  • mapping count is currently 20 for both active versions

2.2 DB schema vs file source

Verified that the active version schema_json in DB matches the JSON file on disk exactly for both organizations.

Evidence:

{
  "organization": "ALLA",
  "filePath": "src/pdfme_template/ALLA_template_pdfme_fainal3.json",
  "matches": true
}
{
  "organization": "ONVALLA",
  "filePath": "src/pdfme_template/ONVALLA_template_pdfme_fainal3.json",
  "matches": true
}

Conclusion:

  • runtime renders from schema_json stored in DB
  • the current DB value is seeded from the JSON file and currently matches it
  • changing only the JSON file will not change runtime behavior unless DB version rows are reseeded or updated

2.3 Seed/runtime source conclusion

Runtime uses both, but with different roles:

  • DB active template/version/mapping is the actual runtime source
  • JSON file is the seed/reseed source of truth for version payload creation

This means P.4 must update:

  • new template JSON files
  • seed or reseed logic that publishes those JSON files into DB versions

Relevant current source selectors:


3. Current Template Page Structure

3.1 Active page count

Verified from active DB runtime schema:

  • ALLA active template version has 2 pages
  • ONVALLA active template version has 2 pages

3.2 Schema names per page

Verified runtime schema dump for ALLA:

PAGE 1 FIELDS:
company1, company2, company_addr1, company_addr2, company_tel, company_email,
company_tax, line, customer_name, customer_addr, customer_tel, customer_email,
dear_sirs, quotation_price_data, quotation_date_labe, quotation_date_data,
quotation_code_lable, quotation_code_data, customer_att, project_name,
site_location, colon, colon copy, colon_tel, colon_fax, colon_email,
colon_att, colon_project, colon_site, tel_label, email_label,
att_label, project_label, site_label

PAGE 2 FIELDS:
topic, data_topic, Please_do_not, yours_faithfuly,
app1, app1_position, app2, app2_position, app3, app3_position

Verified runtime schema dump for ONVALLA:

PAGE 1 FIELDS:
company, company_addr1, company_addr2, company_tel, company_email,
company_tax, line, customer_name, customer_addr, customer_tel, customer_email,
dear_sirs, quotation_price_data, quotation_date_labe, quotation_date_data,
quotation_code_lable, quotation_code_data, customer_att, project_name,
site_location, colon, colon copy, colon_tel, colon_fax, colon_email,
colon_att, colon_project, colon_site, tel_label, email_label,
att_label, project_label, site_label

PAGE 2 FIELDS:
topic, data_topic, Please_do_not, yours_faithfuly,
app1, app1_position, app2, app2_position, app3, app3_position

3.3 Topic/signature page index

Confirmed:

  • topic/signature page is currently page index 1 in zero-based runtime terms
  • this matches the hardcoded topic engine default

Reference:

This is the key verification that explains why inserting a new page in the middle will break the current engine if no runtime change is made first.


4. PDFMe Table Capability Verification

4.1 Verification method

Temporary verification was performed using:

  • @pdfme/generator
  • @pdfme/schemas table plugin
  • @pdfme/pdf-lib for page counting

No production template was modified.

A temporary verification PDF was generated at:

4.2 Runtime source-code evidence for repeat header

The installed table plugin contains explicit repeat-header logic:

node_modules/@pdfme/schemas/dist/dynamicTemplate-CXBCt5wk.js:488
schema.showHead = schema.showHead === false ? false : !schema.__isSplit || schema.repeatHead === true;

node_modules/@pdfme/schemas/dist/dynamicTemplate-CXBCt5wk.js:704
if (!(schema.repeatHead && isBlankPdf(args.basePdf) && headerHeight > 0)) return baseHeights;

Interpretation:

  • repeatHead is a real runtime behavior in the installed table plugin
  • repeated header behavior is only applied when using blank/object-style basePdf
  • this matches the P.4 requirement and also matches the projects current template style

4.3 Temporary generation results

Verified generation results:

{"label":"rows_5_short","rowCount":5,"pageCount":1,"pdfBytes":8869}
{"label":"rows_30_short","rowCount":30,"pageCount":2,"pdfBytes":21737}
{"label":"rows_100_short","rowCount":100,"pageCount":4,"pdfBytes":55297}
{"label":"rows_30_long","rowCount":30,"pageCount":3,"pdfBytes":26739}

Verified conclusions:

  • 5 rows fits on 1 page
  • 30 rows breaks to 2 pages
  • 100 rows breaks to 4 pages
  • 30 long-description rows consume 3 pages instead of 2

4.4 Table behavior conclusions

Confirmed:

  • auto page break works
  • multi-page table generation works
  • row height behavior changes pagination when descriptions become longer
  • repeat header is implemented in the installed runtime and tied to repeatHead: true

Important nuance:

  • visual image-based confirmation was not performed because this environment does not have PDF raster/text inspection tools installed
  • however the runtime code path plus successful multi-page generation confirms the feature support exists in the actual installed library

5. Product Item Mapping Verification

5.1 Actual source fields found

Verified live DB columns for crm_quotation_items:

id
organization_id
quotation_id
item_number
product_type
description
quantity
unit
unit_price
discount
discount_type
tax_rate
total_price
notes
sort_order
created_at
updated_at
deleted_at

5.2 Actual document runtime fields exposed

Verified quotation document runtime exposes:

  • itemNumber
  • productTypeCode
  • productTypeLabel
  • description
  • quantity
  • unitCode
  • unitLabel
  • unitPrice
  • discount
  • discountTypeCode
  • taxRate
  • totalPrice
  • notes

Reference:

5.3 Actual mapping coverage for items_table

Verified active mapping rows already include items_table for both organizations.

Current columns:

  • ItemitemNumber
  • Descriptiondescription
  • Qtyquantity
  • UnitunitLabel
  • Unit PriceunitPrice
  • TotaltotalPrice

5.4 Gap analysis against Task P.4.1 required fields

Required field Verified source Status
product code no dedicated field found gap
description description available
specification no dedicated field found gap
quantity quantity available
unit unit / unitLabel available
unit price unitPrice available
discount discount available
amount totalPrice available
remark closest existing field is notes gap / mapping decision needed

Conclusion:

  • product code does not exist as a standalone quotation item field in the current model
  • specification does not exist as a standalone quotation item field in the current model
  • remark likely maps to notes, but this should be treated as a business decision, not assumed silently

6. Final Implementation Strategy

Recommended implementation order:

  1. generalize topic/signature runtime targeting so it no longer depends on hardcoded page index 1
  2. create new template JSON files
    • ALLA_template_pdfme_product_v1.json
    • ONVALLA_template_pdfme_product_v1.json
  3. place the Product Item page between customer detail and topic/signature pages
  4. configure the Product Item page with official PDFMe table schema using:
    • showHead: true
    • repeatHead: true
    • blank/object-style basePdf
  5. keep old versions untouched and inactive/active-switchable
  6. update reseed/audit source selectors so the new JSON files can be published into DB
  7. verify runtime behavior for both old and new versions through the existing routes

Important implementation constraint:

  • because runtime currently renders from DB schema_json, adding only new JSON files is not sufficient
  • reseed or explicit version creation in template admin is required for runtime adoption

7. Rollback Plan

Recommended rollback:

  1. do not delete the current active 1.0 versions
  2. publish the new Product Item design as a separate version only
  3. if regression occurs, deactivate the new version
  4. reactivate the current 1.0 version in /dashboard/crm/settings/templates
  5. if needed, revert reseed script changes independently from runtime code changes

Why rollback is low-risk:

  • versioned template storage already exists
  • runtime resolves active version dynamically
  • current production version remains intact

8. Regression Test Matrix

8.1 Runtime routes

Verify for both ALLA and ONVALLA:

  • GET /api/crm/quotations/[id]/document-data
  • GET /api/crm/quotations/[id]/document-preview
  • GET /api/crm/quotations/[id]/pdf-preview
  • GET /api/crm/quotations/[id]/pdf-download
  • approved PDF generation flow
  • approved PDF retrieval flow after artifact exists

8.2 Template versions

Verify both:

  • old version 1.0
  • new product-item version

8.3 Row-volume cases

Verify with quotation items around:

  • 5 rows
  • 30 rows
  • 100 rows
  • long wrapped descriptions

8.4 Output expectations

Verify:

  • old template still renders exactly as before
  • new template inserts Product Item page between page 1 and topic/signature page
  • topic/signature block still lands on the correct page
  • repeated table header appears when multiple product pages exist
  • long descriptions affect row height without layout corruption
  • preview and download use the same selected version
  • approved PDF persists the expected template version ID

9. Summary

Task P.4.1 verification confirms:

  • quotation PDF runtime uses one shared active template/version/mapping pipeline
  • current active runtime template is still the 2-page *_fainal3.json structure
  • runtime source is DB schema_json, while JSON files remain the seed/reseed source
  • official PDFMe table support is sufficient for multi-page product item tables
  • current quotation item model is missing dedicated product code and specification fields
  • the biggest implementation blocker is still the topic engines hardcoded page targeting, not the table plugin itself