Files
alla-allaos-fullstack/plans/task-h.1.md
2026-06-16 14:25:26 +07:00

5.4 KiB

Task H.1: PDF Generation Stabilization

Goal

Stabilize Task H PDF generation before starting Task I.

Task H already added:

  • pdfme server-side generation
  • preview/download PDF APIs
  • approved PDF generation
  • approved snapshot persistence
  • approved PDF attachment metadata
  • quotation detail PDF actions

Task H.1 focuses on validation, hardening, and documentation.


Must Read

docs/implementation/technical-debt.md
docs/adr/0008-attachment-storage-strategy.md

src/features/foundation/pdf-generator/**
src/features/foundation/document-template/**
src/features/crm/quotations/document/**
src/features/crm/quotations/**
src/features/foundation/approval/**
src/app/api/crm/quotations/[id]/pdf-preview/route.ts
src/app/api/crm/quotations/[id]/pdf-download/route.ts
src/app/api/crm/quotations/[id]/approved-pdf/route.ts
src/db/schema.ts

Scope 1: Smoke Test With Real Quotation

Create or identify one real quotation record in dev database.

The record must include:

customer
contact
enquiry optional
at least one item
quotation customer role
scope topic
exclusion topic
payment topic
approved status or approval flow completed

Then verify:

Preview PDF
Download PDF
Generate Approved PDF
View Approved PDF

If no real record exists, create a minimal seed/dev fixture.

Rules:

  • dev fixture must be organization-scoped
  • do not hardcode organizationId
  • do not pollute production seed
  • place fixture under dev-only seed or clearly named script

Scope 2: PDF Output Validation

Check generated PDF for:

file opens correctly
page count is reasonable
customer block appears
quotation code appears
item table appears
total amount appears
scope/exclusion/payment appears
approval block appears
signature placeholder appears

If layout breaks:

  • adjust mapping normalization
  • adjust template input preparation
  • do not rewrite template designer
  • do not hardcode quotation-specific hacks into generic pdf generator

Scope 3: Approved PDF API Validation

Validate:

GET /api/crm/quotations/[id]/pdf-preview
GET /api/crm/quotations/[id]/pdf-download
POST /api/crm/quotations/[id]/approved-pdf
GET /api/crm/quotations/[id]/approved-pdf

Expected behavior:

  • preview returns inline PDF
  • download returns attachment PDF
  • approved-pdf POST only works for approved quotation
  • approved-pdf GET returns stored file if available
  • non-approved quotation cannot generate approved PDF

Scope 4: Persistence Validation

After approved PDF generation verify:

quotation.approvedPdfUrl populated
quotation.approvedSnapshot populated
quotation.approvedTemplateVersionId populated
quotation attachment metadata created or updated
audit log generated
file exists in public/generated/quotations/<organizationId>/

If any part is missing, fix only the persistence pipeline.


Scope 5: Permission Validation

Verify permissions:

crm.quotation.pdf.preview
crm.quotation.pdf.download
crm.quotation.pdf.generate_approved

Check behavior for:

super_admin
admin
regular user with permission
regular user without permission

Do not rewrite RBAC model.


Scope 6: Error Handling

Improve user-safe/server-safe errors for:

template not found
template version not found
mapping missing
quotation not approved
generated file missing
pdfme generation error
local storage write error
permission denied

Rules:

  • API must return meaningful status codes
  • UI should show readable toast/message
  • do not expose stack trace to client

Scope 7: Documentation / ADR

Update:

docs/implementation/technical-debt.md

Confirm or add:

pdfme font fallback workaround
local filesystem storage limitation
missing object storage abstraction
approved PDF lifecycle not immutable yet
no full E2E test in CI yet

Create ADR if not exists:

docs/adr/0009-approved-document-storage-lifecycle.md

Include:

Current:
local public/generated storage

Decision:
acceptable for development/MVP only

Future:
object storage abstraction
signed URL
immutable approved artifacts
retention policy

Scope 8: Optional Small Fix

If approval finalization already has a clean hook point, add a non-blocking TODO or optional manual trigger note for:

auto-generate approved PDF after final approval

Do not force automatic generation in Task H.1 if it risks breaking approval flow.


ห้ามทำ

object storage production
signed URL service
template designer
mapping editor
email notification
report
dashboard KPI
large refactor

Output

After completion, summarize:

  1. Files Added
  2. Files Modified
  3. Smoke Test Record Used
  4. PDF APIs Verified
  5. Persistence Verified
  6. Permission Verified
  7. Error Handling Improved
  8. ADR / Technical Debt Updated
  9. Remaining Risks
  10. Task I Readiness

Definition of Done

Task H.1 passes when:

✔ PDF preview works with a real quotation

✔ PDF download works with a real quotation

✔ Approved PDF generation works for approved quotation

✔ Approved PDF GET returns stored PDF

✔ Non-approved quotation cannot generate approved PDF

✔ approvedSnapshot is saved

✔ approvedPdfUrl is saved

✔ approvedTemplateVersionId is saved

✔ attachment metadata is created/updated

✔ audit log exists for approved PDF generation

✔ permissions are enforced

✔ errors are user-safe

✔ storage lifecycle ADR exists

✔ ready for Task I