Database Schema
Complete reference for the RemoteEaze database schema as of 31/12/2025. Covers all tables, relationships, enums, and common patterns.
Schema Snapshot
This document reflects the Prisma schema as of 31 December 2025. The schema lives in packages/database/prisma/schema/.
Common Fields
Nearly every table in the schema shares a set of standard fields. These are documented once here and omitted from individual table descriptions to avoid repetition.
Audit Fields (present on all tables)
| Field | Type | Description |
|---|---|---|
id | String @id @default(cuid()) | Primary key. CUID format unless noted otherwise. |
version | Int @default(1) | Optimistic concurrency counter. Incremented on every update. |
customFields | Json? | Dynamic custom fields. GIN-indexed in PostgreSQL for efficient querying. |
createdAt | DateTime @db.Timestamptz(6) | Record creation timestamp (UTC). |
updatedAt | DateTime @updatedAt | Auto-updated by Prisma on every mutation. |
deletedAt | DateTime? | Soft delete marker. All queries filter deletedAt: null. |
Multi-Tenant Isolation
| Field | Type | Description |
|---|---|---|
tenantId | String | Loose reference to License.id (no FK). Every query is scoped by this field. Global reference tables (Nation, Language, Currency) do not have tenantId. |
Maker-Checker Fields (on workflow-enabled entities)
Entities that go through an approval workflow carry these additional fields:
| Field | Type | Description |
|---|---|---|
recordStatus | RecordStatus | Workflow state. See the RecordStatus enum below. |
createdById | String? | ID of the user who created the record (the "maker"). |
lastModifiedById | String? | ID of the user who last modified the record. |
rejectReason | String? | Reason for rejection, set by the "checker" when returning to maker. |
The workflow follows: CAPTURED -> PENDING_AUTH_L3/L2/L1 (depending on required approval levels) -> AUTHORIZED, or REJECTED / DENIED.
A. System Infrastructure
CustomFieldDefinition
Table: remoteEaze_custom_field_definitions
Purpose: Defines dynamic (tenant-configurable) columns that can be attached to any entity type. Each definition specifies the field key, label, data type, validation rules, default value strategy, and UI rendering config.
| Key Field | Type | Description |
|---|---|---|
entityType | String | The entity this field applies to (e.g. "customer", "account"). |
fieldKey | String | Machine key for the field (unique per tenant + entity). |
fieldLabel | String | Human-readable label for UI display. |
fieldType | CustomFieldType | Data type: STRING, NUMBER, BOOLEAN, DATE, COMPUTED, JSON, SELECT. |
isRequired | Boolean | Whether the field is mandatory. |
displayOrder | Int | Ordering hint for UI rendering. |
defaultValue | String? | Static default value. |
defaultStrategy | DefaultStrategy? | How defaults are determined: STATIC, RULE_BASED, or COMPUTED. |
defaultRules | Json? | Rules for RULE_BASED defaults. |
computedFormula | String? | Formula for COMPUTED defaults. |
validation / validationRules | Json? | Validation configuration. |
uiConfig | Json? | UI rendering hints (widget type, placeholder, etc.). |
isActive | Boolean | Whether the field definition is currently active. |
Unique constraint: [tenantId, entityType, fieldKey]
ActivityLog
Table: remoteEaze_activity_logs
Purpose: Immutable audit trail capturing the "Who, What, Where, When, and Why" of every significant action. Uses loose references (no FKs) so audit history survives entity deletion.
See the dedicated Activity Logs documentation for the full architecture, tiered logging strategy, sensitivity/sanitization model, and usage guide.
| Key Field | Type | Description |
|---|---|---|
id | String | Custom time-sorted format: YYYYMMDD-HHMMSSms-RAND. |
actorId / actorType / actorName | Various | Who performed the action (snapshot at time of action). |
action | String | Action identifier, e.g. "customer.create", "auth.signin". |
entityType / entityId | String | What entity was affected. |
timestamp | DateTime | When the action actually occurred (UTC). |
changeBefore / changeAfter / diff | Json? | State before/after mutation, plus calculated delta. |
recordStatusBefore / recordStatusAfter | String? | Workflow state transitions. |
status | LogStatus | SUCCESS, FAILURE, or PENDING. |
isSensitive | Boolean | Flags rows containing encrypted PII (HIGH sensitivity). |
retentionPolicy | String | Retention rule: "90_days", "1_year", "2_years", "7_years". |
module | String? | Business module: "AUTH", "LOANS", etc. |
tags | String[] | Filterable tags (GIN indexed). |
Indexes: Optimized for tenant+date range, action filtering, entity history, user timeline, trace correlation, status analysis, and tag/custom field queries (GIN).
Sequence
Table: remoteEaze_sequences
Purpose: Atomic auto-incrementing sequence generator used to produce business keys (customer numbers, staff numbers, agent numbers, account numbers). Supports configurable prefix, zero-padding, year inclusion, and yearly reset.
| Key Field | Type | Description |
|---|---|---|
name | String | Sequence identifier, e.g. "CUSTOMER", "ACCOUNT", "AGENT", "STAFF". |
current | BigInt | Current counter value. Incremented atomically in a transaction. |
prefix | String? | Static prefix prepended to the generated value, e.g. "STF-", "AGT-". |
padLength | Int | Zero-pad the sequence number to this length (default 10). |
includeYear | Boolean | Whether to embed the year in the generated value. |
resetYearly | Boolean | Whether to reset the counter to 0 each January. |
lastResetYear | Int? | Tracks when the last yearly reset occurred. |
Unique constraint: [tenantId, name]
B. Tenant & Organization
License
Table: remoteEaze_licenses
Purpose: The root tenant/organization record. Each License represents one organization using the system. Contains company information, contract details, financial configuration, password policies, and session policies.
| Key Field | Type | Description |
|---|---|---|
companyName | String | Full company name. |
companyAbbreviation | String @unique | Auto-generated 3-4 char abbreviation (e.g. "KCB", "STC"). Used in branch code generation. |
slug | String @unique | URL-safe identifier, e.g. "kcb-bank". |
licenseCode | String @unique | Unique license/contract identifier. |
licenseExpiryDate | DateTime @db.Date | Contract expiry. Evaluated at EOD in tenant's timezone. |
modules | String[] | Licensed modules: ["CORE", "LORG", "LP"]. |
timezone | String | IANA timezone, e.g. "Africa/Nairobi". |
financialYearCycle | String | Financial year configuration, e.g. "20251231M1231". |
accountingType | String | "CASH" or "ACCRUAL". |
passwordMin* | Int | Password policy settings (length, numbers, uppercase, special chars, lowercase). |
inactivityTimeout | Int | Session inactivity timeout in seconds (default 600). |
passwordChangeInterval | Int | Days between forced password changes (default 90). |
isActive | Boolean | Whether the license is active. |
Branch
Table: remoteEaze_branches
Purpose: Organizational branches with parent-child hierarchy. Each branch has an auto-generated code and belongs to a nation and currency. On authorization, ProductBalance rows are created for all applicable products.
| Key Field | Type | Description |
|---|---|---|
code | String | Auto-generated: {CNA}-{RCC}-{BBB}-0000. CNA = company abbreviation, RCC = country alpha-3, BBB = branch sequence (000 = Lead). |
name | String | Branch display name. |
branchType | BranchType | LEAD (head office) or BRANCH. |
reportingBranchId | String? | Parent branch FK (self-referencing hierarchy). |
financialReport | Boolean | Whether the branch has an independent P&L (default true). |
nonWorkingDays | Json? | Array of day-of-week integers, e.g. [0, 6] for Saturday/Sunday. |
nationCode | String | FK to Nation (country). |
currencyCode | String | FK to Currency (branch default currency). |
Unique constraint: [tenantId, code]
Maker-Checker: Yes.
Department
Table: remoteEaze_departments
Purpose: Organizational departments/units with hierarchy. Used for access control (deptUnitRestrict on Product) and user assignment.
| Key Field | Type | Description |
|---|---|---|
code | String | Format: "DDDD-UUUU" (department-unit). |
description | String | Department/unit name. |
reportingToId | String? | Parent department FK (self-referencing hierarchy). |
Unique constraint: [tenantId, code]
CostCentre
Table: remoteEaze_cost_centres
Purpose: Cost allocation centres for financial reporting and user assignment.
| Key Field | Type | Description |
|---|---|---|
code | String | Cost centre code. |
centreName | String | Display name. |
description | String? | Optional description. |
Unique constraint: [tenantId, code]
TenantCurrency
Table: remoteEaze_tenant_currencies
Purpose: Currencies enabled per tenant with foreign exchange rates. One currency per tenant is marked as the base currency.
| Key Field | Type | Description |
|---|---|---|
currencyCode | String | FK to Currency (ISO 4217). |
buyRate | Decimal(20,4) | Buying rate. |
sellRate | Decimal(20,4) | Selling rate. |
midRate | Decimal(20,4) | Mid-market rate. |
isBaseCurrency | Boolean | Whether this is the tenant's base (home) currency. |
Unique constraint: [tenantId, currencyCode]
C. Authentication & Access Control
RemoteEaze_userProfile
Table: remoteEaze_userProfile
Purpose: User accounts. Integrates with Better-Auth for authentication while carrying extensive business fields for the financial system. Users can be INTERNAL (staff), EXTERNAL (field agents), or SYSTEM (super admins).
| Key Field | Type | Description |
|---|---|---|
name / email | String | Better-Auth required fields. |
emailVerified | Boolean | Whether email has been verified. |
mustChangePassword | Boolean | Force password change on next login. |
passwordLastChangedAt | DateTime? | For enforcing passwordChangeInterval from License. |
tenantId | String | "SYSTEM" for super admins, licenseId for org users. |
staffNumber | String? | Format: "STF-2025-001". Required for INTERNAL users. |
userType | UserType | INTERNAL, EXTERNAL, or SYSTEM. |
roleId | String | FK to Role. Determines permissions. |
branchId | String? | Current branch assignment. Optional for SYSTEM users. |
branchRestrict | Json? | Array of branch IDs the user can access. |
dataAccessScope | DataAccessScope | SYSTEM, ORGANIZATION, BRANCH, or SELF. Controls data visibility. |
reportingToId | String? | Self-referencing hierarchy (manager). |
languageCode | String | Default "EN". |
Unique constraints: [email], [tenantId, staffNumber]
RemoteEaze_userSession
Table: remoteEaze_userSession
Purpose: Active user sessions managed by Better-Auth. Stores session tokens, expiry, and client context (IP, user agent).
RemoteEaze_authAccount
Table: remoteEaze_authAccount
Purpose: Authentication provider accounts (Better-Auth). Links users to credential or OAuth providers with access/refresh tokens.
RemoteEaze_accountVerification
Table: remoteEaze_accountVerification
Purpose: Email/phone verification tokens with expiry. Used during account verification flows.
Role
Table: remoteEaze_roles
Purpose: Named roles per tenant used for RBAC. Each role has associated permissions, transaction approval thresholds, and approval rules.
| Key Field | Type | Description |
|---|---|---|
slug | String | Machine key, e.g. "BRANCH_MANAGER", "TELLER". |
name | String | Display name, e.g. "Branch Manager". |
isActive | Boolean | Whether the role is active. |
Unique constraints: [tenantId, slug], [tenantId, name]
Maker-Checker: Yes.
Relations: users (RemoteEaze_userProfile[]), permissions (PermissionMatrix[]), thresholds (TransactionApproval[]), permissionRules (TransactionApprovalRule[]).
PermissionMatrix
Table: remoteEaze_permission_matrix
Purpose: Maps a Role to an entity type (e.g. "transfer", "customer"), grouping the granular permission actions for that combination.
| Key Field | Type | Description |
|---|---|---|
roleId | String | FK to Role. |
entityType | String | The entity type this permission set applies to. |
Unique constraint: [tenantId, roleId, entityType]
Relations: actions (PermissionAction[]).
PermissionAction
Table: remoteEaze_permission_actions
Purpose: Individual permission flags within a PermissionMatrix. Each action (read, write, approve_l1, etc.) can be allowed or denied, optionally with a required approval level.
| Key Field | Type | Description |
|---|---|---|
permissionMatrixId | String | FK to PermissionMatrix. |
action | String | Action name: "read", "write", "approve_l1", etc. |
allowed | Boolean | Whether the action is permitted. |
requiredLevel | Int? | Approval level required (if applicable). |
Unique constraint: [permissionMatrixId, action]
TransactionApproval
Table: remoteEaze_transaction_approvals
Purpose: Amount-based approval thresholds per role. Defines what a role can create or approve based on transaction amount ranges and currency.
| Key Field | Type | Description |
|---|---|---|
roleId | String | FK to Role. |
entityType | String | Entity type (e.g. "transfer"). |
fieldName | String | The field being evaluated (e.g. "amount"). |
minAmount / maxAmount | Decimal(20,2) | Amount range (maxAmount null = unlimited). |
currency | String | ISO currency code. Strict match required. |
requiredLevels | Int? | Number of approval levels needed. |
canCreate / canApprove_l1 / canApprove_l2 / canApprove_l3 | Boolean | Permission flags per approval level. |
TransactionApprovalRule
Table: remoteEaze_transaction_approval_rules
Purpose: Conditional rules that override or extend base approval thresholds. Two types: PERMISSION (role-specific conditional overrides) and VALIDATION (global blocking rules that apply to everyone).
| Key Field | Type | Description |
|---|---|---|
ruleName | String | Human-readable rule name. |
ruleType | RuleType | PERMISSION (role-specific) or VALIDATION (global block). |
entityType | String | Entity type the rule applies to. |
roleId | String? | FK to Role. Null = global validation rule. |
priority | Int | Evaluation order (lower = first). |
validationMessage | String? | Error message shown when validation rule blocks. |
Relations: conditions (TransactionApprovalCondition[]).
TransactionApprovalCondition
Table: remoteEaze_transaction_approval_conditions
Purpose: Individual conditions within an approval rule. Uses field-level operators to evaluate transaction data.
| Key Field | Type | Description |
|---|---|---|
ruleId | String | FK to TransactionApprovalRule. |
fieldName | String | Field to evaluate, e.g. "transCode". |
fieldOperation | FieldOp | Operator: EQ, NE, GT, LT, IN, NOT_IN, CONTAINS. |
fieldValue | String | Value to compare against. |
logicalOp | LogicalOp? | How to combine with other conditions: AND or OR. |
D. Global Reference Data
These tables have no tenantId. They are system-wide, read-only for tenants, and typically seeded from ISO standards.
Nation
Table: remoteEaze_nations
Purpose: ISO 3166 country reference. Used for branch location, customer nationality/residence, and identity type scoping.
| Key Field | Type | Description |
|---|---|---|
code | String @id | ISO 3166-1 alpha-2 (e.g. "KE"). |
alpha3Code | String @unique | ISO 3166-1 alpha-3 (e.g. "KEN"). |
numericCode | String @unique | ISO 3166-1 numeric (e.g. "404"). |
name | String | Country name. |
dialCode | String? | Phone dial code, e.g. "+254". |
Relations: branches, sectors, identityTypes.
Language
Table: remoteEaze_languages
Purpose: ISO 639 language reference. Used for user language preferences.
| Key Field | Type | Description |
|---|---|---|
code | String @id | ISO 639-1 (e.g. "EN", "SW"). |
alpha3Code | String @unique | ISO 639-2 (e.g. "eng"). |
name | String | Language name. |
Currency
Table: remoteEaze_currencies
Purpose: ISO 4217 currency reference. Critical for banking math -- the decimals field determines rounding precision across the system.
| Key Field | Type | Description |
|---|---|---|
code | String @id | ISO 4217 (e.g. "KES", "USD"). |
numericCode | String @unique | ISO 4217 numeric (e.g. "404"). |
name | String | Currency name. |
decimals | Int | Decimal places for this currency (default 2). Drives all financial calculations. |
Relations: tenantConfigs, branches, accountConditions, commissionTypes, commissionBands, accounts, facilities, facilityCollaterals, collateralValuations.
Sector
Table: remoteEaze_sectors
Purpose: Economic sectors per country, defined by regulators. Used for customer and account classification (regulatory reporting).
| Key Field | Type | Description |
|---|---|---|
name | String | Sector name. |
countryCode | String | FK to Nation. |
code | String | Regulator-assigned code (e.g. "1000"). |
Unique constraint: [countryCode, code]
Relations: industries, customers, accounts.
Industry
Table: remoteEaze_industries
Purpose: Industries within sectors. Finer-grained classification for regulatory reporting.
| Key Field | Type | Description |
|---|---|---|
name | String | Industry name. |
sectorId | String | FK to Sector. |
code | String | Regulator-assigned code. |
Unique constraint: [sectorId, code]
Relations: customers, accounts.
E. Tenant Reference Data (Lookup Tables)
These are simple code + description lookup tables scoped by tenantId. They power dropdown menus across the UI and enforce consistent categorization. All follow the same pattern:
| Field | Type | Description |
|---|---|---|
code | String | Machine-readable identifier (unique per tenant). |
description | String | Human-readable display name. |
Unique constraint (all): [tenantId, code]
Complex Configuration Tables
| Table | DB Name | Purpose | Extra Fields |
|---|---|---|---|
| IdentityType | remoteEaze_identity_types | ID document types (passport, national ID, etc.) | countryCode (FK Nation), mandatoryFields (Json), formatRegex, integratorApi |
| AccountStatus | remoteEaze_account_statuses | Account operational statuses (ACTIVE, DORMANT, FROZEN, etc.) | allowDebit, allowCredit, allowCobTrans (boolean flags controlling what transactions are permitted) |
Simple Lookup Tables
| Table | DB Name | Typical Codes |
|---|---|---|
| CustomerType | remoteEaze_customer_types | "INDIVIDUAL", "CORPORATE" |
| CustomerRating | remoteEaze_customer_ratings | "HIGH_RISK", "LOW_RISK" |
| Title | remoteEaze_titles | "MR", "DR", "PROF" |
| Gender | remoteEaze_genders | "M", "F", "O" |
| MaritalStatus | remoteEaze_marital_statuses | "SINGLE", "MARRIED" |
| SourceFunds | remoteEaze_source_funds | "NGO", "GOVERNMENT" (org-level, not customer-level) |
| LoanPurpose | remoteEaze_loan_purposes | "AGRICULTURE", "SCHOOL_FEES" |
| CollateralType | remoteEaze_collateral_types | "LOGBOOK", "TITLE_DEED" |
| DocumentType | remoteEaze_document_types | "PHOTO", "PASSPORT_COPY", "MANDATE", "BOARD_RESOLUTION" |
| AccountType | remoteEaze_account_types | "INDIVIDUAL_SAVINGS", "CORPORATE_CURRENT", "SME_LOAN", "FIXED_DEPOSIT" |
F. Entity Onboarding (CRM)
Customer
Table: remoteEaze_customers
Purpose: Core customer entity supporting both Individual and Corporate customer types. Carries demographics, contact info, KYC data, compliance fields, and complex JSON fields for identities, directors, shareholders, and documents.
| Key Field | Type | Description |
|---|---|---|
customerNumber | String | 10-digit auto-generated via Sequence (unique per tenant). |
customerTypeId | String | FK to CustomerType ("INDIVIDUAL" or "CORPORATE"). |
displayName | String | Computed: "John Doe" for individuals, "Acme Corp" for corporates. |
Individual-specific fields: firstName, surname, titleCode, genderCode, maritalStatusCode, dateOfBirth, placeOfBirth, countryOfBirth.
Corporate-specific fields: corporateName, dateOfIncorporation, placeOfIncorporation, countryOfIncorporation.
Creation rules:
- At least one entry in
identitiesis always required on creation (both Individual and Corporate). - For Corporate: at least one Director, one Shareholder, and one Contact Person are required.
- Total shareholder percentage across all shareholders cannot exceed 100%.
- Identity
refis validated against theformatRegexdefined in the matchingIdentityTyperecord. customerTypeIdcannot be changed after creation.
Contact: email, phone, addressPhysical, addressHome, addressPostal.
Classification: nationality, residence, sectorId, industryId, customerRatingCode.
Relationships: relationOfficerId (FK to User), agentId (FK to Agent), branchId (FK to Branch).
Complex JSON fields:
identities-- Array:[{ typeCode, ref, issueDate, expiryDate }]directors-- Array (corporate):[{ name, address, email, phone, idTypeCode, idRef, memo }]shareholders-- Array (corporate):[{ name, address, email, phone, idTypeCode, idRef, sharePercentage }]contacts-- Array (corporate):[{ name, email, phone, role }]nextOfKin-- Array:[{ name, address, relationship, idTypeCode, idRef, idIssueDate, idExpiryDate }]documents-- Array:[{ typeCode, ref, imageUrl, uploadDate, expiryDate }]
Credit: totalCreditLimit (Decimal) -- Max total facility exposure allowed for this customer.
Dual status:
recordStatus(RecordStatus) -- Maker-checker workflow state.customerStatus(CustomerStatus) -- Operational state: ACTIVE, PENDING_KYC, BLOCKED, DECEASED.statusMemo/statusDate-- Reason and timestamp for last customerStatus change.
Relations: accounts, mandates (as signatory), facilities.
Maker-Checker: Yes.
Agent
Table: remoteEaze_agents
Purpose: Field agents who operate on behalf of the organization, typically for mobile banking or outreach. Each agent is linked to exactly one user account and one branch. Personal information (name, email, phone) comes from the linked User record (single source of truth).
| Key Field | Type | Description |
|---|---|---|
agentNumber | String | Auto-generated from branch code: {CNA}-{RCC}-{BBB}-{AAAA}. AAAA is per-branch sequence (0001-9999). Example: KCB-KEN-001-0001. |
userId | String | FK to User (one-to-one). Agent must have a user account. Name/email/phone pulled from User. branchId and userId cannot be changed after creation. |
agentAccountId | String? @unique | FK to Account. Null until agent's operating account is created and linked via the linkAccount action. |
branchId | String | FK to Branch (home/recruiting branch). Determines the agent number prefix and cannot be changed. |
agentAddress | String? | Work address (can differ from User's personal address). |
startTime / endTime | String? | Working hours in 24-hour format, e.g. "08:00" / "17:00". End time must be after start time. |
geoLockEnabled | Boolean | Whether geo-restriction is enabled. If true, allowedGeoZone is required. |
allowedGeoZone | String? | Permitted working zone. Format: lat,lng,radius_meters. |
currentLocation | String? | Last known position. Format: lat,lng. System-tracked when geo-lock enabled. |
currentLocationAt | DateTime? | When location was last captured. |
statusMemo | String? | Reason for status change. Required (min 5 chars) when setting agentStatus to SUSPENDED or TERMINATED. |
Dual status:
recordStatus(RecordStatus) — Maker-checker workflow state.agentStatus(AgentStatus) — Operational state: ACTIVE, SUSPENDED, TERMINATED.
Working config updates: An AUTHORIZED agent's working hours and geo-fencing can be updated directly (no maker-checker cycle) via the updateConfig action.
Relations: customers (managed), managedAccounts.
Maker-Checker: Yes.
Profile fields removed: agentName, agentEmail, and agentPhones have been removed from the Agent model. These values are now sourced from the linked User record to maintain a single source of truth.
G. Financial Engine (General Ledger)
Product
Table: remoteEaze_products
Purpose: Chart of Accounts (GL codes). Each product represents a general ledger account category. Products are either customer-facing contracts (savings, loans) or internal GL accounts (expense, income tracking).
| Key Field | Type | Description |
|---|---|---|
productCode | String | Auto-generated: PP-NNNNN. Series by type: ASSET (AS-10000..29999), LIABILITY (LI-30000..49999), INCOME (IN-50000..69999), EXPENSE (EX-70000..79999). |
productName | String | Display name. |
productType | ProductType | ASSET, LIABILITY, INCOME, EXPENSE, CONTINGENT_ASSET, CONTINGENT_LIABILITY. |
isContractProduct | Boolean | true = customer-facing (savings, loans). false = internal GL. |
deptUnitRestrict | String[] | Departments restricted from using this product during transaction posting. |
branchRestrict | String[] | Branches allowed to use this product. Empty = unrestricted. ProductBalance rows are created only for these branches on authorization. |
Relations: balances (ProductBalance[]), accounts, facilityClassProducts, activityRules, and various GL account link relations from AccountCondition and CommissionType.
Maker-Checker: Yes.
ProductBalance
Table: remoteEaze_product_balances
Purpose: System-managed ledger balances per product per branch. Tracks Year-to-Date, Month-to-Date, and Day-level open balances and debit/credit movements. Created automatically when a Product is authorized or a new Branch is created.
| Key Field | Type | Description |
|---|---|---|
productId / branchId | String | Composite key identifying one balance row. |
ytdOpenBalance / ytdDebitMvmt / ytdCreditMvmt | Decimal(20,4) | Year-to-date tracking. |
mtdOpenBalance / mtdDebitMvmt / mtdCreditMvmt | Decimal(20,4) | Month-to-date tracking. |
dayOpenBalance / dayDebitMvmt / dayCreditMvmt | Decimal(20,4) | Daily tracking (reset by batch job). |
Unique constraint: [tenantId, productId, branchId]
Not user-editable. Read-only via API. Updated by the transaction posting engine and batch jobs.
TransCode
Table: remoteEaze_trans_codes
Purpose: Transaction codes that define posting behavior. Referenced by CommissionType to link fee types to their transaction posting rules.
| Key Field | Type | Description |
|---|---|---|
code | String | Transaction code, e.g. "1000", "90901". |
description | String | Human-readable description. |
debitCredit | TransDebitCredit | DEBIT, CREDIT, or BOTH. |
turnOverCharge | Boolean | Whether this code triggers turnover-based charges. |
Unique constraint: [tenantId, code]
Maker-Checker: Yes.
H. Product Rules Engine
AccountCondition (Interest Engine)
Table: remoteEaze_account_conditions
Purpose: Interest calculation configuration with temporal versioning. Defines how debit interest (customer pays) and credit interest (customer earns) are calculated, including tiered rates, day-count conventions, frequency settings, GL account links, and tax configuration.
| Key Field | Type | Description |
|---|---|---|
code | String | Condition code. Must be uppercase alphanumeric with dashes only, e.g. "SAV-STD-01". Cannot be changed after creation. |
name | String | Display name (3–100 chars). |
effectiveFrom | DateTime @db.Date | Start of validity. Must be a valid date. |
effectiveTo | DateTime? | End of validity. Null = currently active. Must be after effectiveFrom if set. |
currencyCode | String | FK to Currency. Cannot be changed after creation. |
interestBasis | InterestBasis | Day-count convention: ACTUAL_360, ACTUAL_364, ACTUAL_365, ACTUAL_ACTUAL, THIRTY_360, THIRTY_E_360. Default: ACTUAL_365. |
debitCalcMethod / creditCalcMethod | InterestCalcMethod | FLAT_RATE, LEVEL (each tier applies to portion in range), or BAND (entire balance uses rate of matching tier). |
balanceType | BalanceType | Balance figure used for calculation: DAILY, AVERAGE_DAILY, LOWEST_MONTHLY, HIGHEST_MONTHLY, END_OF_PERIOD. |
accrualFrequency | AccrualFrequency | DAILY or MONTHLY. Must be at least as frequent as postingFrequency. |
postingFrequency | PostingFrequency | MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY. |
capitalizationFrequency | CapitalizationFrequency | NEVER, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY. Must be less frequent than or equal to postingFrequency. |
debitTiers / creditTiers | Json? | Tiered rate arrays: [{ minAmount, maxAmount, rate }]. Only the last tier may have null maxAmount. No duplicate minAmount values. |
debitInterestMinimum / debitInterestMaximum | Decimal? | Min/max interest to charge per period. Minimum cannot exceed maximum. |
debitInterestDeMinimis | Decimal? | Do not charge if calculated interest is below this threshold. |
debitAllowCompound / creditAllowCompound | Boolean | Whether compound interest is allowed. |
debitExpenseAccountId | String? | FK to Product of type EXPENSE (debit interest expense account). |
debitLiabilityAccountId | String? | FK to Product of type LIABILITY (accrued interest payable). |
creditIncomeAccountId | String? | FK to Product of type INCOME (credit interest income account). |
taxAccountId | String? | FK to Product of type LIABILITY (tax payable). |
debitTaxRate / creditTaxRate | Decimal? | Tax rates (max 4 decimal places, cannot exceed 100%). Debit = excise duty, Credit = withholding tax. |
debitTaxType / creditTaxType | TaxType? | INCLUSIVE or EXCLUSIVE. Required if the corresponding tax rate is set. |
capitalizeFees | Boolean | Whether to capitalize fees. If true, feesCapitalizationDays is required. |
interestCharges | Json? | Fee commission types to apply on interest events: { onDebitPosting, onDebitCapitalization, onCreditPosting }. |
scheduleConfig | Json? | Posting schedule config: { postingDayOfMonth, useWorkingDay, rollForward }. |
Unique constraint: [tenantId, code, effectiveFrom] (allows temporal versioning — multiple versions of the same code can coexist with different effective dates).
Supersede operation: Creates a new CAPTURED version of an existing open-ended AUTHORIZED condition. The new version's effectiveFrom must be at least tomorrow. The current version's effectiveTo is automatically set to the day before the new effectiveFrom. All product links from the current version are copied to the new version atomically.
Interest preview: AUTHORIZED conditions support a preview endpoint that calculates interest for a given balance and number of days, with optional tax calculation.
Maker-Checker: Yes. A condition code cannot be reused (same code + effectiveFrom combination). Use supersede instead of creating a new record with the same code.
ProductAccountCondition
Table: remoteEaze_product_account_conditions
Purpose: Junction table linking Products to AccountConditions. Only CONTRACT products (customer-facing) can be linked. Unlinking is prevented if active AUTHORIZED accounts exist using that combination.
Unique constraint: [productId, accountConditionId]
CommissionType (Fee Engine)
Table: remoteEaze_commission_types
Purpose: Fee and commission definitions. Each commission type has GL account links, a transaction code, tax configuration, and calculation settings. Supports FLAT, PERCENTAGE, and FORMULA calculation bases.
| Key Field | Type | Description |
|---|---|---|
code | String | Commission code, e.g. "STMT-FEE", "OD-SETUP". |
currencyCode | String | FK to Currency. |
incomeAccountId | String | FK to Product (INCOME type). |
taxAccountId | String? | FK to Product (LIABILITY type, for tax collection). |
transCodeId | String | FK to TransCode. |
calculationBasis | CalculationBasis | FLAT, PERCENTAGE, or FORMULA. |
bandCalcType | BandCalcType | LEVEL (tiered) or BAND (flat by bracket). |
externalCalcApi | String? | URL for FORMULA basis (external calculation service). |
taxType / taxRate | Various | Tax configuration (e.g. 16% VAT). |
chargeAsInterest | Boolean | Whether to include in APR calculation (regulatory). |
Maker-Checker: Yes. Must have at least one band before submission.
CommissionBand
Table: remoteEaze_commission_bands
Purpose: Tiered fee brackets within a CommissionType. Defines amount ranges with either flat fees or percentage-based charges.
| Key Field | Type | Description |
|---|---|---|
commissionTypeId | String | FK to CommissionType. |
currencyCode | String | Must match parent CommissionType currency. |
minAmount / maxAmount | Decimal(20,4) | Amount range (maxAmount null = unlimited). |
chargeAmount | Decimal? | Flat fee (mutually exclusive with chargePercentage). |
chargePercentage | Decimal? | Percentage rate. |
minCharge / maxCharge | Decimal? | Floor/ceiling for percentage-based charges. |
Unique constraint: [commissionTypeId, currencyCode, minAmount]
Bands are validated as a set: contiguous ranges, no gaps, no overlaps.
FacilityClass
Table: remoteEaze_facility_classes
Purpose: Credit facility templates. Defines whether facilities are revolving (overdraft) or term (fixed loan), and what percentage of the limit is available for utilization.
| Key Field | Type | Description |
|---|---|---|
code | String | Class code, e.g. "OD-SECURED", "TERM-LOAN". |
isRevolving | Boolean | true = overdraft (reusable limit), false = term loan (draw once). |
availabilityPercent | Decimal(5,2) | Percentage of approved limit available (default 100%). |
Maker-Checker: Yes.
Relations: eligibleProducts (FacilityClassProduct[]), facilities (Facility[]).
FacilityClassProduct
Table: remoteEaze_facility_class_products
Purpose: Junction table linking FacilityClasses to eligible Products. Only CONTRACT products can be linked. Unlinking prevented if active facilities exist.
Unique constraint: [facilityClassId, productId]
ActivityStatusRule
Table: remoteEaze_activity_status_rules
Purpose: Lifecycle automation rules for account dormancy management. Defines conditions that trigger automatic status changes on accounts (e.g. mark as DORMANT after 90 days of inactivity). Includes cycle detection to prevent circular status transitions.
| Key Field | Type | Description |
|---|---|---|
name | String | Rule name. |
ruleType | ActivityRuleType | DAYS_SINCE_LAST_DEBIT, DAYS_SINCE_LAST_CREDIT, DAYS_SINCE_LAST_TRANSACTION, BALANCE_BELOW_THRESHOLD, BALANCE_IS_ZERO, CONSECUTIVE_MONTHS_INACTIVE. |
thresholdDays | Int? | For DAYS_SINCE_* rules. |
thresholdAmount | Decimal? | For BALANCE_* rules. |
targetAccountStatusId | String | FK to AccountStatus. The status to assign when the rule triggers. |
productId | String? | FK to Product. Null = applies to all products. |
priority | Int | Evaluation order (lower = first). |
Maker-Checker: Yes.
WorkDayYear
Table: remoteEaze_work_day_years
Purpose: Business calendar year definition. Tracks the current, last, and next working days. Used for interest calculations, business date determination, and transaction scheduling.
| Key Field | Type | Description |
|---|---|---|
year | Int | Calendar year (e.g. 2025). |
currentWorkingDay | DateTime @db.Date | Today's business date. |
lastWorkingDay | DateTime @db.Date | Previous business date. |
nextWorkingDay | DateTime @db.Date | Next business date. |
Unique constraint: [tenantId, year]
Maker-Checker: Yes.
WorkDayMonth
Table: remoteEaze_work_day_months
Purpose: Monthly breakdown within a WorkDayYear. Defines which days are weekends and which are public holidays for each month.
| Key Field | Type | Description |
|---|---|---|
workDayYearId | String | FK to WorkDayYear. |
month | Int | Month number (1-12). |
weekendDays | Int[] | Day-of-week integers, e.g. [0, 6] (Sunday, Saturday). |
publicHolidayDays | Int[] | Day-of-month integers, e.g. [1, 25] (1st and 25th). |
Unique constraint: [workDayYearId, month]
Months can only be modified when the parent year is in CAPTURED or REJECTED status.
I. Account & Credit Management
Account
Table: remoteEaze_accounts
Purpose: The core financial account entity. Can be customer-facing (savings, loans, fixed deposits) or internal GL accounts. Carries six balance fields, interest state, schedule state, activity tracking, and services/notifications configuration.
| Key Field | Type | Description |
|---|---|---|
accountNumber | String | Auto-generated via Sequence. Format: ACC-{8-digit-zero-padded-counter}, e.g. ACC-00000001. Unique per tenant. |
accountName | String | Computed on create: {customerDisplayName} {accountType.description} {currencyCode}. For agent/internal accounts, product name is used in place of customer name. |
customerId | String? | FK to Customer. Required for contract products unless isAgentAccount = true. Null for internal GL accounts. Customer must be AUTHORIZED at creation time. |
isAgentAccount | Boolean | true = this is an agent operating account (float/commissions). Mutually exclusive with customerId. |
productId | String | FK to Product. Must be AUTHORIZED. For contract products, determines whether customer/agent is required. Cannot be changed after creation. |
accountTypeId | String | FK to AccountType. |
currencyCode | String | FK to Currency. Cannot be changed after creation. |
startDate / endDate | DateTime? | Validity period. Typically required for term products (loans, fixed deposits). endDate must be after startDate. |
dateOpened | DateTime | Account opening business date. Set automatically on creation. |
accountConditionId | String? | FK to AccountCondition (interest rules). Must be AUTHORIZED if provided. |
accountStatusId | String | FK to AccountStatus (current operational status). |
activityStatusId | String? | FK to AccountStatus. Automated by the ActivityStatusRule engine — not manually set. |
signingRule | SigningRule? | Account-level signing policy: ANY_ONE, ALL_MUST_SIGN, TWO_OF_THREE, MAJORITY. |
facilityReference | String? | Links to Facility for overdraft accounts. |
branchId | String | FK to Branch. Required. |
relationOfficerId | String? | FK to User (Relationship Officer). User must belong to the same tenant. |
agentId | String? | FK to Agent. Agent must be AUTHORIZED if provided. |
sectorId / industryId | String? | FK to Sector/Industry. Inherited from the customer record; can be overridden per account. |
accountEmail / accountPhone | String? | Contact information specific to this account (e.g. for joint or corporate accounts). |
uniqueQRCode | String? | Auto-generated on create. Format: QR-ACC-{accountNumber}. |
Contract product rules:
isContractProduct = trueon the product → eithercustomerIdorisAgentAccount = trueis required (not both).isContractProduct = false(internal GL) →customerIdandisAgentAccountmust both be absent/false.
Operational status update: An AUTHORIZED account's accountStatusId can be changed directly (no maker-checker). Restrictive statuses (BLOCKED, CLOSED, DORMANT, FROZEN) require a statusMemo (min 5 characters).
Balance fields:
| Field | Description |
|---|---|
unclearOnlineBalance | Current balance including pending transactions. |
clearedOnlineBalance | Current balance excluding pending. |
availableOnlineBalance | Cleared + overdraft limit. |
unclearOpenBalance | Start-of-day including pending. |
clearedOpenBalance | Start-of-day excluding pending. |
availableOpenBalance | Start-of-day + overdraft. |
Interest state fields: lastDrInterestAccrDate, lastDrInterestCapDate, lastCrInterestAccrDate, lastCrInterestCapDate, lastDrInterestCapAmt, lastCrInterestCapAmt, currAccrDrInterAmt, currAccrCrInterAmt, plus YTD and grand-total interest/charge amounts.
Schedule state: scheduleDefined, scheduleFrequency, nextScheduleDate, nextScheduleAmount, lastScheduleDate, lastScheduleAmount. scheduleFrequency is required when scheduleDefined = true.
Activity tracking: lastTxnDate, lastCreditDate, lastDebitDate (used by ActivityStatusRule evaluation).
Services: subscribedServices (DEBITCARD, CREDITCARD, POS, INTERNET), notificationServices (EMAIL, SMS).
Maker-Checker: Yes.
Auto-mandate on authorization: When an account for an Individual customer reaches AUTHORIZED status, the system automatically creates a PRIMARY_HOLDER mandate using the customer's name, contact details, and first identity document. This happens atomically in the same transaction as the status change. Corporate accounts do not get an auto-mandate.
AccountMandate
Table: remoteEaze_account_mandates
Purpose: Signing authority records per account. Defines who is authorized to sign for transactions, their transaction limits, and validity period. SigningRule (how mandates must be collectively fulfilled) lives on the Account, not the mandate.
| Key Field | Type | Description |
|---|---|---|
accountId | String | FK to Account. Account must be AUTHORIZED. |
signatoryName | String | Full name of the signatory (min 2 chars). |
signatoryType | SignatoryType | PRIMARY_HOLDER, JOINT_HOLDER, POWER_OF_ATTORNEY, AUTHORIZED_SIGNATORY, DIRECTOR. |
signatoryCustomerId | String? | FK to Customer. Optional link if the signatory is also an existing customer record. |
transactionLimit | Decimal? | Max amount this signatory can authorize alone. |
effectiveFrom | DateTime @db.Date | Start of validity. effectiveTo must be after effectiveFrom if set. |
effectiveTo | DateTime? | End of validity. Null = indefinite. |
isActive | Boolean | Can be deactivated without deletion (default true). |
email / phone | String? | Contact information for the signatory. |
idTypeCode / idRef | String? | Identity document type code and reference number. |
idIssueDate / idExpiryDate | DateTime? | Identity document dates. |
additionalAttributes | Json? | Extra identity fields driven by the IdentityType.mandatoryFields config. |
Rules:
- Can only be created on AUTHORIZED accounts.
- If
signatoryCustomerIdis provided, the customer must exist in the same tenant. - The
signingRulefor collective authorization is set on the Account (Account.signingRule), not here.
Auto-creation: Two paths create a PRIMARY_HOLDER mandate automatically:
- Individual customer account reaches AUTHORIZED — mandate is created with the customer's
displayName, contact details, and first identity document, atomically in the same transaction. - Agent's account is linked via
linkAccount— mandate is created using the agent's User record (user.name,user.email,user.userPhoneOfficial). NosignatoryCustomerIdis set for agent mandates.
AccountStatement
Table: remoteEaze_account_statements
Purpose: Statement delivery configuration per account. Defines how often statements are generated and how they are delivered. Tracks the last generation date and balance.
| Key Field | Type | Description |
|---|---|---|
accountId | String | FK to Account. Account must be AUTHORIZED. |
statementFreq | StatementFrequency | DAILY, WEEKLY, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY. |
deliveryMethod | StatementDelivery | EMAIL, PHYSICAL, or BOTH. |
lastStatementDate | DateTime? | Business date of the last generated statement (system-managed). |
lastStatementBal | Decimal? | Account balance at the time of the last statement (system-managed). |
Rules: Can only be created for AUTHORIZED accounts. An account can have one statement configuration.
Facility
Table: remoteEaze_facilities
Purpose: Credit facilities (overdraft lines or term loans) granted to customers. Each facility is based on a FacilityClass template, has an approved amount, and tracks expiry/review dates.
| Key Field | Type | Description |
|---|---|---|
facilityRef | String | Computed: {customerNumber}.{facilityClassCode}. |
customerId | String | FK to Customer. Customer must be AUTHORIZED and ACTIVE. |
facilityClassId | String | FK to FacilityClass (template). Must be AUTHORIZED. |
currencyCode | String | FK to Currency. |
amountApproved | Decimal(20,4) | Total credit limit approved. Checked against customer's totalCreditLimit. |
amountAdvised | Decimal(20,4) | Amount communicated to customer. Must not exceed amountApproved. |
expiryDate | DateTime | Facility expiry date. |
reviewFreq | Int | Days before expiry to trigger review alert (default 30). |
expiryMode | ExpiryMode | MANUAL or AUTOMATIC renewal. |
revolvingLimit | Boolean? | Override FacilityClass setting. Null = use class default. |
availMarker | AvailMarker | YES = available for utilization, NO = suspended. |
Dual status: recordStatus (workflow) + facilityStatus (ACTIVE, EXPIRED, SUSPENDED, CANCELLED).
Maker-Checker: Yes. dateApproved set automatically on AUTHORIZED.
FacilityCollateral
Table: remoteEaze_facility_collaterals
Purpose: Collateral pledged against a facility. Carries current valuation and links to a CollateralType.
| Key Field | Type | Description |
|---|---|---|
facilityId | String | FK to Facility. |
collateralTypeId | String | FK to CollateralType. |
collateralRef | String | External reference (title deed, logbook, certificate). |
currencyCode | String | FK to Currency. |
marketValue / forcedSaleValue | Decimal(20,4) | Current valuation. Updated when new valuations are added. |
lastValuationDate | DateTime | Date of latest valuation. |
expiryDate | DateTime? | For time-limited collateral (e.g. fixed deposit receipts). |
CollateralValuation
Table: remoteEaze_collateral_valuations
Purpose: Immutable valuation history for collateral. Each record represents one professional valuation. On creation, the parent FacilityCollateral is updated with the latest values atomically.
| Key Field | Type | Description |
|---|---|---|
facilityCollateralId | String | FK to FacilityCollateral. |
valuationDate | DateTime | Date of valuation. |
currencyCode | String | FK to Currency. |
marketValue / forcedSaleValue | Decimal(20,4) | Assessed values. |
valuerName | String | Name of valuer/firm. |
valuerReference | String? | Valuer's report reference number. |
valuationMethod | String? | e.g. "MARKET_COMPARISON", "INCOME_APPROACH". |
Immutable: No updates. Corrections via soft delete + new record.
FacilityAccount
Table: remoteEaze_facility_accounts
Purpose: Junction table tracking which accounts draw from which facilities and how much. Enforces allocation limits: total allocation across all linked accounts cannot exceed the facility's amountAdvised.
| Key Field | Type | Description |
|---|---|---|
facilityId / accountId | String | Junction keys. Both must be AUTHORIZED. |
allocationAmount | Decimal(20,4) | Portion of facility reserved for this account. |
amtUtilized | Decimal(20,4) | Cumulative drawn amount. |
amtOutstanding | Decimal(20,4) | Current outstanding balance. |
Unique constraint: [facilityId, accountId]
J. Third-Party Delivery
ThirdPartySystem
Table: remoteEaze_third_party_systems
Purpose: Registry of external systems (core banking, ERPs, payment gateways) that the platform can deliver data to. Stores connection details, authentication credentials (encrypted at rest), and default retry/timeout behaviour. Uses maker-checker workflow.
| Key Field | Type | Description |
|---|---|---|
code | String | Short unique identifier, e.g. T24, SAP, FLEXCUBE. Unique per tenant. Immutable after creation. |
name | String | Human-readable name, e.g. "Temenos T24 Core Banking". |
description | String? | Optional description. |
transportFormat | TransportFormat | Default serialization format: REST_JSON or REST_XML. |
baseUrl | String | Root API address, e.g. https://t24.bank.com/api. |
authType | AuthType | Authentication method: NONE, BASIC, BEARER, API_KEY, OAUTH2. |
authConfig | String? | Encrypted JSON containing credentials. Decrypted only at delivery time inside the queue processor. Never returned via API. |
defaultHeaders | Json? | Default HTTP headers merged into all outgoing requests. |
timeoutMs | Int | HTTP timeout in milliseconds (default: 30000). |
retryLimit | Int | Maximum retry attempts for failed deliveries (default: 3). |
retryBackoffMs | Int | Delay between retries in milliseconds (default: 1000). |
isActive | Boolean | Whether this system is enabled for deliveries. |
Unique constraint: [tenantId, code]
ThirdPartyMapping
Table: remoteEaze_third_party_mappings
Purpose: Junction table mapping internal entity records to their identifiers in external systems. For example, a customer cust_abc123 might be CUS001 in T24. Simple CRUD — no maker-checker workflow.
| Key Field | Type | Description |
|---|---|---|
entityType | String | What kind of record: customer, account, transaction, etc. |
entityId | String | The record's internal ID. |
entityDisplayName | String? | Denormalized human-readable label, e.g. "CUS001 — John Doe". Captured at creation time. |
systemId | String | FK to ThirdPartySystem. Which external system this mapping is for. |
externalKey | String | Slot name for the external identifier, e.g. PRIMARY, T24_ACCOUNT, SAP_BP_NUMBER. |
externalValue | String | The actual value in the external system, e.g. CUS001, 1234567. |
valueType | ExternalValueType | Data type: STRING, NUMBER, BOOLEAN, DATE. |
Unique constraint: [tenantId, entityType, entityId, systemId, externalKey]
DeliveryHookConfig
Table: remoteEaze_delivery_hook_configs
Purpose: Rules defining when and how to deliver data to external systems. Each config ties an entity type + event to a system with field mappings that transform the payload. Uses maker-checker workflow. Only AUTHORIZED + active configs trigger deliveries.
| Key Field | Type | Description |
|---|---|---|
systemId | String | FK to ThirdPartySystem. Target external system. |
entityType | String | Entity type that triggers delivery, e.g. customer, account. |
event | DeliveryEvent | Triggering event: ON_CREATE, ON_UPDATE, ON_DELETE, ON_SUBMIT, ON_AUTHORIZE, ON_REJECT, ON_DENY. |
isActive | Boolean | Whether this config is enabled. |
endpointUrl | String? | Path appended to system base URL (e.g. /customers). Can be a full URL override. |
httpMethod | DeliveryHttpMethod | POST, PUT, or PATCH. |
transportFormat | TransportFormat? | Override system default format. Null = use system default. |
fieldMappings | Json | Array of { source, target, transforms[] } defining how to map entity fields to the outgoing payload. |
responseMappings | Json? | Array of { source, externalKey }. On ON_CREATE success, extracts values from the response and auto-upserts ThirdPartyMapping records. |
includeThirdPartyIds | Boolean | Attach known External IDs to the payload under _thirdPartyIds (default: true). |
includeMetadata | Boolean | Wrap payload in an event envelope with timestamp and correlation ID (default: true). |
retryLimit | Int? | Override system retry limit. Null = use system default. |
retryBackoffMs | Int? | Override system retry backoff. Null = use system default. |
Unique constraint: [tenantId, systemId, entityType, event]
DeliveryLog
Table: remoteEaze_delivery_logs
Purpose: Immutable audit trail of every delivery attempt. Written exclusively by the queue processor — never directly via API. Each retry creates a new log entry, so you can trace the full retry history.
| Key Field | Type | Description |
|---|---|---|
hookConfigId | String | FK to DeliveryHookConfig. Which config triggered this delivery. |
systemId | String | FK to ThirdPartySystem. Denormalized for efficient querying. |
entityType | String | Entity type. |
entityId | String | Entity ID. |
event | DeliveryEvent | Which event triggered the delivery. |
correlationId | String | UUID linking all deliveries triggered by the same entity event. |
jobId | String? | Background queue job ID. |
requestUrl | String | Full URL that was called. |
requestMethod | String | HTTP method used. |
requestHeaders | Json? | Sanitized headers (Authorization header stripped). |
requestPayload | Json | Exactly what was sent. |
responseStatus | Int? | HTTP status code returned. |
responseBody | Json? | What the external system returned. |
responseHeaders | Json? | Response headers. |
status | DeliveryStatus | PENDING, SUCCESS, FAILED, RETRYING. |
attempt | Int | Which attempt this is (starts at 1). |
maxAttempts | Int | Maximum attempts allowed. |
errorMessage | String? | Error details if failed. |
durationMs | Int? | Request duration in milliseconds. |
nextRetryAt | DateTime? | When the next retry will happen. |
Enums Reference
Workflow & Status
| Enum | Values | Description |
|---|---|---|
| RecordStatus | CAPTURED, PENDING_AUTH_L3, PENDING_AUTH_L2, PENDING_AUTH_L1, AUTHORIZED, REJECTED, DENIED | Maker-checker workflow states. CAPTURED = draft, PENDING_AUTH_* = awaiting approval at respective level, AUTHORIZED = live, REJECTED = returned for corrections, DENIED = permanently blocked. |
| CustomerStatus | ACTIVE, PENDING_KYC, BLOCKED, DECEASED | Customer operational states. |
| AgentStatus | ACTIVE, SUSPENDED, TERMINATED | Agent operational states. |
| FacilityStatus | ACTIVE, EXPIRED, SUSPENDED, CANCELLED | Facility operational states. |
| LogStatus | SUCCESS, FAILURE, PENDING | Audit log outcome status. |
User & Access
| Enum | Values | Description |
|---|---|---|
| UserType | INTERNAL, EXTERNAL, SYSTEM | INTERNAL = staff, EXTERNAL = field agents, SYSTEM = super admin. |
| DataAccessScope | SYSTEM, ORGANIZATION, BRANCH, SELF | Data visibility level for users. |
| ActorType | HUMAN, SYSTEM, SERVICE, CRON, IMPERSONATION | Who performed an audited action. |
Financial
| Enum | Values | Description |
|---|---|---|
| ProductType | ASSET, LIABILITY, INCOME, EXPENSE, CONTINGENT_ASSET, CONTINGENT_LIABILITY | GL account classification. |
| TransDebitCredit | DEBIT, CREDIT, BOTH | Transaction code posting direction. |
| InterestBasis | ACTUAL_360, ACTUAL_364, ACTUAL_365, ACTUAL_ACTUAL, THIRTY_360, THIRTY_E_360 | Day-count conventions for interest calculation. |
| InterestCalcMethod | FLAT_RATE, LEVEL, BAND | FLAT_RATE = simple. LEVEL = each tier applies to portion in range. BAND = entire balance uses rate of matching tier. |
| BalanceType | DAILY, AVERAGE_DAILY, LOWEST_MONTHLY, HIGHEST_MONTHLY, END_OF_PERIOD | Which balance figure to use for interest calculation. |
| CalculationBasis | FLAT, PERCENTAGE, FORMULA | Commission calculation method. |
| BandCalcType | LEVEL, BAND | Same as InterestCalcMethod but for commission bands. |
| TaxType | INCLUSIVE, EXCLUSIVE | Whether tax is included in the amount or added on top. |
Frequency
| Enum | Values | Description |
|---|---|---|
| AccrualFrequency | DAILY, MONTHLY | How often interest is accrued. |
| PostingFrequency | MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY | How often accrued interest is posted. |
| CapitalizationFrequency | NEVER, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY | How often posted interest is capitalized (added to principal). |
| ScheduleFrequency | DAILY, WEEKLY, BI_WEEKLY, MONTHLY, BI_MONTHLY, QUARTERLY, HALF_YEARLY, ANNUALLY | Repayment schedule frequency. |
| StatementFrequency | DAILY, WEEKLY, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY | Statement generation frequency. |
Branch & Organization
| Enum | Values | Description |
|---|---|---|
| BranchType | LEAD, BRANCH | LEAD = head office, BRANCH = sub-branch. |
Third-Party Delivery
| Enum | Values | Description |
|---|---|---|
| TransportFormat | REST_JSON, REST_XML | Payload serialization format for external system communication. |
| AuthType | NONE, BASIC, BEARER, API_KEY, OAUTH2 | Authentication method for connecting to external systems. |
| ExternalValueType | STRING, NUMBER, BOOLEAN, DATE | Data type of an external ID value stored in ThirdPartyMapping. |
| DeliveryEvent | ON_CREATE, ON_UPDATE, ON_DELETE, ON_SUBMIT, ON_AUTHORIZE, ON_REJECT, ON_DENY | Entity lifecycle events that can trigger a delivery hook. |
| DeliveryHttpMethod | POST, PUT, PATCH | HTTP methods available for outgoing delivery requests. |
| DeliveryStatus | PENDING, SUCCESS, FAILED, RETRYING | Outcome status of a delivery attempt. RETRYING = will be retried automatically. |
Custom Fields
| Enum | Values | Description |
|---|---|---|
| CustomFieldType | STRING, NUMBER, BOOLEAN, DATE, COMPUTED, JSON, SELECT | Data types for dynamic custom field definitions. |
| DefaultStrategy | STATIC, RULE_BASED, COMPUTED | How default values for custom fields are determined. |
Rules & Conditions
| Enum | Values | Description |
|---|---|---|
| RuleType | PERMISSION, VALIDATION | PERMISSION = role-specific conditional override. VALIDATION = global blocking rule. |
| FieldOp | EQ, NE, GT, LT, IN, NOT_IN, CONTAINS | Field-level comparison operators for approval conditions. |
| LogicalOp | AND, OR | Logical combinator for multi-condition rules. |
| ActivityRuleType | DAYS_SINCE_LAST_DEBIT, DAYS_SINCE_LAST_CREDIT, DAYS_SINCE_LAST_TRANSACTION, BALANCE_BELOW_THRESHOLD, BALANCE_IS_ZERO, CONSECUTIVE_MONTHS_INACTIVE | Trigger conditions for account lifecycle automation. |
Account & Facility
| Enum | Values | Description |
|---|---|---|
| SignatoryType | PRIMARY_HOLDER, JOINT_HOLDER, POWER_OF_ATTORNEY, AUTHORIZED_SIGNATORY, DIRECTOR | Types of account signatories. |
| SigningRule | ANY_ONE, ALL_MUST_SIGN, TWO_OF_THREE, MAJORITY | Rules for how mandates must be fulfilled. |
| StatementDelivery | EMAIL, PHYSICAL, BOTH | Statement delivery method. |
| ExpiryMode | MANUAL, AUTOMATIC | Facility expiry behavior. |
| AvailMarker | YES, NO | Whether a facility is available for utilization. |