Files
alla-allaos-fullstack/docs/implementation/task-h3-approval-signature-strategy.md
phaichayon a85d24235c task-h.4
2026-06-19 12:30:26 +07:00

79 lines
3.0 KiB
Markdown

# Task H.3: Approval Signature Strategy
## Files Added
- `src/features/crm/quotations/document/signature.types.ts`
- `src/features/crm/quotations/document/signature-position.ts`
- `src/features/crm/quotations/document/server/signature-resolver.ts`
- `scripts/verify-task-h3.js`
- `docs/adr/0012-approval-signature-strategy.md`
- `docs/implementation/task-h3-approval-signature-strategy.md`
## Files Modified
- `src/features/crm/quotations/document/types.ts`
- `src/features/crm/quotations/document/server/service.ts`
- `src/features/crm/quotations/components/quotation-document-preview.tsx`
- `src/features/foundation/pdf-generator/server/service.ts`
- `src/db/seeds/foundation.seed.ts`
- `docs/implementation/technical-debt.md`
- `package.json`
## Signature Resolution Strategy
- `Prepared By` resolves from `quotation.salesmanId`, then falls back to `quotation.createdBy`
- `Approved By` resolves from the latest approved workflow action for `sales_manager` or `department_manager`, excluding the final authorization step
- `Authorized By` resolves from the latest approved workflow action for the final workflow step, which is `top_manager` in the standard flow
- each signature block now carries:
- `name`
- `position`
- `actedAt`
## Position Resolution Strategy
- primary source is `memberships.businessRole`
- display label first checks active `crm_job_title` master options
- fallback labels are:
- `sales` -> `Sales Engineer`
- `sales_support` -> `Sales Support`
- `sales_manager` -> `Sales Manager`
- `department_manager` -> `Department Manager`
- `top_manager` -> `General Manager`
## PDF Mapping Changes
- `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`
## Snapshot Changes
- `prepareApprovedQuotationSnapshot()` now stores the resolved signature block through `documentData`
- persisted `templateInput` now preserves the text values used for `app1/app2/app3`
- approved PDF generation prefers snapshot input when a snapshot already exists
## UI Changes
- quotation document preview now shows an `Approval Signatures` section
- each block displays:
- name
- position
- timestamp when available
## Verification Result
- `scripts/verify-task-h3.js` validates:
- DB mappings for `app1/app2/app3`
- `crm_job_title` master options
- approved snapshot signature payload
- approved snapshot template input alignment
## Remaining Risks
- organizations with custom approval roles outside the current sales-manager / department-manager / final-step model may need an extended resolver rule later
- `Prepared By` currently uses quotation `createdAt` as the available timestamp because the system does not yet store a separate “prepared at” event
- end-to-end PDF binary text extraction is still not automated; verification currently proves snapshot and template-input integrity