From e028a8b9768d0c16bb84e502c29ef10ab8f32231 Mon Sep 17 00:00:00 2001 From: Peter Kovacs Date: Fri, 9 Jan 2026 13:15:26 +0100 Subject: [PATCH] FINERACT-2421: [doc] Asset Externalization documentation --- .../features/asset-externalization.adoc | 307 ++++++++++++++++++ .../src/docs/en/chapters/features/index.adoc | 1 + 2 files changed, 308 insertions(+) create mode 100644 fineract-doc/src/docs/en/chapters/features/asset-externalization.adoc diff --git a/fineract-doc/src/docs/en/chapters/features/asset-externalization.adoc b/fineract-doc/src/docs/en/chapters/features/asset-externalization.adoc new file mode 100644 index 000000000..3616c5cff --- /dev/null +++ b/fineract-doc/src/docs/en/chapters/features/asset-externalization.adoc @@ -0,0 +1,307 @@ + +# Asset Externalization +--- + + +## 1. Purpose & Scope + +The Asset Externalization capability enables **loan ownership transfer** between a **Platform Owner** and external investors within **Fineract**, supporting: + +* Loan sales and securitization for GPL products +* Real-time ownership awareness with **COB-based execution** +* Full accounting, reporting, and auditing for **Platform Owner–owned and investor-owned loans** +* API-driven ownership lifecycle management +* Event-driven downstream integration (ETL, Credit domains) + +Ownership is **exclusive**: once sold, the loan is **100% investor-owned** until buyback. + +--- + +## 2. In-Scope vs Out-of-Scope + +### In Scope (Fineract Responsibilities) + +* Persist and manage **loan ownership throughout loan lifecycle** +* Accept ownership transfer requests (sale, buyback, cancel) +* Execute ownership changes **at Close of Business (COB)** +* Generate **accounting journal entries** per ownership +* Publish **ownership change events** +* Provide **GET/POST APIs** for ownership and transfers +* Support delayed settlement (pending → active) +* Produce investor accounting reports + +### Out of Scope + +* General high-level mechanism for determining which loans/clients are eligible for sale or buyback (loan state requirements are scope and implemented) +* Smart Order Router which could prioritize internal logic or market logic +* Credit ETL (Extract, Transform, Load) schema decisions outside Fineract + +--- + +## 3. Ownership Model + +### Ownership Characteristics + +* Single owner at any time (**Platform Owner** or Investor) +* Ownership stored with: + +* Asset Owner ID +* Transfer (Sale / Buyback) ID +* Purchase Price Ratio +* Effective date range +* Status +* Ownership updates requested in real time, **executed during COB** + +### Ownership Statuses + +|=== +| Status | Description +| PENDING | Transfer requested, not yet executed +| ACTIVE | Investor owns the loan +| BUYBACK | Ownership reverted to Platform Owner +| DECLINED | Transfer invalid due to balance/state +| CANCELLED | Transfer cancelled before execution +|=== + +--- + +## 4. Functional Flows + +### 4.1 Asset Sale (Ownership Transfer to Investor) + +**Preconditions** + +* Loan must be **ACTIVE** +* No active ownership +* Balance at COB **> 0.00** + +**Process** + +1. Sale request submitted via API +2. Ownership record created with status **PENDING** +3. At COB on settlement date: + +* If balance > 0.00 → status becomes **ACTIVE** +* If balance ≤ 0.00 → status becomes **DECLINED** +4. Journal entries posted using **closing balance** +5. Ownership effective from next day + +**Persisted Data** + +* Asset Owner ID +* Sale Transaction ID +* Purchase Price Ratio +* Settlement date +* Effective date range +* Timestamps + +--- + +### 4.2 Buyback (Ownership Transfer to Platform Owner) + +**Preconditions** + +* Active ownership exists +* Loan must be **ACTIVE** +* Can be triggered for fraud, reversals, or business decision + +**Process** + +1. Buyback request submitted +2. Buyback transfer record created +3. At COB: + +* Ownership marked **INACTIVE** +* Journal entries posted using closing balance +4. Ownership reverts to Platform Owner + +**No buyback occurs if** + +* Loan is CLOSED +* No active ownership +* Loan not found + +--- + +### 4.3 Delayed Settlement (Phase 2) + +* Sale request can include **future settlement date** +* Ownership remains **PENDING** until settlement +* Pending accounting entries applied +* At settlement COB: + +* Pending → ACTIVE if balance > 0 +* Pending → DECLINED if balance ≤ 0 + +--- + +## 5. Accounting Behavior + +### General Rules + +* All accounting logic remains unchanged **except owner tagging** +* Fees, payments, delinquency, charge-off rules remain unchanged +* Fees after sale belong to **investor** +* No ownership transfer or GL entries if balance ≤ 0 + +--- + +### 5.1 Sale & Buyback Journal Entries (COB) + +**Sale** + +* DR Loan/Fee Receivable – Investor +* CR Loan/Fee Receivable – Platform Owner + +**Buyback** + +* DR Loan/Fee Receivable – Platform Owner +* CR Loan/Fee Receivable – Investor + +--- + +### 5.2 Investor-Owned Loan Transactions + +For investor-owned loans, journal entries are posted **against investor GLs** for: + +* Disbursement +* Repayments (all payment types) +* Refunds +* Goodwill credits +* Snooze & NSF fees +* Fee waivers +* Credit balance refunds +* Repayment adjustments & reversals +* Charge-offs (non-payment, deceased, bankrupt) +* Recoveries (repayments, refunds) + +--- + +## 6. Events + +### Ownership Change Events + +Events are published **in real time** when ownership changes occur. + +**Published For** + +* Sale +* Buyback +* Declined transfers + +**Event Payload** + +* Date/time +* Loan account ID +* Sale/Buyback Transaction ID +* Asset Owner ID +* Loan balance + +**Consumption** + +* Fineract SOR → Adaptor → Credit ETL +* Persisted in Credit databases + +--- + +## 7. APIs + +### Transfer Requests + +Ownership transfer requests are supported for **sale**, **buyback**, and **cancel**, targeting loans by internal or external identifiers. + +**Root endpoint** + +* `/external-asset-owners` + +**Sale / Buyback / Cancel** + +* `POST /external-asset-owners/transfers?loanId=&command=` +* `POST /external-asset-owners/transfers?loanExternalId=&command=` +* `POST /external-asset-owners/transfers/loans/?command=` +* `POST /external-asset-owners/transfers/loans/external-id/?command=` + +--- + +### Retrieve Ownership + +Ownership and transfer information can be retrieved using: + +* `GET /external-asset-owners/transfers?transferExternalId=` +* `GET /external-asset-owners/transfers?loanId=` +* `GET /external-asset-owners/transfers?loanExternalId=` + +--- + +### Retrieve Accounting Data + +Accounting data related to ownership is available through: + +* Transfer journal entries + +* `GET /external-asset-owners/transfers/external-id/{ownerExternalId}/journal-entries` + +* Owner journal entries + +* `GET /external-asset-owners/owners/external-id/{ownerExternalId}/journal-entries` + +--- + +## 8. Data Model (Summary) + +### Core Tables + +* `m_external_asset_owner` +* `m_external_asset_owner_transfer` +* `m_external_asset_owner_active_transfer_loan_mapping` +* `m_external_asset_owner_journal_entry_mapping` +* `m_external_asset_transfer_journal_entry_mapping` +* `m_external_asset_owner_transfer_details` + +Supports: + +* Ownership history +* Effective dating +* Auditing +* Investor-level accounting reconciliation + +--- + +## 9. Reporting + +### Daily Investor Reports + +* GL Trial Balance Summary (by investor) +* Transaction Detail Report (by investor) + +Used for reconciliation of: + +* Investor cash +* GL balances +* Ownership-related postings + +--- + +## 10. Validation Rules (Consolidated) + +* Only **ACTIVE loans** accepted for sale +* No transfer if: + +* Loan CLOSED +* Balance ≤ 0 at COB +* Active ownership already exists +* Invalid loan ID +* Only one pending transfer allowed per loan +* Ownership changes occur **only during COB** + +--- + +## 11. Key Design Constraints + +* Transfer initiation via API only +* Execution strictly at COB +* Ownership effective date always starts **day after settlement** +* Journal entries linked to owner via mapping tables +* Accounting and Investor modules are logically coupled + +--- diff --git a/fineract-doc/src/docs/en/chapters/features/index.adoc b/fineract-doc/src/docs/en/chapters/features/index.adoc index 2c25d78d7..fd4d68c4f 100644 --- a/fineract-doc/src/docs/en/chapters/features/index.adoc +++ b/fineract-doc/src/docs/en/chapters/features/index.adoc @@ -12,3 +12,4 @@ include::loan-charges.adoc[leveloffset=+1] include::journal-entry-aggregation.adoc[leveloffset=+1] include::re-ageing.adoc[leveloffset=+1] include::pause-delinquency.adoc[leveloffset=+1] +include::asset-externalization.adoc[leveloffset=+1]