Skip to content

Credit Policies

Access prerequisites

  • Permission (module): creditConfigManage (to create/edit). Read access to the screen is granted by viewCredits.
  • License/Feature: CREDIT_INVESTMENTS enabled 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: creditConfigManage registered 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 *ngIf flags; both must be active for the buttons to appear).
  • License/Feature: CREDIT_INVESTMENTS enabled. 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

  1. Go to the menu Tokenized Credit → Policies.
  2. Use the Scope (Deals / Receivables / Parties) and Active (Yes/No) filters to locate existing policies.
  3. Click Create to open the form.
  4. Fill in Name, Scope, Priority, Version, and the Action (what happens if a rule fails).
  5. 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.
  6. Click Save (or Update when editing).

Fields

FieldWhat it isRequired?System/backend effect
NamePolicy identificationYesStored in name; appears in the listing and in the evaluation result (policyName).
ScopeWhich entity the policy applies to: DEAL, RECEIVABLE, or PARTYYesDefines 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.
PriorityEvaluation 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.
VersionPolicy version numberNo (default 1)Stored in version; used to track revisions of the rule over time.
ActiveEnables/disables the policyYes (default Yes)Stored in active. Only active policies are evaluated (findByScope(scope, true)). Disabling is the way to "retire" without deleting history.
DescriptionFree text explaining the policyNoStored in description; internal documentation, no effect on evaluation.
ActionWhat happens if any rule in the policy fails: Automatically Approve, Manual Review, or RejectYesStored 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 → FieldEntity 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 EXISTSYes (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 → ValueComparison valueConditionalAutomatically converted: true/false become boolean; numbers become numeric; for IN/NOT IN/BETWEEN it is split by comma into a list.
Rule → MessageError message displayed when the rule failsNoStored 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 with creditConfigManage.
  • Add rule / Remove rule: manipulate the list of rules in the form and regenerate rulesJson automatically (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 to MANUAL_REVIEW for 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 REJECT action 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.

  1. Scope: Deals. Action: Automatically Approve.
  2. Rules:
    • grossAmount 50000
    • originator.riskScore 70
    • originator.defaultCount = 0
  3. 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.

  1. Scope: Receivables. Action: Manual Review.
  2. Rules:
    • hasInvoiceValidation = true — Message: "Invoice not validated".
    • hasDebtorConsent = true — Message: "Debtor did not confirm".
  3. 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.

  1. Scope: Parties. Action: Reject. Priority: 1 (evaluate early).
  2. Rules:
    • usedCredit < creditLimit(model as between/lte according to the available metric; use an absolute ceiling here, e.g.😃
    • defaultCount 2 — Message: "Excess defaults".
  3. 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.