feat(advisories): gold standard migration for security advisories (#1637)

* feat(advisories): gold standard migration for security advisories

Move security advisories from client-side RSS fetching (24 feeds per
page load) to Railway cron seed with Redis-read-only Vercel handler.

- Add seed script fetching via relay RSS proxy with domain allowlist
- Add ListSecurityAdvisories proto, handler, and RPC cache tier
- Add bootstrap hydration key for instant page load
- Rewrite client service: bootstrap -> RPC fallback, no browser RSS
- Wire health.js, seed-health.js, and dataSize tracking

* fix(advisories): empty RPC returns ok:true, use full country map

P1 fixes from Codex review:
- Return ok:true for empty-but-successful RPC responses so the panel
  clears to empty instead of stuck loading on cold environments
- Replace 50-entry hardcoded country map with 251-entry shared config
  generated from the project GeoJSON + aliases, matching coverage of
  the old client-side nameToCountryCode matcher

* fix(advisories): add Cote d'Ivoire and other missing country aliases

Adds 14 missing aliases including "cote d ivoire" (US State Dept
title format), common article-prefixed names (the Bahamas, the
Gambia), and alternative official names (Czechia, Eswatini, Cabo
Verde, Timor-Leste).

* fix(proto): inject @ts-nocheck via Makefile generate target

buf generate does not emit @ts-nocheck, but tsc strict mode rejects
the generated code. Adding a post-generation sed step in the Makefile
ensures both CI proto-freshness (make generate + diff) and CI
typecheck (tsc --noEmit) pass consistently.
This commit is contained in:
Elie Habib
2026-03-15 11:54:08 +04:00
committed by GitHub
parent ac9e3c8af2
commit f336418c17
20 changed files with 1043 additions and 206 deletions

View File

@@ -277,6 +277,32 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/intelligence/v1/list-security-advisories:
get:
tags:
- IntelligenceService
summary: ListSecurityAdvisories
description: ListSecurityAdvisories retrieves pre-seeded travel and health advisories.
operationId: ListSecurityAdvisories
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ListSecurityAdvisoriesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Error:
@@ -797,3 +823,40 @@ components:
format: double
countryName:
type: string
ListSecurityAdvisoriesRequest:
type: object
ListSecurityAdvisoriesResponse:
type: object
properties:
advisories:
type: array
items:
$ref: '#/components/schemas/SecurityAdvisoryItem'
byCountry:
type: object
additionalProperties:
type: string
ByCountryEntry:
type: object
properties:
key:
type: string
value:
type: string
SecurityAdvisoryItem:
type: object
properties:
title:
type: string
link:
type: string
pubDate:
type: string
source:
type: string
sourceCountry:
type: string
level:
type: string
country:
type: string