This commit is contained in:
phaichayon
2026-06-26 11:03:25 +07:00
parent 42c8c59947
commit 052677fa2c
16 changed files with 1604 additions and 68 deletions

View File

@@ -0,0 +1,81 @@
# Task F.2: Approval Matrix Foundation
## Summary
This task adds approval-matrix based workflow resolution for quotation submission so the system no longer relies on a single static workflow code.
## Delivered
- Added `crm_approval_matrices` persistence in [src/db/schema.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/db/schema.ts).
- Added SQL migration in [drizzle/0002_calm_approval_matrix.sql](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/drizzle/0002_calm_approval_matrix.sql).
- Seeded a default quotation matrix in [src/db/seeds/foundation.seed.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/db/seeds/foundation.seed.ts) to preserve current behavior.
- Added matrix validation in [src/features/crm/approval/schemas/approval-matrix.schema.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/approval/schemas/approval-matrix.schema.ts).
- Added matrix CRUD and resolver services in [src/features/crm/approval/server/service.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/approval/server/service.ts).
- Added settings APIs:
- [src/app/api/crm/settings/approval-matrices/route.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/settings/approval-matrices/route.ts)
- [src/app/api/crm/settings/approval-matrices/[id]/route.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/settings/approval-matrices/[id]/route.ts)
- Updated quotation submit approval flow in [src/app/api/crm/quotations/[id]/submit-approval/route.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/quotations/[id]/submit-approval/route.ts) to resolve workflow by matrix before creating the approval request.
- Extended foundation approval submit input in:
- [src/features/foundation/approval/types.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/approval/types.ts)
- [src/features/foundation/approval/server/service.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/approval/server/service.ts)
- Added permissions in [src/lib/auth/rbac.ts](/c:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/lib/auth/rbac.ts):
- `crm.approval.matrix.read`
- `crm.approval.matrix.create`
- `crm.approval.matrix.update`
- `crm.approval.matrix.delete`
## Matching Rules
- Scope filters consider organization, entity type, active state, and soft delete.
- `productType`, `branchId`, and `currency` match exact values or `null` wildcard.
- `amount` respects `minAmount` and `maxAmount` when those bounds exist.
- Specific rules outrank default rules.
- Specificity scoring prefers:
- product type match
- branch match
- currency match
- amount-range match
- Lower `priority` value wins after specificity.
- If specificity and priority tie, the newest active rule wins.
- If candidates still tie on the same creation timestamp, the resolver throws a deterministic configuration conflict.
- If no specific rule matches, the resolver falls back to an active default rule.
## Submit Approval Integration
- Quotation submit approval now:
1. loads the quotation
2. enforces CRM scoped access
3. resolves the approval matrix
4. submits approval using the resolved `workflowId`
5. writes audit data for the resolution
- Existing approve, reject, return, and cancel flows remain unchanged.
## Audit
- Matrix CRUD uses `entityType = crm_approval_matrix`.
- Matrix maintenance actions:
- `create_approval_matrix`
- `update_approval_matrix`
- `delete_approval_matrix`
- Quotation submission writes `resolve_approval_matrix` with:
- `quotationId`
- `approvalRequestId`
- `matrixId`
- `workflowId`
- `matchReason`
- `productType`
- `branchId`
- `amount`
- `currency`
## Seed Behavior
- Foundation seed creates or refreshes one active default quotation matrix pointing to `quotation_standard_approval`.
- This preserves legacy quotation approval behavior until organization-specific rules are added.
- Sample non-default matrices were intentionally not seeded because additional workflows such as executive approval are not yet guaranteed in every environment.
## Known Limitations
- F.2 adds API and service foundations only. No matrix admin UI is included.
- Overlapping active rules are allowed. Resolver handles them deterministically, but configuration hygiene still matters.
- Matrix branch, product, and currency values currently assume the same ids already stored on quotation records.