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