Credit Policies
Access prerequisites
- Permission (module):
creditConfigManage(to create/edit). Read access to the screen is granted byviewCredits. - License/Feature:
CREDIT_INVESTMENTSenabled in the tenant license (Vault). - Menu container: TOKENIZATION → group Tokenized Credit
What it is / when to use
The Credit Policies screen registers eligibility rules and automatic risk assessment that the credit engine applies automatically to Deals (operations), Receivables, and Parties (participants). Each policy is a set of rules (field + operator + value) associated with an action — automatically approve, send for manual review, or reject.
Use this screen before operating credit: policies are the "risk lock" that decides whether an operation passes through directly, requires human analysis, or is blocked at the source — without depending on the operator remembering every criterion.
Prerequisites
- Permission:
creditConfigManageregistered for the operator's role (remember: the permission is dual — static CPM enum in the backend + dynamic module in the DB that controls the screen's*ngIfflags; both must be active for the buttons to appear). - License/Feature:
CREDIT_INVESTMENTSenabled. If disabled, the Tokenized Credit group does not appear in the menu at all. - Dependencies on other screens: none. However, it makes sense to register policies before creating Deals/Receivables, since evaluation runs at the moment those entities are approved.
Step by step
- Go to the menu Tokenized Credit → Policies.
- Use the Scope (Deals / Receivables / Parties) and Active (Yes/No) filters to locate existing policies.
- Click Create to open the form.
- Fill in Name, Scope, Priority, Version, and the Action (what happens if a rule fails).
- In the Rules block, click Add rule and build each condition: Field (the list changes according to scope), Operator, Value, and an optional error Message.
- Click Save (or Update when editing).
Fields
| Field | What it is | Required? | System/backend effect |
|---|---|---|---|
| Name | Policy identification | Yes | Stored in name; appears in the listing and in the evaluation result (policyName). |
| Scope | Which entity the policy applies to: DEAL, RECEIVABLE, or PARTY | Yes | Defines scope. The engine only evaluates policies whose scope matches the entity being approved (PolicyEvaluationService.evaluate(scope, ...)). Changing the scope changes the list of available Fields. |
| Priority | Evaluation order (lower = earlier) | No (default 0) | Stored in priority; policies are fetched ordered by priority. Does not interrupt evaluation — all policies for the scope are evaluated, but order affects result readability. |
| Version | Policy version number | No (default 1) | Stored in version; used to track revisions of the rule over time. |
| Active | Enables/disables the policy | Yes (default Yes) | Stored in active. Only active policies are evaluated (findByScope(scope, true)). Disabling is the way to "retire" without deleting history. |
| Description | Free text explaining the policy | No | Stored in description; internal documentation, no effect on evaluation. |
| Action | What happens if any rule in the policy fails: Automatically Approve, Manual Review, or Reject | Yes | Stored inside rulesJson as action. During evaluation, the action is escalated across all failed policies: REJECT > MANUAL_REVIEW > AUTO_APPROVE. A single policy requiring REJECT makes the final result a rejection. |
| Rule → Field | Entity attribute to compare (e.g., grossAmount, riskScore, originator.riskScore) | Yes (per rule) | Read by dot-notation from the evaluated object (originator.riskScore reads from { originator: { riskScore } }). The field list is specific per scope. |
| Rule → Operator | = ≠ > ≥ < ≤ IN NOT IN BETWEEN EXISTS NOT EXISTS | Yes (per rule) | Defines the comparison. IN/NOT IN/BETWEEN expect a list of values (comma-separated); BETWEEN uses exactly two (min, max). EXISTS/NOT EXISTS check for field presence. |
| Rule → Value | Comparison value | Conditional | Automatically converted: true/false become boolean; numbers become numeric; for IN/NOT IN/BETWEEN it is split by comma into a list. |
| Rule → Message | Error message displayed when the rule fails | No | Stored in rule.message; appears in the evaluation result as the reason for failure (failedRules[].message). |
Actions and modals
- Create / Update: saves the policy via
createPolicy/updatePolicy. The Save/Update button is only rendered for users withcreditConfigManage. - Add rule / Remove rule: manipulate the list of rules in the form and regenerate
rulesJsonautomatically (you do not edit the JSON manually). - Edit (pencil icon in the table): loads the policy and rebuilds the rules from the saved
rulesJson.
Since this is a sensitive risk configuration operation, saving may trigger step-up (password + MFA re-authentication, X-Step-Up-Token header, 5-minute window) depending on the environment configuration. This is not 4-eyes approval — it is only a re-confirmation of the operator's identity.
Business rules / important notes
Attention
- No policy = automatic approval. If a scope has no active policy, the entity is auto-approved by default. There is no implicit "deny all" — the lock only exists if you register it.
- Evaluation failure falls back to Manual Review. If the engine errors during evaluation (e.g., corrupted
rulesJson), the result is forced toMANUAL_REVIEWfor safety — it never approves blindly. - Null fields cause failure. If the rule's field does not exist on the evaluated object, most operators fail (except
NOT EXISTS). Be careful when referencing fields that are not always populated. - Changing scope resets valid fields. Rules built for one scope may reference fields that do not exist in another; review the rules if you change the scope of an existing policy.
- Action escalation is per failure. A single policy with a
REJECTaction that fails already drives the global result to rejection, even if dozens of others have passed.
- Financial values: numeric fields used in comparisons (gross/net amounts, credit limits) represent amounts that in the credit domain are treated as BigNumber — when defining thresholds (e.g.,
grossAmount > 100000), verify the unit/decimal places expected by the engine.
Examples
Scenario 1 — Auto-approve small deals from a trusted originator
Goal: frictionless processing of low-value operations from good originators.
- Scope: Deals. Action: Automatically Approve.
- Rules:
grossAmount≤50000originator.riskScore≥70originator.defaultCount=0
- Save.
Result: when approving a deal of R$ 30,000 whose originator has a score of 80 and zero defaults, all three rules pass and the deal is auto-approved. If the amount were R$ 80,000, the ≤ 50000 rule fails and, since the action is AUTO_APPROVE, this policy simply does not block — the result will depend on the other policies in the scope.
Scenario 2 — Force manual review of receivables without a validated invoice
Goal: never automatically approve a receivable without a validated fiscal document.
- Scope: Receivables. Action: Manual Review.
- Rules:
hasInvoiceValidation=true— Message: "Invoice not validated".hasDebtorConsent=true— Message: "Debtor did not confirm".
- Save.
Result: a receivable without a validated invoice causes the first rule to fail; since the action is MANUAL_REVIEW, the receivable goes to the human analysis queue instead of being approved directly.
Scenario 3 — Reject parties above the credit limit
Goal: immediately block over-leveraged participants.
- Scope: Parties. Action: Reject. Priority: 1 (evaluate early).
- Rules:
usedCredit<creditLimit— (model asbetween/lteaccording to the available metric; use an absolute ceiling here, e.g.😃defaultCount≤2— Message: "Excess defaults".
- Save.
Result: a party with 3 defaults fails the second rule; since the action is REJECT, the global evaluation result will be rejection even if other policies pass.