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:
- Files Added
- Files Modified
- Smoke Test Record Used
- PDF APIs Verified
- Persistence Verified
- Permission Verified
- Error Handling Improved
- ADR / Technical Debt Updated
- Remaining Risks
- 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