Files
alla-allaos-fullstack/plans/task-h.3.md
phaichayon a85d24235c task-h.4
2026-06-19 12:30:26 +07:00

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

  1. Files Added
  2. Files Modified
  3. Signature Resolution Strategy
  4. Position Resolution Strategy
  5. PDF Mapping Changes
  6. Snapshot Changes
  7. Verification Result
  8. ADR Added
  9. 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