feat(aml,risk-review,accounting): update financial activity mapping options, AML flagged transactions filters, and risk review report

This commit is contained in:
2026-09-18 10:32:47 +05:30
parent 0cef1b5a50
commit f9b73a4930
14 changed files with 863 additions and 234 deletions
+53 -86
View File
@@ -167,7 +167,9 @@
</div>
<!-- The 15th of the month after the one being reported, worked out rather than fixed at
15 Feb 2026 — a due date that never moves stops being a due date. -->
<div class="dc-meta">Due: <strong>{{ ctrDueDateLabel }}</strong></div>
<div class="dc-meta">
Due: <strong>{{ ctrDueDateLabel }}</strong>
</div>
<button class="dc-btn" (click)="showTab('ctr')"><fa-icon icon="external-link-alt"></fa-icon> Open</button>
</div>
<div class="dc-card">
@@ -220,9 +222,7 @@
@if (ctrLinesLoading) {
<div class="fiu-note">Loading the generated CTR lines…</div>
} @else if (ctrLinesError) {
<div class="fiu-note fiu-note--warn">
<fa-icon icon="exclamation-triangle"></fa-icon> {{ ctrLinesError }}
</div>
<div class="fiu-note fiu-note--warn"><fa-icon icon="exclamation-triangle"></fa-icon> {{ ctrLinesError }}</div>
} @else if (!ctrTxns.length) {
<div class="fiu-note fiu-note--warn">
<fa-icon icon="exclamation-triangle"></fa-icon>
@@ -432,87 +432,17 @@
}
<div class="fiu-section">
<!-- LIVE: suspicious AML alerts awaiting AML Officer review (Structuring, PEP, etc.) -->
<div class="fiu-form-meta">
<div class="fiu-form-title">
<h3>Live AML Alerts (Awaiting Triage)</h3>
<p>Flagged by the monitoring engine for suspicious behavioral patterns — triage and whitelist or escalate</p>
</div>
<!-- Whitelisted is deliberately absent: cleared alerts are not STR business and have
their own register below. -->
<select class="fiu-inp" [(ngModel)]="amlAlertStatusFilter">
<option value="">All statuses</option>
<option value="RAISED">Raised</option>
<option value="UNDER_REVIEW">Under Review</option>
<option value="ESCALATED">Escalated</option>
</select>
<!-- The triage queue that used to head this tab has gone. It listed the same open alerts as the AML Rules
Master, and listed them worse: without the severity bands, the per-rule findings or the batch decision that
screen carries. Two places to work the same queue is how an alert gets cleared in one and escalated in the
other. This tab keeps what is about the filing itself - what was cleared, and what became an STR case. -->
<div class="fiu-note">
<fa-icon icon="info-circle"></fa-icon>
<span>
Alerts are triaged in <strong>RBI &rsaquo; AML Rules Master &rsaquo; Flagged Transactions</strong>. What an
officer escalates there arrives here as an STR case.
</span>
</div>
<div class="fiu-tbl-wrap">
<table class="fiu-tbl">
<thead>
<tr>
<th>ID</th>
<th>Client</th>
<th>Type</th>
<th>Rule</th>
<th class="ta-r">Amount</th>
<th>Raised On</th>
<th>Status</th>
<th class="ta-c">Routes To</th>
<th>Notes</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@for (alert of amlSuspiciousAlerts; track alert.id) {
<tr>
<td>{{ alert.id }}</td>
<td>{{ alert.clientDisplayName }}</td>
<td>{{ alert.transactionType }}</td>
<td>{{ alert.ruleCode }} &mdash; {{ alert.ruleDescription }}</td>
<td class="ta-r mono">&#8377;{{ alert.amount | number: '1.0-0' }}</td>
<td>{{ asDate(alert.raisedOn) | date: 'medium' }}</td>
<td>
<span [class]="amlStatusClass(alert.status)">{{ alert.status }}</span>
</td>
<td class="ta-c">
<span [class]="alertRouteClass(alert.status, false)">{{ alertRouteLabel(alert.status, false) }}</span>
</td>
<td>
@if (alert.status === 'RAISED' || alert.status === 'UNDER_REVIEW') {
<input
type="text"
class="fiu-inp"
placeholder="Review notes"
[(ngModel)]="amlReviewNotes[alert.id]"
/>
} @else {
<span class="muted">{{ alert.reviewNotes }}</span>
}
</td>
<td>
@if (alert.status === 'RAISED' || alert.status === 'UNDER_REVIEW') {
<div class="fiu-action-group" *mifosxHasPermission="'REVIEW_AML_ALERT'">
<button class="fiu-btn fiu-btn-g" (click)="whitelistAlert(alert)">Whitelist</button>
<button class="fiu-btn fiu-btn-xml" (click)="escalateAlert(alert)">Escalate</button>
</div>
}
</td>
</tr>
} @empty {
<tr>
<td colspan="10" class="fiu-empty">No suspicious behavioral alerts awaiting triage.</td>
</tr>
}
</tbody>
</table>
</div>
<p class="fiu-tbl-legend">
<span class="report-pill report-pending">Pending</span> awaiting Whitelist/Escalate decision &middot;
<span class="report-pill report-str">→ STR</span> escalated to Principal Officer as an STR case
</p>
<hr style="border: 0; border-top: 1px solid var(--f-g200); margin: 8px 0" />
<!-- Cleared register: whitelisted alerts, kept out of the STR queue but retained with the
evidence recorded at review time. -->
@@ -590,7 +520,7 @@
</tr>
</thead>
<tbody>
@for (sc of amlStrCases; track sc.id) {
@for (sc of liveStrCases; track sc.id) {
<tr [class.selected-row]="selectedStrCase?.id === sc.id">
<td>{{ sc.id }}</td>
<td>{{ sc.clientDisplayName }}</td>
@@ -607,13 +537,50 @@
</tr>
} @empty {
<tr>
<td colspan="8" class="fiu-empty">No STR cases yet.</td>
<td colspan="8" class="fiu-empty">No STR cases outstanding.</td>
</tr>
}
</tbody>
</table>
</div>
<!-- Filed cases are finished work, not outstanding work, so they sit apart from the live queue — but they are
the bank's record of what went to FIU-IND and against which reference, so they stay visible. -->
@if (filedStrCases.length) {
<div class="fiu-form-meta" style="margin-top: 18px">
<div class="fiu-form-title">
<h3>Filed with FIU-IND</h3>
<p>Reported and closed — kept for the record, with the reference the filing was made under.</p>
</div>
</div>
<div class="fiu-tbl-wrap">
<table class="fiu-tbl">
<thead>
<tr>
<th>ID</th>
<th>Client</th>
<th>Conclusion</th>
<th>Filed On</th>
<th>FIU Reference</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@for (sc of filedStrCases; track sc.id) {
<tr>
<td>{{ sc.id }}</td>
<td>{{ sc.clientDisplayName }}</td>
<td>{{ sc.conclusion || '—' }}</td>
<td>{{ asDate(sc.strFiledOn) | date: 'dd MMM yyyy' }}</td>
<td class="mono">{{ sc.strReferenceNo || '—' }}</td>
<td><button class="fiu-btn fiu-btn-g" (click)="selectStrCase(sc)">View</button></td>
</tr>
}
</tbody>
</table>
</div>
}
@if (selectedStrCase) {
<div class="str-case-detail">
<div class="fiu-form-meta">