# 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.