Skip to content

feat: " climate disasters alerts seeders "#2550

Open
FayezBast wants to merge 1 commit intomainfrom
revert-2544-revert/pr-2535-climate-disasters
Open

feat: " climate disasters alerts seeders "#2550
FayezBast wants to merge 1 commit intomainfrom
revert-2544-revert/pr-2535-climate-disasters

Conversation

@FayezBast
Copy link
Copy Markdown
Collaborator

This PR restores the climate disasters feature by reverting the accidental revert in #2544.

Included in this restore:

  • adds the climate disasters seeder
  • restores ListClimateDisasters proto/RPC support
  • wires the server handler and gateway route back in
  • restores generated client/server bindings
  • restores bootstrap, health, MCP, cache key, OpenAPI, and Railway watch-path updates

Key files restored:

  • scripts/seed-climate-disasters.mjs
  • proto/worldmonitor/climate/v1/climate_disaster.proto
  • proto/worldmonitor/climate/v1/list_climate_disasters.proto
  • proto/worldmonitor/climate/v1/service.proto
  • server/worldmonitor/climate/v1/list-climate-disasters.ts
  • server/worldmonitor/climate/v1/handler.ts
  • server/gateway.ts

Caveat:

  • RELIEFWEB_APPNAME must be configured before merge/deploy, otherwise the seeder will fail.

@mintlify
Copy link
Copy Markdown

mintlify bot commented Mar 30, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
WorldMonitor 🟢 Ready View Preview Mar 30, 2026, 1:49 PM

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
worldmonitor Ignored Ignored Mar 30, 2026 1:49pm

Request Review

@FayezBast FayezBast changed the title Revert "revert: climate disasters (#2535) — accidental merge" feat: " climate disasters alerts seeders " Mar 30, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 30, 2026

Greptile Summary

This PR restores the climate disasters feature by reverting the accidental revert in #2544. It re-adds the full stack for the ListClimateDisasters RPC: proto definitions, generated client/server bindings, the Railway seeder (seed-climate-disasters.mjs), the RPC handler, gateway wiring, bootstrap/health/MCP registration, OpenAPI docs, and a solid test suite.

