feat(intelligence): GDELT tone/vol timeline analysis for escalation signals (#2044) (#2087)

* feat(intelligence): GDELT tone/vol timeline per topic (#2044)

* fix(gdelt-timeline): add isMain guard to seed script, fix gateway cache tier

- Wrap runSeed() call in isMain guard (process.argv[1].endsWith check) to
  prevent CI failures when the seed module is imported rather than executed
  directly — pre-push hook does not catch this
- Change gateway cache tier from 'medium' (20min CDN) to 'daily' (1h
  browser/s-maxage=86400 CDN) to align with the 1h TIMELINE_TTL on the
  per-topic tone/vol Redis keys

* fix(gdelt-timeline): TTL 1h→12h, medium cache tier, real fetchedAt, exit 0

- seed-gdelt-intel.mjs: TIMELINE_TTL 3600→43200 (12h = 2× 6h cron) so
  tone/vol keys survive between cron runs instead of expiring after 1h
- seed-gdelt-intel.mjs: afterPublish wraps tone/vol as {data, fetchedAt}
  so the real write timestamp is stored alongside the arrays
- get-gdelt-topic-timeline.ts: unwrap new envelope shape; fetchedAt now
  reflects actual data write time instead of request time
- gateway.ts: daily→medium cache tier (CDN s-maxage=1200 matches 6h cadence)
- seed-gdelt-intel.mjs: process.exit(1)→0 to match seeder suite convention

* fix(gdelt-timeline): add GdeltTimelinePoint type cast in unwrap helper
This commit is contained in:
Elie Habib
2026-03-23 20:10:15 +04:00
committed by GitHub
parent 9696a545eb
commit 4f19e36804
10 changed files with 337 additions and 10 deletions

View File

@@ -522,6 +522,39 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/intelligence/v1/get-gdelt-topic-timeline:
get:
tags:
- IntelligenceService
summary: GetGdeltTopicTimeline
description: GetGdeltTopicTimeline retrieves tone and volume timelines for a GDELT intel topic.
operationId: GetGdeltTopicTimeline
parameters:
- name: topic
in: query
description: Topic ID (military, cyber, nuclear, sanctions, intelligence, maritime).
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetGdeltTopicTimelineResponse'
"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:
@@ -1543,3 +1576,42 @@ components:
type: string
country:
type: string
GetGdeltTopicTimelineRequest:
type: object
properties:
topic:
type: string
description: Topic ID (military, cyber, nuclear, sanctions, intelligence, maritime).
description: GetGdeltTopicTimelineRequest retrieves tone and volume timelines for a GDELT intel topic.
GetGdeltTopicTimelineResponse:
type: object
properties:
topic:
type: string
description: Topic ID.
tone:
type: array
items:
$ref: '#/components/schemas/GdeltTimelinePoint'
vol:
type: array
items:
$ref: '#/components/schemas/GdeltTimelinePoint'
fetchedAt:
type: string
description: ISO timestamp when this data was fetched.
error:
type: string
description: Error message if fetch failed.
description: GetGdeltTopicTimelineResponse contains tone and volume timelines for a topic.
GdeltTimelinePoint:
type: object
properties:
date:
type: string
description: Date string from GDELT (e.g. "20240101T000000").
value:
type: number
format: double
description: Tone or volume value at this point.
description: GdeltTimelinePoint is a single data point in a tone or volume timeline.