6.1 KiB
Task H.3: Approval Signature Strategy
Goal
ทำให้ PDF ใบเสนอราคาสามารถแสดงข้อมูลผู้จัดทำ ผู้อนุมัติ และผู้มีอำนาจอนุมัติได้อย่างถูกต้อง
รองรับทั้ง:
Preview PDF
Approved PDF
Approved Snapshot
Document Artifact
โดยข้อมูลลายเซ็นต้องมาจาก Approval Workflow จริง ไม่ใช่ค่าคงที่ใน Template
Background
Task H.2 เพิ่ม:
Dynamic Topic Engine
PDFME Runtime Mapping
Template Mapping Resolver
Task H.1 เพิ่ม:
Approved Snapshot
Artifact Storage
Task H.3 จะเติมส่วนที่ยังขาด:
Prepared By
Approved By
Authorized By
Position
Approval Timeline Resolution
Current Problem
Template ปัจจุบันมี placeholder เช่น:
app1
app1_position
app2
app2_position
app3
app3_position
แต่ยังไม่มี strategy กลางสำหรับดึงข้อมูลจริงจาก:
quotation
approval workflow
approval actions
membership
business role
Scope H3.1 Signature Data Contract
Create:
src/features/crm/quotations/document/signature.types.ts
Define:
type SignatureBlock = {
preparedBy: {
name: string;
position: string;
};
approvedBy: {
name: string;
position: string;
};
authorizedBy: {
name: string;
position: string;
};
};
Scope H3.2 Position Resolution Strategy
Create:
src/features/crm/quotations/document/signature-position.ts
Resolve position from:
membership.businessRole
Recommended mapping:
sales
→ Sales Engineer
sales_support
→ Sales Support
sales_manager
→ Sales Manager
department_manager
→ Department Manager
top_manager
→ General Manager
Rules:
Do NOT hardcode display strings inside PDF generator.
Source from:
crm_job_title
master option when available.
Fallback:
businessRole label
Scope H3.3 Prepared By Resolution
Prepared By source:
Priority:
quotation.salesmanId
Fallback:
quotation.createdBy
Output:
preparedBy.name
preparedBy.position
Rules:
Must resolve display name.
Never use raw user id.
Scope H3.4 Approved By Resolution
Resolve from approval workflow history.
Source:
crm_approval_actions
Rules:
Find latest approved action from:
sales_manager
or
department_manager
depending on workflow configuration.
Output:
approvedBy.name
approvedBy.position
Scope H3.5 Authorized By Resolution
Resolve from final approval step.
Source:
crm_approval_actions
Rules:
Find final approved action.
Expected role:
top_manager
Output:
authorizedBy.name
authorizedBy.position
Scope H3.6 Signature Resolver
Create:
src/features/crm/quotations/document/server/signature-resolver.ts
Expose:
resolveQuotationSignatures(
quotationId,
organizationId
)
Returns:
SignatureBlock
Responsibilities:
load quotation
load approval history
resolve users
resolve positions
build final signature object
Scope H3.7 PDF Mapping Integration
Update:
src/features/crm/quotations/document/server/service.ts
Inject:
signatures.preparedBy.name
signatures.preparedBy.position
signatures.approvedBy.name
signatures.approvedBy.position
signatures.authorizedBy.name
signatures.authorizedBy.position
Into:
documentData
templateInput
approvedSnapshot
Scope H3.8 PDFME Placeholder Mapping
Update seed mappings.
Expected:
app1
→ signatures.preparedBy.name
app1_position
→ signatures.preparedBy.position
app2
→ signatures.approvedBy.name
app2_position
→ signatures.approvedBy.position
app3
→ signatures.authorizedBy.name
app3_position
→ signatures.authorizedBy.position
Rules:
Idempotent seed.
Update existing mappings if incorrect.
Scope H3.9 Approved Snapshot Integration
Update:
prepareApprovedQuotationSnapshot()
Snapshot must store:
resolved signatures
Purpose:
Future PDF regeneration must preserve:
who approved
who authorized
even if users later change.
Scope H3.10 Preview Behavior
Preview PDF:
resolve live signatures
Approved PDF:
prefer approved snapshot signatures
Rules:
Approved artifact must remain immutable.
Scope H3.11 UI Visibility
Update quotation detail.
Add section:
Approval Signatures
Display:
Prepared By
Approved By
Authorized By
with:
name
position
approval timestamp
if available.
Scope H3.12 Verification
Create:
scripts/verify-task-h3.js
Verify:
preparedBy exists
approvedBy exists
authorizedBy exists
app1 mapped
app2 mapped
app3 mapped
snapshot contains signatures
approved PDF contains names
ADR
Create:
docs/adr/0012-approval-signature-strategy.md
Freeze:
Prepared By rule
Approved By rule
Authorized By rule
Position resolution rule
Snapshot immutability rule
Explicit Non-Scope
Do NOT implement:
Digital signature
Image signature
Certificate signature
PKI
e-Signature
QR verification
Stamp image upload
Only text-based approval identity.
Output
- Files Added
- Files Modified
- Signature Resolution Strategy
- Position Resolution Strategy
- PDF Mapping Changes
- Snapshot Changes
- Verification Result
- ADR Added
- Remaining Risks
Definition of Done
✔ Prepared By resolves correctly
✔ Approved By resolves correctly
✔ Authorized By resolves correctly
✔ Position resolves correctly
✔ PDF Preview displays signatures
✔ Approved PDF displays signatures
✔ Approved Snapshot stores signatures
✔ app1/app2/app3 mappings work
✔ Artifact remains immutable
✔ ADR created