Hotfix Rule: Force Fresh Data After CRUD Mutation
Task-h not implements
This commit is contained in:
248
plans/task-h.md
Normal file
248
plans/task-h.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Task H: PDF Generation + Approved Document Persistence
|
||||
|
||||
## ALLA OS CRM vNext
|
||||
|
||||
คุณคือ Senior Full-stack Engineer
|
||||
|
||||
ให้ implement PDF generation สำหรับ Quotation โดยต่อยอดจาก Task G
|
||||
|
||||
## ต้องอ่านก่อน
|
||||
|
||||
```txt
|
||||
docs/implementation/task-a-template-audit.md
|
||||
docs/implementation/technical-debt.md
|
||||
docs/adr/0008-attachment-storage-strategy.md
|
||||
|
||||
src/features/foundation/document-template/**
|
||||
src/features/crm/quotations/document/**
|
||||
src/features/crm/quotations/**
|
||||
src/features/foundation/approval/**
|
||||
src/db/schema.ts
|
||||
```
|
||||
|
||||
## Goal
|
||||
|
||||
สร้าง production foundation สำหรับ:
|
||||
|
||||
```txt
|
||||
Generate PDF from pdfme template
|
||||
Preview/download PDF
|
||||
Persist approved PDF snapshot
|
||||
Attach generated PDF metadata to quotation
|
||||
```
|
||||
|
||||
## Scope H1: PDF Generation Service
|
||||
|
||||
สร้าง service:
|
||||
|
||||
```txt
|
||||
src/features/foundation/pdf-generator/**
|
||||
```
|
||||
|
||||
Functions:
|
||||
|
||||
```ts
|
||||
generatePdfFromTemplate(input)
|
||||
generateQuotationPdf(quotationId)
|
||||
generateQuotationPreviewPdf(quotationId)
|
||||
generateApprovedQuotationPdf(quotationId)
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
* ใช้ templateVersion + schemaJson จาก Task G
|
||||
* ใช้ `buildQuotationDocumentData`
|
||||
* ใช้ `mapDocumentDataToTemplateInput`
|
||||
* ห้าม generate จาก client
|
||||
* validate organizationId ทุกครั้ง
|
||||
|
||||
## Scope H2: PDF Download APIs
|
||||
|
||||
เพิ่ม routes:
|
||||
|
||||
```txt
|
||||
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
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
```txt
|
||||
pdf-preview = generate PDF ชั่วคราวจาก current data
|
||||
pdf-download = download quotation PDF
|
||||
approved-pdf = generate/store approved PDF
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
* preview/download ต้อง check permission
|
||||
* approved-pdf ต้องอนุญาตเฉพาะ approved quotation
|
||||
* response ต้องเป็น application/pdf
|
||||
* filename ใช้ quotation code
|
||||
|
||||
## Scope H3: Approved Snapshot Persistence
|
||||
|
||||
เมื่อ quotation approved แล้ว หรือเมื่อกด generate approved PDF:
|
||||
|
||||
ให้ persist:
|
||||
|
||||
```txt
|
||||
approvedSnapshot
|
||||
approvedPdfUrl
|
||||
approvedAt
|
||||
templateVersionId
|
||||
```
|
||||
|
||||
ถ้า schema ยังไม่มี field บางตัว ให้เพิ่มอย่างระวัง
|
||||
|
||||
Snapshot ต้องเก็บ:
|
||||
|
||||
```txt
|
||||
quotation data
|
||||
items
|
||||
customers
|
||||
topics
|
||||
approval timeline
|
||||
templateVersionId
|
||||
templateInput
|
||||
generatedAt
|
||||
generatedBy
|
||||
```
|
||||
|
||||
## Scope H4: Attachment Metadata Integration
|
||||
|
||||
หลัง generate approved PDF ให้สร้าง attachment metadata:
|
||||
|
||||
```txt
|
||||
fileName
|
||||
originalFileName
|
||||
filePath
|
||||
fileSize
|
||||
fileType = application/pdf
|
||||
description = Approved quotation PDF
|
||||
uploadedBy
|
||||
uploadedAt
|
||||
```
|
||||
|
||||
ถ้ายังไม่มี storage provider จริง:
|
||||
|
||||
* ใช้ local/generated path placeholder ได้
|
||||
* ระบุ technical debt ชัดเจน
|
||||
|
||||
## Scope H5: Quotation UI Integration
|
||||
|
||||
ใน quotation detail:
|
||||
|
||||
เพิ่ม actions:
|
||||
|
||||
```txt
|
||||
Preview PDF
|
||||
Download PDF
|
||||
Generate Approved PDF
|
||||
View Approved PDF
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
* Preview PDF ใช้ได้กับ draft/pending/approved
|
||||
* Generate Approved PDF ใช้ได้เฉพาะ approved
|
||||
* ถ้ามี approvedPdfUrl แล้ว แสดง View Approved PDF
|
||||
* แสดง template version ที่ใช้
|
||||
|
||||
## Scope H6: Approval Integration
|
||||
|
||||
หลัง final approval สำเร็จ:
|
||||
|
||||
```txt
|
||||
quotation.status = approved
|
||||
```
|
||||
|
||||
ให้เตรียม hook หรือ optional call:
|
||||
|
||||
```ts
|
||||
prepareApprovedQuotationSnapshot()
|
||||
```
|
||||
|
||||
ถ้า generate PDF อัตโนมัติยังเสี่ยง ให้ทำ manual action ก่อน
|
||||
|
||||
Recommendation:
|
||||
|
||||
```txt
|
||||
Task H: manual generate approved PDF
|
||||
Future: auto-generate after final approval
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
เพิ่มถ้ายังไม่มี:
|
||||
|
||||
```txt
|
||||
crm.quotation.pdf.preview
|
||||
crm.quotation.pdf.download
|
||||
crm.quotation.pdf.generate_approved
|
||||
```
|
||||
|
||||
## Audit
|
||||
|
||||
Audit actions:
|
||||
|
||||
```txt
|
||||
crm_quotation_pdf_preview optional
|
||||
crm_quotation_pdf_download optional
|
||||
crm_quotation_pdf_generate_approved required
|
||||
```
|
||||
|
||||
Preview/download audit ไม่บังคับ
|
||||
Generate approved PDF ต้อง audit
|
||||
|
||||
## ห้ามทำ
|
||||
|
||||
```txt
|
||||
Template drag/drop designer
|
||||
Notification
|
||||
Dashboard KPI
|
||||
Report
|
||||
External object storage production
|
||||
Email sending
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
สรุป:
|
||||
|
||||
1. Files Added
|
||||
2. Files Modified
|
||||
3. PDF Generator Added
|
||||
4. API Routes Added
|
||||
5. UI Actions Added
|
||||
6. Approved Snapshot Persistence
|
||||
7. Attachment Metadata Integration
|
||||
8. Permission Added
|
||||
9. Audit Integration
|
||||
10. Remaining Risks
|
||||
11. Task I Readiness
|
||||
|
||||
## Definition of Done
|
||||
|
||||
Task H ผ่านเมื่อ:
|
||||
|
||||
✔ generate PDF จาก pdfme template ได้
|
||||
|
||||
✔ preview/download PDF ได้
|
||||
|
||||
✔ approved quotation generate approved PDF ได้
|
||||
|
||||
✔ approved snapshot ถูก persist
|
||||
|
||||
✔ attachment metadata ถูกสร้าง
|
||||
|
||||
✔ UI มี PDF actions
|
||||
|
||||
✔ permission guard ครบ
|
||||
|
||||
✔ audit generate approved PDF
|
||||
|
||||
✔ ยังไม่ทำ template designer
|
||||
|
||||
✔ ยังไม่ทำ notification/report
|
||||
Reference in New Issue
Block a user