mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
feat(intelligence): GetCountryRisk RPC + MCP tool for per-country risk scores (#2502)
* feat(intelligence): GetCountryRisk RPC for per-country risk intelligence Adds a new fast Redis-read RPC that consolidates CII score, travel advisory level, and OFAC sanctions exposure into a single per-country response. Replaces the need to call GetRiskScores (all-countries) and filter client-side. Wired to MCP as get_country_risk tool (no LLM, ~200ms, good for agent screening). - proto/intelligence/v1/get_country_risk.proto (new) - server/intelligence/v1/get-country-risk.ts (reads 3 pre-seeded Redis keys) - gateway.ts: slow cache tier - api/mcp.ts: RpcToolDef with 8s timeout - tests/mcp.test.mjs: update tool count 27→28 * fix(intelligence): upstream-unavailable signal, fetchedAt from CII, drop redundant catch P1: return upstreamUnavailable:true when all Redis reads are null — prevents CDN from caching false-negative sanctions/risk responses during Redis outages. P2: fetchedAt now uses cii.computedAt (actual data age) instead of request time. P2: removed redundant .catch(() => null) — getCachedJson already swallows errors. * fix(intelligence): accurate OFAC counts and country names for GetCountryRisk P1: sanctions:pressure:v1.countries is a top-12 slice — switch to a new sanctions:country-counts:v1 key (ISO2→count across ALL 40K+ OFAC entries). Written by seed-sanctions-pressure.mjs in afterPublish alongside entity index. P1: trigger upstreamUnavailable:true when sanctions key alone is missing, preventing false-negative sanctionsActive:false from being cached by CDN. P2: advisory seeder now writes byCountryName (ISO2→display name) derived from country-names.json reverse map. Handler uses it as fallback so countries outside TIER1_COUNTRIES (TH, CO, BD, IT...) get proper names.
This commit is contained in:
@@ -120,6 +120,39 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
/api/intelligence/v1/get-country-risk:
|
||||
get:
|
||||
tags:
|
||||
- IntelligenceService
|
||||
summary: GetCountryRisk
|
||||
description: GetCountryRisk retrieves composite risk intelligence for a specific country.
|
||||
operationId: GetCountryRisk
|
||||
parameters:
|
||||
- name: country_code
|
||||
in: query
|
||||
description: ISO 3166-1 alpha-2 country code.
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GetCountryRiskResponse'
|
||||
"400":
|
||||
description: Validation error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
default:
|
||||
description: Error response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
/api/intelligence/v1/get-country-intel-brief:
|
||||
get:
|
||||
tags:
|
||||
@@ -1014,6 +1047,45 @@ components:
|
||||
type: string
|
||||
description: Related entities identified.
|
||||
description: EventClassification represents an AI-generated classification of a real-world event.
|
||||
GetCountryRiskRequest:
|
||||
type: object
|
||||
properties:
|
||||
countryCode:
|
||||
type: string
|
||||
pattern: ^[A-Z]{2}$
|
||||
description: ISO 3166-1 alpha-2 country code.
|
||||
required:
|
||||
- countryCode
|
||||
description: GetCountryRiskRequest specifies which country to retrieve risk intelligence for.
|
||||
GetCountryRiskResponse:
|
||||
type: object
|
||||
properties:
|
||||
countryCode:
|
||||
type: string
|
||||
description: ISO 3166-1 alpha-2 country code.
|
||||
countryName:
|
||||
type: string
|
||||
description: Country name.
|
||||
cii:
|
||||
$ref: '#/components/schemas/CiiScore'
|
||||
advisoryLevel:
|
||||
type: string
|
||||
description: Travel advisory level from government sources (e.g. "do-not-travel", "reconsider", "caution"). Empty if none.
|
||||
sanctionsActive:
|
||||
type: boolean
|
||||
description: Whether this country has active OFAC sanctions designations.
|
||||
sanctionsCount:
|
||||
type: integer
|
||||
format: int32
|
||||
description: Count of sanctioned entities associated with this country.
|
||||
fetchedAt:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 'Data freshness timestamp derived from CII computedAt, as Unix epoch milliseconds.. Warning: Values > 2^53 may lose precision in JavaScript'
|
||||
upstreamUnavailable:
|
||||
type: boolean
|
||||
description: True when all upstream Redis keys were unavailable. Signals CDN cache bypass.
|
||||
description: GetCountryRiskResponse contains composite risk intelligence for a specific country.
|
||||
GetCountryIntelBriefRequest:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user