Global Situational Awareness
A real-time geopolitical event monitoring dashboard that aggregates news from multiple sources, enriches them with AI analysis, and displays them on an interactive 3D globe.
π Live at realpolitik.world
- 3D Mapbox globe with auto-rotation
- Event clustering for high-density regions
- Color-coded markers by category (Military, Diplomacy, Economy, Unrest)
- Severity-based sizing and glow effects
- Click-to-focus with detailed event popups
- Desktop: Full dashboard with sidebar event list and map popups
- Mobile: Three-phase "Pilot's View" intelligence sheet
- Scanner mode: Scrollable event feed with sort/filter
- Pilot mode: Detailed event cards with swipe navigation
- Analyst mode: AI briefing with Pythia
- iOS Safari optimized: Full viewport height, safe area handling
- Shareable URLs:
realpolitik.world/?event=EVENT_ID - Opens directly to event with fly-to animation
- Works on both desktop and mobile
- Chronological view of how stories develop
- Multiple sources consolidated into single events
- Relative timestamps ("2h ago", "3d ago")
- Direct links to original articles
- Gemini AI integration for event summarization
- Fallout prediction: AI-generated impact analysis
- Multi-source aggregation and deduplication
- Semantic similarity for event clustering
- Automatic polling for new events
- Live indicator with last-updated timestamp
- Toast notifications for breaking events
- Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS v4
- Mapping: Mapbox GL JS (3D globe, clustering, custom layers)
- Animation: Framer Motion (mobile gestures)
- Worker: Python + Google Gemini, runs on GitHub Actions
- Storage: Cloudflare R2 (production) / local JSON (development)
- Node.js 18+
- Python 3.10+ (for worker)
- Mapbox API token
- Google Gemini API key (for worker)
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Add your NEXT_PUBLIC_MAPBOX_TOKEN
# Run the development server
npm run devOpen http://localhost:3000 to view the dashboard.
Add ?mobile=1 to the URL to force mobile layout on desktop:
http://localhost:3000/?mobile=1
The worker fetches and enriches news events:
cd worker
# Install Python dependencies
pip install -r requirements.txt
# Set up environment variables
export GEMINI_API_KEY=your_key
export NEWSAPI_KEY=your_key
# Run locally
python run_local.pyrealpolitik/
βββ src/
β βββ app/ # Next.js app router
β βββ components/
β β βββ mobile/ # Mobile-specific components
β β βββ map/ # Map popup and fallback
β β βββ Dashboard.tsx # Desktop layout
β β βββ WorldMap.tsx # Mapbox globe
β β βββ EventsSidebar.tsx
β βββ hooks/ # Custom React hooks
β β βββ useEventLayers.ts
β β βββ useAutoRotate.ts
β β βββ useMediaQuery.ts
β β βββ useViewportHeight.ts
β β βββ usePopupPosition.ts
β βββ types/ # TypeScript definitions
βββ worker/ # Python news worker
βββ public/
β βββ events.json # Event data
βββ shared/
βββ event_schema.json # Event schema definition
| Category | Color | Description |
|---|---|---|
| π΄ MILITARY | Red | Armed conflicts, defense actions |
| π΅ DIPLOMACY | Cyan | International relations, treaties |
| π’ ECONOMY | Green | Trade, sanctions, markets |
| π‘ UNREST | Amber | Protests, civil unrest |
GitHub Actions (hourly cron) β Cloudflare R2 β Vercel (Next.js)
- Frontend: Vercel (free tier)
- Worker: GitHub Actions (2000 free min/month)
- Storage: Cloudflare R2 (free tier, S3-compatible)
# Deploy to Vercel
vercel deploy --prod
# Set environment variable in Vercel dashboard:
# NEXT_PUBLIC_EVENTS_URL = https://pub-xxxxx.r2.dev/events.json- Create bucket at dash.cloudflare.com β R2
- Enable public access or custom domain
- Create API token with Object Read & Write permissions
- Note:
R2_ENDPOINT_URL,R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY
Add secrets to GitHub repo (Settings β Secrets β Actions):
| Secret | Description |
|---|---|
NEWSAPI_KEY |
NewsAPI.org API key |
GEMINI_API_KEY |
Google Gemini API key for AI enrichment |
TAVILY_API_KEY |
Tavily API key for briefing web search |
R2_ACCESS_KEY_ID |
Cloudflare R2 access key |
R2_SECRET_ACCESS_KEY |
Cloudflare R2 secret key |
R2_ENDPOINT_URL |
https://<account_id>.r2.cloudflarestorage.com |
R2_BUCKET_NAME |
realpolitik-events |
UPSTASH_REDIS_REST_URL |
Upstash Redis REST URL (for reactions/limits) |
UPSTASH_REDIS_REST_TOKEN |
Upstash Redis REST token |
The worker runs automatically every 15 minutes via .github/workflows/update-intel.yml.
NewsAPI free tier allows 100 requests/day. Default is every 15 minutes (96/day).
To adjust, edit the cron in .github/workflows/update-intel.yml:
- Every hour:
0 * * * *(24/day) - Every 30 min:
*/30 * * * *(48/day)
MIT
Built for those who need to stay ahead of global events.