task-g
This commit is contained in:
509
plans/task-g.md
Normal file
509
plans/task-g.md
Normal file
@@ -0,0 +1,509 @@
|
||||
# Task G: Quotation Document Preview / PDF Template Foundation
|
||||
|
||||
## ALLA OS CRM vNext
|
||||
|
||||
คุณคือ Senior Full-stack Engineer
|
||||
|
||||
ให้ implement Quotation Document Preview และ PDF Template Foundation โดยต่อยอดจาก:
|
||||
|
||||
```txt
|
||||
Task A
|
||||
Task B
|
||||
Task B.1
|
||||
Task C
|
||||
Task D
|
||||
Task E
|
||||
Task E.1
|
||||
Task F
|
||||
```
|
||||
|
||||
## ต้องอ่านก่อน
|
||||
|
||||
```txt
|
||||
docs/implementation/task-a-template-audit.md
|
||||
docs/implementation/task-b-template-audit.md
|
||||
docs/implementation/task-b1-foundation-stabilization.md
|
||||
docs/implementation/technical-debt.md
|
||||
|
||||
docs/adr/0007-quotation-revision-strategy.md
|
||||
docs/adr/0008-attachment-storage-strategy.md
|
||||
|
||||
Layout.md
|
||||
AGENTS.md
|
||||
.agents/skills/kiranism-shadcn-dashboard
|
||||
|
||||
src/features/foundation/**
|
||||
src/features/crm/customers/**
|
||||
src/features/crm/enquiries/**
|
||||
src/features/crm/quotations/**
|
||||
src/db/schema.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Goal
|
||||
|
||||
สร้าง foundation สำหรับเอกสารใบเสนอราคา
|
||||
|
||||
โฟกัสที่:
|
||||
|
||||
```txt
|
||||
Quotation document preview
|
||||
PDF template metadata
|
||||
Template versioning
|
||||
Template placeholder mapping
|
||||
Approved snapshot preparation
|
||||
```
|
||||
|
||||
ยังไม่ทำ PDF generation จริงแบบ production เต็ม
|
||||
|
||||
---
|
||||
|
||||
# Scope G1: Template Schema
|
||||
|
||||
เพิ่ม tables ถ้ายังไม่มี
|
||||
|
||||
```txt
|
||||
crm_document_templates
|
||||
crm_document_template_versions
|
||||
crm_document_template_mappings
|
||||
crm_document_template_table_columns
|
||||
```
|
||||
|
||||
## crm_document_templates
|
||||
|
||||
```txt
|
||||
id
|
||||
organizationId
|
||||
|
||||
documentType
|
||||
productType
|
||||
fileType
|
||||
|
||||
templateName
|
||||
description
|
||||
|
||||
isDefault
|
||||
isActive
|
||||
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
createdBy
|
||||
updatedBy
|
||||
```
|
||||
|
||||
documentType example:
|
||||
|
||||
```txt
|
||||
quotation
|
||||
```
|
||||
|
||||
fileType example:
|
||||
|
||||
```txt
|
||||
pdfme
|
||||
excel
|
||||
html
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## crm_document_template_versions
|
||||
|
||||
```txt
|
||||
id
|
||||
organizationId
|
||||
templateId
|
||||
|
||||
version
|
||||
filePath
|
||||
schemaJson
|
||||
previewImageUrl
|
||||
|
||||
isActive
|
||||
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
createdBy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## crm_document_template_mappings
|
||||
|
||||
```txt
|
||||
id
|
||||
organizationId
|
||||
templateVersionId
|
||||
|
||||
placeholderKey
|
||||
sourcePath
|
||||
dataType
|
||||
|
||||
sheetName
|
||||
defaultValue
|
||||
formatMask
|
||||
sortOrder
|
||||
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
```
|
||||
|
||||
dataType:
|
||||
|
||||
```txt
|
||||
scalar
|
||||
multiline
|
||||
table
|
||||
image
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## crm_document_template_table_columns
|
||||
|
||||
```txt
|
||||
id
|
||||
organizationId
|
||||
mappingId
|
||||
|
||||
columnName
|
||||
sourceField
|
||||
columnLetter
|
||||
sortOrder
|
||||
formatMask
|
||||
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope G2: Quotation Snapshot Preparation
|
||||
|
||||
เพิ่มใน quotation document service
|
||||
|
||||
สร้าง function:
|
||||
|
||||
```ts
|
||||
buildQuotationDocumentData(quotationId)
|
||||
```
|
||||
|
||||
ให้ output เป็น normalized object สำหรับ preview/document generation
|
||||
|
||||
ต้องรวม:
|
||||
|
||||
```txt
|
||||
company
|
||||
branch
|
||||
customer
|
||||
contact
|
||||
quotation
|
||||
items
|
||||
quotationCustomers
|
||||
topics
|
||||
approval
|
||||
signatures placeholder
|
||||
```
|
||||
|
||||
ตัวอย่าง output:
|
||||
|
||||
```ts
|
||||
{
|
||||
company: {},
|
||||
branch: {},
|
||||
customer: {},
|
||||
contact: {},
|
||||
quotation: {},
|
||||
items: [],
|
||||
topics: {
|
||||
scope: [],
|
||||
exclusion: [],
|
||||
payment: []
|
||||
},
|
||||
approval: {
|
||||
status,
|
||||
approvedAt,
|
||||
approvers: []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
* validate organizationId
|
||||
* ห้าม query ข้าม organization
|
||||
* ใช้ approved quotation ได้
|
||||
* draft/pending preview ได้ แต่ต้องแสดง watermark/status badge ใน UI
|
||||
|
||||
---
|
||||
|
||||
# Scope G3: Template Mapping Resolver
|
||||
|
||||
สร้าง service:
|
||||
|
||||
```txt
|
||||
src/features/foundation/document-template/**
|
||||
```
|
||||
|
||||
หรือถ้าเหมาะสม:
|
||||
|
||||
```txt
|
||||
src/features/crm/quotations/document/**
|
||||
```
|
||||
|
||||
Functions:
|
||||
|
||||
```ts
|
||||
resolveTemplateForDocument(params)
|
||||
resolveTemplateMappings(templateVersionId)
|
||||
mapDocumentDataToTemplateInput(documentData, mappings)
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
* template default ตาม documentType + productType + fileType
|
||||
* fallback default template ของ documentType
|
||||
* mapping ต้องไม่ hardcode เฉพาะ quotation มากเกินไป
|
||||
* sourcePath ใช้ dot path เช่น customer.name, quotation.code, items
|
||||
|
||||
---
|
||||
|
||||
# Scope G4: API Routes
|
||||
|
||||
เพิ่ม route handlers:
|
||||
|
||||
```txt
|
||||
src/app/api/crm/quotations/[id]/document-data/route.ts
|
||||
src/app/api/crm/quotations/[id]/document-preview/route.ts
|
||||
src/app/api/crm/document-templates/route.ts
|
||||
src/app/api/crm/document-templates/[id]/route.ts
|
||||
src/app/api/crm/document-templates/[id]/versions/route.ts
|
||||
```
|
||||
|
||||
รองรับ:
|
||||
|
||||
```txt
|
||||
GET quotation document data
|
||||
GET quotation document preview data
|
||||
GET/POST document templates
|
||||
GET/PATCH/DELETE document template
|
||||
GET/POST template versions
|
||||
```
|
||||
|
||||
ยังไม่ต้องทำ binary PDF download
|
||||
|
||||
---
|
||||
|
||||
# Scope G5: Preview UI
|
||||
|
||||
ใน:
|
||||
|
||||
```txt
|
||||
/dashboard/crm/quotations/[id]
|
||||
```
|
||||
|
||||
แทน Document Preview Placeholder ด้วย real preview tab
|
||||
|
||||
Preview ต้องแสดง:
|
||||
|
||||
```txt
|
||||
quotation header
|
||||
customer block
|
||||
project info
|
||||
items table
|
||||
price summary
|
||||
scope/exclusion/payment topics
|
||||
approval block
|
||||
signature placeholders
|
||||
status watermark/badge
|
||||
```
|
||||
|
||||
ใช้ Layout.md และ shadcn dashboard style
|
||||
|
||||
ห้ามสร้าง design system ใหม่
|
||||
|
||||
---
|
||||
|
||||
# Scope G6: Template Settings UI
|
||||
|
||||
เพิ่ม route ถ้ายังเป็น placeholder:
|
||||
|
||||
```txt
|
||||
/dashboard/crm/settings/templates
|
||||
```
|
||||
|
||||
UI ขั้นต่ำ:
|
||||
|
||||
```txt
|
||||
Template list
|
||||
Template versions
|
||||
Default template badge
|
||||
Active/inactive badge
|
||||
Mapping count
|
||||
```
|
||||
|
||||
ยังไม่ต้องทำ template designer แบบ drag/drop
|
||||
|
||||
ทำได้แค่ metadata CRUD หรือ read-only listing ก่อน
|
||||
|
||||
---
|
||||
|
||||
# Scope G7: pdfme Template Seed
|
||||
|
||||
ถ้ามี template json อยู่แล้ว ให้ seed เป็น default quotation pdfme template
|
||||
|
||||
Seed:
|
||||
|
||||
```txt
|
||||
documentType = quotation
|
||||
fileType = pdfme
|
||||
productType = default
|
||||
templateName = ALLA Quotation Standard
|
||||
version = 1.0
|
||||
schemaJson = existing pdfme template json
|
||||
isDefault = true
|
||||
isActive = true
|
||||
```
|
||||
|
||||
Mapping placeholders:
|
||||
|
||||
```txt
|
||||
customer_name -> customer.name
|
||||
customer_addr -> customer.address
|
||||
customer_tel -> customer.phone
|
||||
customer_email -> customer.email
|
||||
customer_att -> contact.name
|
||||
project_name -> quotation.projectName
|
||||
site_location -> quotation.projectLocation
|
||||
quotation_date -> quotation.quotationDate
|
||||
quotation_code -> quotation.code
|
||||
quotation_price -> quotation.totalAmount
|
||||
currency -> quotation.currency
|
||||
exclusion_data -> topics.exclusion
|
||||
item_topic -> topics.scope
|
||||
```
|
||||
|
||||
ถ้าไม่มี template json ใน repo ให้สร้าง seed placeholder template schemaJson แบบ minimal
|
||||
|
||||
---
|
||||
|
||||
# Scope G8: Approved Snapshot Preparation
|
||||
|
||||
ยังไม่ต้อง generate PDF จริง
|
||||
|
||||
แต่ให้เตรียม service function:
|
||||
|
||||
```ts
|
||||
prepareApprovedQuotationSnapshot(quotationId)
|
||||
```
|
||||
|
||||
ใช้สำหรับอนาคตเมื่อ quotation approved แล้ว
|
||||
|
||||
Output:
|
||||
|
||||
```ts
|
||||
{
|
||||
quotationId,
|
||||
approvedAt,
|
||||
documentData,
|
||||
templateVersionId,
|
||||
templateInput
|
||||
}
|
||||
```
|
||||
|
||||
ยังไม่ต้องเขียนลง approvedPdfUrl ถ้ายังไม่มี PDF generator
|
||||
|
||||
---
|
||||
|
||||
# Permissions
|
||||
|
||||
เพิ่มถ้ายังไม่มี:
|
||||
|
||||
```txt
|
||||
crm.document_template.read
|
||||
crm.document_template.create
|
||||
crm.document_template.update
|
||||
crm.document_template.delete
|
||||
crm.quotation.document.preview
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Audit
|
||||
|
||||
Audit mutation:
|
||||
|
||||
```txt
|
||||
crm_document_template
|
||||
crm_document_template_version
|
||||
crm_document_template_mapping
|
||||
```
|
||||
|
||||
Preview GET ไม่ต้อง audit
|
||||
|
||||
---
|
||||
|
||||
# ห้ามทำ
|
||||
|
||||
```txt
|
||||
PDF binary generation
|
||||
Excel binary generation
|
||||
File upload storage
|
||||
Drag/drop template designer
|
||||
Report
|
||||
Dashboard KPI
|
||||
Notification
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Output
|
||||
|
||||
หลังทำเสร็จ สรุป:
|
||||
|
||||
1. Files Added
|
||||
2. Files Modified
|
||||
3. Schema Added
|
||||
4. API Routes Added
|
||||
5. Preview UI Added
|
||||
6. Template Settings UI Added
|
||||
7. Template Seed Added
|
||||
8. Mapping Resolver Added
|
||||
9. Approved Snapshot Prep Added
|
||||
10. Remaining Risks
|
||||
11. Task H Readiness
|
||||
|
||||
---
|
||||
|
||||
# Definition of Done
|
||||
|
||||
Task G ผ่านเมื่อ:
|
||||
|
||||
✔ document template schema พร้อม
|
||||
|
||||
✔ template version schema พร้อม
|
||||
|
||||
✔ mapping schema พร้อม
|
||||
|
||||
✔ quotation document data service พร้อม
|
||||
|
||||
✔ template resolver พร้อม
|
||||
|
||||
✔ quotation preview tab แสดงข้อมูลจริง
|
||||
|
||||
✔ template settings route ใช้งานได้ขั้นต่ำ
|
||||
|
||||
✔ pdfme default template seed พร้อม หรือ fallback minimal seed พร้อม
|
||||
|
||||
✔ approved snapshot preparation พร้อม
|
||||
|
||||
✔ ยังไม่ generate PDF binary จริง
|
||||
|
||||
✔ ยังไม่ทำ template designer
|
||||
|
||||
✔ ยังไม่ทำ report/dashboard
|
||||
Reference in New Issue
Block a user