- Updated `RiskListAccess` and `ThresholdWriteAccess` to enforce access control in the risk repository and threshold repository, ensuring only authorized roles can perform sensitive operations. - Introduced new methods in `RiskRepository` for counting pending alerts and listing alerts with access checks, improving data security and compliance. - Enhanced the `chat.py` and `deps.py` files to integrate compliance roles into the risk management matrix, allowing for more granular access control. - Updated documentation to reflect the new testing baseline of 825 passed tests, indicating improved stability and functionality across the application. This update significantly strengthens the risk management capabilities, ensuring robust access control and compliance with organizational policies.
124 lines
3.2 KiB
TypeScript
124 lines
3.2 KiB
TypeScript
import { apiFetch } from './client'
|
|
|
|
const RISK_AGENT_TYPE = 'risk'
|
|
|
|
function riskHeaders(token: string, extra?: HeadersInit): HeadersInit {
|
|
return {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
Authorization: `Bearer ${token}`,
|
|
'X-Agent-Type': RISK_AGENT_TYPE,
|
|
...extra,
|
|
}
|
|
}
|
|
|
|
export type RiskAlertItem = {
|
|
alert_id: string
|
|
alert_type: string
|
|
customer_id: string
|
|
risk_score: number
|
|
status: string
|
|
created_at: string
|
|
handler_result?: string | null
|
|
}
|
|
|
|
type ListAlertsResponse = {
|
|
items: RiskAlertItem[]
|
|
total: number
|
|
disclaimer: string
|
|
page?: number
|
|
page_size?: number
|
|
stats?: { pending_review_count: number; today_pending_count: number }
|
|
}
|
|
|
|
export async function listPendingAlerts(token: string, pageSize = 100) {
|
|
const { data } = await apiFetch<ListAlertsResponse>(
|
|
`/api/risk/alerts?status=pending_review&page_size=${pageSize}`,
|
|
{ headers: riskHeaders(token) },
|
|
)
|
|
return data
|
|
}
|
|
|
|
export type ListAlertsParams = {
|
|
status?: string
|
|
alert_type?: string
|
|
customer_id?: string
|
|
start_date?: string
|
|
end_date?: string
|
|
page?: number
|
|
page_size?: number
|
|
}
|
|
|
|
export async function listAlerts(token: string, params: ListAlertsParams = {}) {
|
|
const q = new URLSearchParams()
|
|
if (params.status) q.set('status', params.status)
|
|
if (params.alert_type) q.set('alert_type', params.alert_type)
|
|
if (params.customer_id) q.set('customer_id', params.customer_id)
|
|
if (params.start_date) q.set('start_date', params.start_date)
|
|
if (params.end_date) q.set('end_date', params.end_date)
|
|
q.set('page', String(params.page ?? 1))
|
|
q.set('page_size', String(params.page_size ?? 20))
|
|
const { data } = await apiFetch<ListAlertsResponse>(`/api/risk/alerts?${q.toString()}`, {
|
|
headers: riskHeaders(token),
|
|
})
|
|
return data
|
|
}
|
|
|
|
export type HandleAlertPayload = {
|
|
handler_result: 'confirmed_normal' | 'confirmed_suspicious' | 'reported'
|
|
handler_comment?: string
|
|
}
|
|
|
|
export async function handleAlert(token: string, alertId: string, payload: HandleAlertPayload) {
|
|
const { data } = await apiFetch<Record<string, unknown>>(
|
|
`/api/risk/alerts/${encodeURIComponent(alertId)}/handle`,
|
|
{ method: 'POST', headers: riskHeaders(token), body: JSON.stringify(payload) },
|
|
)
|
|
return data
|
|
}
|
|
|
|
export type SuitabilityCheckPayload = {
|
|
customer_id: string
|
|
product_id: string
|
|
}
|
|
|
|
export type SuitabilityCheckResponse = {
|
|
match_result: string
|
|
mismatch_type: string
|
|
is_matched: boolean
|
|
blocked: boolean
|
|
block_reason?: string
|
|
block_response_code?: string
|
|
customer_level?: string
|
|
product_level?: string
|
|
advice?: string
|
|
notice?: string
|
|
rule_refs?: string[]
|
|
}
|
|
|
|
export async function checkSuitability(token: string, payload: SuitabilityCheckPayload) {
|
|
const { data } = await apiFetch<SuitabilityCheckResponse>('/api/risk/suitability/check', {
|
|
method: 'POST',
|
|
headers: riskHeaders(token),
|
|
body: JSON.stringify(payload),
|
|
})
|
|
return data
|
|
}
|
|
|
|
export type AmlScanResponse = {
|
|
scanned: number
|
|
hit_customers: number
|
|
alerts: string[]
|
|
skipped_existing: string[]
|
|
disclaimer: string
|
|
}
|
|
|
|
export async function scanAml(token: string) {
|
|
const { data } = await apiFetch<AmlScanResponse>('/api/risk/aml/scan', {
|
|
method: 'POST',
|
|
headers: riskHeaders(token),
|
|
body: JSON.stringify({}),
|
|
})
|
|
return data
|
|
}
|