Key points:

  • The seeder fetches from ReliefWeb (v1 with v2 fallback) and the existing natural-events cache (GDACS / NASA FIRMS), deduplicates by ID and fingerprint, sorts by recency, and caps output at 300 records with a 6h TTL.
  • RELIEFWEB_APPNAME must be set in Railway before deploy; the seeder throws a hard error if it is absent (acknowledged in the PR description).
  • _seedMetaKey / _maxStaleMin in api/mcp.ts were not updated to reflect that the tool now also covers disaster data refreshed on a 6h schedule — only the 2h anomalies schedule is tracked.
  • A cosmetic double-period (\"milliseconds.. Warning\") appears in the generated OpenAPI files — fixable upstream in the proto comment.
  • All registration touchpoints (bootstrap, health, seed-health, cache-keys, gateway, MCP) are consistent and follow existing conventions.

Confidence Score: 5/5

Safe to merge after confirming RELIEFWEB_APPNAME is set in Railway; all remaining findings are P2 suggestions.

The restore is thorough, well-tested, and follows all established patterns in the codebase. There are no P0/P1 issues. The only substantive finding is the _maxStaleMin mismatch in api/mcp.ts (P2), which does not affect data correctness or availability. Per confidence guidance, P2-only findings do not reduce the score below 5.

api/mcp.ts — _maxStaleMin should be updated to reflect the slower 6h disaster seed schedule.

Important Files Changed

Filename Overview
scripts/seed-climate-disasters.mjs New 467-line seeder: fetches from ReliefWeb v1/v2 (with fallback) and the existing natural-events cache (GDACS/NASA FIRMS), deduplicates, sorts, and writes up to 300 records to Redis. Robust error handling via Promise.allSettled, sensible fallbacks, and good unit-test coverage.
server/worldmonitor/climate/v1/list-climate-disasters.ts New RPC handler; reads from Redis seed cache using getCachedJson (pure cache-read pattern, consistent with other seed-only handlers). Correctly handles both camelCase and snake_case field names from Redis.
api/mcp.ts Adds climate:disasters:v1 cache key to get_climate_data tool, but _seedMetaKey and _maxStaleMin still reflect only the 2h anomalies schedule, not the 6h disaster schedule.
proto/worldmonitor/climate/v1/climate_disaster.proto New proto message for ClimateDisaster; correctly annotates int64 with INT64_ENCODING_NUMBER and uses sebuf HTTP annotations.
proto/worldmonitor/climate/v1/service.proto Adds ListClimateDisasters RPC with correct HTTP GET annotation; consistent with existing ListClimateAnomalies pattern.
api/bootstrap.js Adds climateDisasters to BOOTSTRAP_CACHE_KEYS and SLOW_KEYS; consistent with convention for slow-seeded data sources.
api/health.js Adds climateDisasters to BOOTSTRAP_KEYS and SEED_META with maxStaleMin: 720 (2x the 360-min run interval); matches the seed's CACHE_TTL of 21600 seconds.
server/gateway.ts Wires /api/climate/v1/list-climate-disasters with 'static' cache tier, matching the existing anomalies endpoint tier.
tests/climate-disasters-seed.test.mjs New test file covers all key exported helpers: ReliefWeb type filter, appname validation, natural-event source filtering, coordinate-based country resolution, partial-failure resilience, and Redis output shape.
src/generated/client/worldmonitor/climate/v1/service_client.ts Generated client stubs for ClimateDisaster types and listClimateDisasters method; consistent with existing generated code patterns.
src/generated/server/worldmonitor/climate/v1/service_server.ts Generated server route for ListClimateDisasters; correctly parses page_size/cursor query params and handles validation/errors consistently.
src/services/climate/index.ts Adds getHydratedClimateDisasters() accessor that reads the climateDisasters bootstrap slot; correctly typed and isolated from anomaly logic.

Sequence Diagram

sequenceDiagram
    participant Railway as Railway Cron (6h)
    participant Seeder as seed-climate-disasters.mjs
    participant ReliefWeb as ReliefWeb API (v1/v2)
    participant NatCache as natural:events:v1 (Redis)
    participant Redis as Redis (climate:disasters:v1)
    participant Handler as list-climate-disasters.ts
    participant Client as ClimateServiceClient

    Railway->>Seeder: trigger (every 6h)
    par Fetch sources
        Seeder->>ReliefWeb: POST /v1/disasters (RELIEFWEB_APPNAME)
        ReliefWeb-->>Seeder: disaster rows (FL/TC/DR/HT/WF)
    and
        Seeder->>NatCache: getCachedJson(natural:events:v1)
        NatCache-->>Seeder: GDACS + NASA FIRMS events
    end
    Seeder->>Seeder: dedupe + sort + cap at 300
    Seeder->>Redis: SET climate:disasters:v1 (TTL 6h)
    Seeder->>Redis: SET seed-meta:climate:disasters

    Client->>Handler: GET /api/climate/v1/list-climate-disasters
    Handler->>Redis: getCachedJson(climate:disasters:v1)
    Redis-->>Handler: { disasters: [...] }
    Handler-->>Client: ListClimateDisastersResponse (paginated)
Loading

Comments Outside Diff (2)

  1. docs/api/ClimateService.openapi.yaml, line 186 (link)

    P2 Double period in startedAt description

    The description has two consecutive periods before "Warning":

    description: 'Event start time as Unix epoch milliseconds.. Warning: Values > 2^53 may lose precision in JavaScript'

    This same double-period also appears in docs/api/ClimateService.openapi.json. If these files are generated by buf/sebuf, the fix should be in the proto source (proto/worldmonitor/climate/v1/climate_disaster.proto, field comment for started_at).

  2. api/mcp.ts, line 52-56 (link)

    P2 _seedMetaKey/_maxStaleMin not updated for disaster data

    The get_climate_data tool now serves from two separate seeds with very different refresh schedules:

    • Climate anomalies run every 2h (maxStaleMin: 120)
    • Climate disasters run every 6h (maxStaleMin: 720, as registered in api/health.js)

    However, _seedMetaKey still points only to the anomalies seed and _maxStaleMin remains 120. If the MCP framework uses these fields to evaluate freshness before serving, it will check only the anomalies seed timestamp against a 120-minute threshold — meaning a disaster payload that is legitimately up to 360 minutes old could be flagged as stale, or anomaly freshness could incorrectly gate serving disaster data.

    Consider raising _maxStaleMin to 720 (the slower interval) to avoid false-stale signals for the disaster dataset.

Reviews (1): Last reviewed commit: "Revert "Revert "feat(climate): add clima..." | Re-trigger Greptile

@SebastienMelki
Copy link
Copy Markdown
Collaborator

@FayezBast — this restore looks complete and well-tested. Greptile gives it 5/5. Two things before merging:

  1. RELIEFWEB_APPNAME in Railway: This env var must be set before deploy. Please confirm it's in the Railway config.
  2. _maxStaleMin in api/mcp.ts: Now serving from two seeds with different schedules (anomalies 2h, disasters 6h), _maxStaleMin: 120 only reflects the anomaly cadence. Consider raising to 720 for the slower schedule.
  3. Minor: proto comment for started_at has a double period — fixable in proto source.

Otherwise ready to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants