Spaces:
Sleeping
Sleeping
File size: 27,326 Bytes
f59a149 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | # ShockMap β Final Polish & Deployment Prompt Guide
### Google Solution Challenge 2026 | Phase 1 Completion
> **How to use this file:** Each section is a self-contained prompt. Paste it directly into Claude, Cursor, or your AI coding tool. Work top to bottom β the design system must come first, then features, then deployment. Mock data is explicitly permitted in every prompt.
---
## Table of Contents
1. [Design System Overhaul](#1-design-system-overhaul)
2. [Dashboard β Animated HHI Globe + Live Ticker](#2-dashboard)
3. [Propagation Graph β THE WOW FEATURE](#3-propagation-graph-wow)
4. [War Room β Cinematic Incident Command](#4-war-room)
5. [Supply Map β Animated Shock Corridors](#5-supply-map)
6. [Query Interface β Streaming Analyst](#6-query-interface)
7. [Alerts Feed β Live Signal Wall](#7-alerts-feed)
8. [Global Bug Fixes & UX Hardening](#8-global-bug-fixes)
9. [Demo Mode β Autopilot & Keyboard Shortcuts](#9-demo-mode)
10. [Deployment β Docker + Railway/Render](#10-deployment)
---
## 1. Design System Overhaul
> **Run this first. Everything else builds on this.**
```
I am building ShockMap β a real-time supply shock intelligence platform for India's critical import dependencies (pharma APIs, rare earth minerals). The stack is React 19 + Vite + Tailwind CSS + FastAPI. Judges are Google engineers evaluating real-world impact and technical polish.
I need you to implement a complete design system in `frontend/src/styles/tokens.css` and a global `theme.ts` config. The aesthetic is **military-grade command center + editorial data journalism** β think Bloomberg Terminal meets a dark ops war room. NOT purple-gradient AI slop.
Design decisions to commit to:
- **Color palette**: Near-black base `#080C10`, with a single electric accent `#00E5A0` (toxic teal for active/safe states) and `#FF4444` (alarm red for critical shocks). Muted `#1A2332` for cards. Text: `#E8EDF2` primary, `#6B7E94` secondary.
- **Typography**: Import `Syne` (display headings β bold, slightly condensed geometric) + `JetBrains Mono` (data values, metrics, codes) + `IBM Plex Sans` (body UI text). All via Google Fonts.
- **Motion system**: Define three animation tiers in CSS vars:
- `--anim-instant`: 80ms (micro, hover states)
- `--anim-fast`: 200ms (panel transitions)
- `--anim-slow`: 600ms (page reveals, shock propagation)
- **Data states**: CSS classes for `state-critical` (red pulse glow), `state-elevated` (amber), `state-normal` (teal), `state-stale` (grey). Each should have a subtle animated border-glow keyframe.
- **Card system**: `.card-glass` β dark semi-transparent background, 1px border using `rgba(255,255,255,0.06)`, subtle inset shadow, no border-radius above 8px (this is ops software, not a consumer app).
- **Grid**: Define a strict 12-column CSS grid. Include `.grid-dashboard` (3 cols large, 2 medium, 1 small) and `.grid-detail` (sidebar + main).
- **Scrollbars**: Custom thin scrollbar in the accent color.
Also create `frontend/src/components/ui/` with these base components:
- `<RiskBadge level="critical|elevated|normal" />` β animated pill with pulsing dot
- `<MetricCard title value delta trend />` β large mono number, small label, optional sparkline div slot
- `<SectionHeader title subtitle eyebrow />` β Syne display font, eyebrow in mono caps
- `<LoadingShock />` β a custom loader: animated horizontal scan line, not a spinner
Apply the design system globally in `App.tsx`. The overall feel: someone looking at this should feel like they're in a Bloomberg terminal crossed with a Pentagon situation room.
```
---
## 2. Dashboard
```
In ShockMap's React 19 frontend, I need to rebuild `frontend/src/pages/Dashboard.tsx` with three major enhancements. The design system (Syne + JetBrains Mono + dark command center palette) is already in place.
**Enhancement 1: Animated HHI Concentration Heatmap (replace the static version)**
- Use `react-simple-maps` + custom SVG overlays to render a China province map
- Color provinces using HHI score: a gradient from `#1A2332` (low) β `#FF8800` (medium) β `#FF4444` (critical concentration)
- On load: provinces should fade in with staggered 40ms delays using CSS animation
- On hover: show a tooltip with: Province name, HHI score, top 3 APIs sourced, % of India's supply
- Active shock provinces: add a continuous `pulse-ring` CSS animation (expanding ring, opacity fade) in alarm red
- Use this mock data inline (no API needed): Hebei (HHI: 0.82, APIs: Paracetamol API, 6-APA, Para-aminophenol), Shandong (HHI: 0.71, APIs: Ciprofloxacin API, Metformin), Inner Mongolia (HHI: 0.65, APIs: Rare Earth Oxides, Neodymium)
**Enhancement 2: Real-time Shock Ticker (top of page)**
- A horizontally auto-scrolling ticker bar pinned below the nav
- Each item: severity dot + shock title + province + time-ago
- CSS marquee-style infinite scroll, pausable on hover
- Items pulse red when severity is CRITICAL
- Wire to `/api/v1/shocks` with 30s polling; use mock data if API is offline
**Enhancement 3: System Status Bar (bottom of page)**
- Sticky bottom bar showing: Engine 1 status (live/demo mode indicator), Engine 2 last propagation run timestamp, Engine 3 (Gemini) status (green/grey), total shocks monitored count, feed mode badge
- All values animate in with a typewriter effect on mount
- If `DEMO_MODE=true`, show a distinct amber "DEMO SCENARIO ACTIVE" badge
Keep all existing metric cards but upgrade them to use `<MetricCard>` with a mini sparkline (7-day fake data array is fine).
```
---
## 3. Propagation Graph β WOW
> **This is your single most impressive visual. Spend the most time here.**
```
I need to build the most visually stunning feature of ShockMap: the Shock Propagation Graph in `frontend/src/pages/GraphExplorer.tsx`. This must be the "jaw-drop" moment for Google Solution Challenge judges. Use React 19 + Vite. The design system (dark command center, Syne/JetBrains Mono) is in place.
**Library**: Use `@react-sigma/core` with `graphology` (Sigma.js v3). This handles large graph rendering at 60fps in WebGL. Install: `npm install @react-sigma/core graphology graphology-layout-forceatlas2 sigma`.
**Graph Data (use this mock, no API needed):**
```json
{
"nodes": [
{"id": "hebei", "label": "Hebei Province", "type": "province", "risk": 95, "x": 0, "y": 0},
{"id": "pap", "label": "Para-Aminophenol", "type": "ksm", "risk": 88, "x": 1, "y": 1},
{"id": "6apa", "label": "6-APA", "type": "ksm", "risk": 72, "x": 1, "y": -1},
{"id": "paracetamol_api", "label": "Paracetamol API", "type": "api", "risk": 85, "x": 2, "y": 1},
{"id": "amoxicillin_api", "label": "Amoxicillin API", "type": "api", "risk": 68, "x": 2, "y": -1},
{"id": "paracetamol", "label": "Paracetamol", "type": "drug", "risk": 82, "x": 3, "y": 1.5},
{"id": "ceftriaxone", "label": "Ceftriaxone", "type": "drug", "risk": 74, "x": 3, "y": 0},
{"id": "amoxicillin", "label": "Amoxicillin", "type": "drug", "risk": 65, "x": 3, "y": -1.5},
{"id": "shandong", "label": "Shandong Province", "type": "province", "risk": 45, "x": 0, "y": -3},
{"id": "ciprofloxacin_api", "label": "Ciprofloxacin API", "type": "api", "risk": 40, "x": 2, "y": -3},
{"id": "ciprofloxacin", "label": "Ciprofloxacin", "type": "drug", "risk": 38, "x": 3, "y": -3}
],
"edges": [
{"source": "hebei", "target": "pap", "weight": 0.9},
{"source": "hebei", "target": "6apa", "weight": 0.7},
{"source": "pap", "target": "paracetamol_api", "weight": 0.85},
{"source": "6apa", "target": "amoxicillin_api", "weight": 0.68},
{"source": "paracetamol_api", "target": "paracetamol", "weight": 0.82},
{"source": "paracetamol_api", "target": "ceftriaxone", "weight": 0.6},
{"source": "amoxicillin_api", "target": "amoxicillin", "weight": 0.65},
{"source": "shandong", "target": "ciprofloxacin_api", "weight": 0.4},
{"source": "ciprofloxacin_api", "target": "ciprofloxacin", "weight": 0.38}
]
}
```
**Visual specifications β this is what makes it WOW:**
1. **Node appearance by type:**
- `province`: large hexagon shape, bright red glow if risk > 70, with a slow rotating outer ring animation
- `ksm` (key starting material): medium diamond shape, amber
- `api`: medium circle, orange-red gradient based on risk score
- `drug`: rounded square, color interpolated from green (risk 0) to red (risk 100)
- All nodes: size proportional to risk score (min 8px, max 30px)
- Node label: show below, JetBrains Mono font, small
2. **Edge appearance:**
- Edge width proportional to `weight`
- Color: interpolate from `#334455` (low risk) to `#FF4444` (high risk path)
- **Animated shock pulse**: When a shock is "active" on a node, animate a glowing particle traveling along each outgoing edge β a bright dot that moves from source to target repeatedly. This is the single most impressive visual. Implement using a CSS/SVG overlay or Sigma's edge renderer with a custom `drawEdge` that uses a time-based offset to place a bright circle along the edge path.
3. **Interactions:**
- Click a node: right panel slides in showing node details (risk score, buffer days, substitutability, upstream/downstream list)
- Hover: edge highlights in bright white, connected nodes glow
- "Trigger Shock" button: clicking this on a province node animates a ripple outward β all connected nodes briefly flash their risk color, with a 150ms stagger per hop
4. **Layout:**
- Left: full-height Sigma canvas (WebGL)
- Right: 320px sliding details panel (transforms in from right)
- Top: filter bar β filter by node type, min risk threshold slider
5. **Metrics overlay (top-left corner of canvas):**
- Semi-transparent card showing: Nodes at risk: X, Critical paths: Y, Avg propagation depth: Z
- These animate as numbers count up on mount
6. **Background**: Dark canvas `#080C10` with a very subtle dot grid pattern using CSS `radial-gradient`
Make all interactions smooth, 60fps. No page reloads.
```
---
## 4. War Room
```
Rebuild `frontend/src/pages/WarRoom.tsx` (the Shock Detail page) for ShockMap. This is the "command center" moment judges will remember. Design system is in place (dark, Syne/JetBrains Mono). Mock data is fine.
**Mock shock data to use:**
- Shock: "Hebei Analgesic Stress β Factory Shutdown"
- Severity: CRITICAL
- Province: Hebei, China
- Affected drugs: Paracetamol (risk 82), Ceftriaxone (risk 74)
- Days to stockout: 18
- Exposure estimate: βΉ2,340 Cr
- Aggregate risk score: 87/100
**Enhancement 1: Cinematic Page Entry**
- On mount: the page enters with a full-screen flash of alarm red (200ms), then fades to the dark background. This signals "incident activated."
- The title "WAR ROOM" appears with a glitch text effect (3-frame flicker using CSS animation) in JetBrains Mono caps
- Severity badge drops in from top with a bounce-settle easing
**Enhancement 2: Days-to-Stockout Countdown**
- Replace the static metric with an animated circular arc gauge
- The arc fills clockwise, colored from red (0 days) through amber (14 days) to green (30+ days)
- Current value in large JetBrains Mono in center
- On load, it counts up from 0 to the actual value over 1.2 seconds with easeOutCubic
**Enhancement 3: 72-Hour Action Ladder**
- Each action card shows: priority number, action title, quantity/amount, estimated cost, and impact delta
- Use this mock data:
- Action 1: "Advance-buy 18 MT Para-Aminophenol from alternate Indian supplier" β Cost: βΉ4.2 Cr β Impact: -12 risk pts, +8 days
- Action 2: "Lock 40 MT Paracetamol API from SE Asia spot market" β Cost: βΉ18 Cr β Impact: -20 risk pts, +12 days
- Action 3: "Activate strategic buffer release for Ceftriaxone" β Cost: βΉ0 β Impact: -8 risk pts, +5 days
- Each card has a "βΆ Run Simulation" button
- When clicked: the card expands to show a before/after delta panel:
- Aggregate Risk: 87 β 67 (animated counter)
- Days to Stockout: 18 β 26 (animated counter)
- Exposure: βΉ2,340 Cr β βΉ1,890 Cr
- A green checkmark animates in with a subtle bounce
- Only one simulation can be "active" at a time
**Enhancement 4: Evidence Pack**
- A collapsible section showing 3 source articles as citation cards
- Each card: favicon placeholder, headline, source name, timestamp, a one-line excerpt
- Use mock sources: Reuters, Bloomberg, DGFT India notification
- Cards fan in with 80ms stagger on expand
**Enhancement 5: Propagation Path Visual (mini)**
- A horizontal flow diagram showing: Hebei β PAP β Paracetamol API β Paracetamol
- Nodes are colored by risk, connected by animated dashed lines
- Each node shows risk score below it
- Clicking any node opens the full Graph Explorer in a new tab
Layout: two-column. Left col (60%): shock summary, countdown gauge, propagation mini-map, evidence. Right col (40%): sticky action ladder.
```
---
## 5. Supply Map
```
Upgrade `frontend/src/pages/SupplyMap.tsx` in ShockMap (React 19 + Leaflet/react-leaflet). The design system is in place. This page shows supply corridors from China provinces to Indian states.
**Enhancement 1: Animated Supply Corridors**
Using Leaflet's SVG overlay, draw animated "flow lines" between source provinces and destination states:
- Each corridor is an SVG path (great-circle arc) between coordinates
- Animate small bright dots traveling along each path continuously (like a pulse in a circuit board)
- Corridor width proportional to trade volume (use mock weights)
- Corridor color: `#00E5A0` (healthy flow) β `#FF4444` (disrupted flow)
- When a province has an active shock: the corridor flashes and the dots speed up + turn red
**Mock corridors to render:**
```json
[
{"from": [39.9, 116.4], "to": [28.7, 77.1], "label": "Hebei β Delhi NCR", "volume": 0.9, "disrupted": true},
{"from": [36.7, 117.0], "to": [19.1, 72.9], "label": "Shandong β Mumbai", "volume": 0.7, "disrupted": false},
{"from": [41.8, 123.4], "to": [12.9, 77.6], "label": "Liaoning β Bangalore", "volume": 0.5, "disrupted": false},
{"from": [40.8, 111.7], "to": [22.6, 88.4], "label": "Inner Mongolia β Kolkata", "volume": 0.6, "disrupted": true}
]
```
**Enhancement 2: Province Shock Overlays**
- Use GeoJSON for Chinese provinces (use a CDN-hosted simplified version)
- Fill provinces by current risk: dark base β amber β red
- Active shock provinces: add a pulsing circle marker with 3 expanding rings (CSS animation via Leaflet DivIcon)
- Clicking a province: popup card showing shock summary + "Open War Room" button
**Enhancement 3: Indian State Risk Absorption View**
- Toggle button: "Source View" / "Impact View"
- In Impact View: color Indian states by absorbed downstream risk (Maharashtra high, Delhi NCR high, others lower)
- Tooltip on hover: state name, # of APIs at risk, top exposed medicine
**Enhancement 4: Map UI Polish**
- Use a dark map tile: `https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png`
- Custom zoom controls (styled to match the command center theme)
- A legend card (bottom left): explaining the corridor color coding
- Fit map bounds to show both China and India on load with smooth flyTo animation
```
---
## 6. Query Interface
```
Rebuild `frontend/src/pages/QueryPage.tsx` for ShockMap's "Operator Analyst" feature powered by Gemini Flash via `/api/v1/query`. Design system in place.
**Enhancement 1: Streaming Typewriter Response**
- When the API returns an answer, render it character-by-character with a 12ms delay per character using a streaming typewriter effect
- Show a blinking cursor `β` (JetBrains Mono) while streaming
- Implement this even if the API returns all at once (fake the stream on the frontend)
**Enhancement 2: Suggested Query Chips**
- Below the input, show 4 pre-built query chips:
- "Which drugs depend most on Hebei?"
- "What should procurement do in the next 72 hours?"
- "Which APIs have substitutes available?"
- "Show me the highest risk propagation path"
- Chips are pill-shaped, dark background, teal border, hover glow
- Clicking a chip populates the input and auto-submits after 300ms
**Enhancement 3: Response Cards with Citations**
Structure every response as:
- Main answer block (typewriter animated)
- A "Referenced entities" section: small cards for each drug/API mentioned with its current risk badge
- A "Suggested next steps" section: 2-3 action bullets with arrow icons
- A "Confidence" indicator: 3 dots, filled based on score (use mock: 0.87)
Use this mock response for when the API is offline (graceful degradation):
> "Based on current shock data, Paracetamol and Ceftriaxone face the highest downstream risk from the Hebei disruption. Para-Aminophenol sourcing is the critical bottleneck. Recommend immediate spot-market sourcing from SE Asia and activation of DGFT buffer release protocols within 24 hours."
**Enhancement 4: Query History**
- Left sidebar (240px) showing past queries in the current session
- Each entry: truncated query text + timestamp + a small risk-level dot
- Click to reload that response
- "Clear history" button at bottom
**Enhancement 5: Input UX**
- Large, prominent input with placeholder "Ask ShockMap anything about current supply risks..."
- CMD+Enter submits
- Textarea auto-expands (max 4 lines)
- Show a character count warning at 280+ chars
- Subtle animated border glow on focus using the teal accent
```
---
## 7. Alerts Feed
```
Upgrade `frontend/src/pages/AlertsFeed.tsx` for ShockMap. Design system in place.
**Enhancement 1: Live Signal Wall Layout**
Change the layout from a plain list to a "signal wall" β 3-column masonry-style card grid (CSS columns, not JS masonry).
Each alert card shows:
- Severity badge (CRITICAL / ELEVATED / NORMAL) with animated pulse dot
- Shock type icon (factory: π, port: β, export ban: π«, contamination: βοΈ β rendered as styled SVG, not emoji)
- Province + sector tags
- Headline in Syne medium weight
- Time since detected (live-updating relative time: "4 minutes ago")
- Affected entities list (max 3 drug names, then "+2 more")
- A thin progress bar at card bottom showing risk score 0-100
**Enhancement 2: Filter Bar**
- Horizontal filter row with toggle pills: All / Critical / Elevated / Pharma / Rare Earth / China / India
- Active filter highlighted in teal
- Filter transitions: cards that don't match fade to 30% opacity + blur (CSS transition, no re-render)
**Enhancement 3: New Alert Animation**
- When a new alert arrives (poll every 15s), it doesn't just append β it slides in from the top with a brief red flash border, then settles
- A "NEW" badge appears for 8 seconds then fades
**Enhancement 4: Card Hover State**
- On hover: card lifts (translateY -4px), border brightens to the risk-level color, a subtle scanline effect sweeps across
- "Open War Room" CTA appears with a slide-up from card bottom
Use 6 mock alerts in varying severity levels if the API is unavailable.
```
---
## 8. Global Bug Fixes & UX Hardening
```
Apply these cross-cutting fixes and polish to all pages of ShockMap (React 19 + Vite + Tailwind + FastAPI backend):
**Fix 1: API Offline Graceful Degradation**
In `frontend/src/lib/api.ts`, wrap every fetch call with a try-catch that:
- Catches network errors and 5xx responses
- Returns mock data from `frontend/src/lib/mockData.ts` automatically
- Shows a subtle amber banner "Using demo data β live API offline" at the top of the page
- Does NOT crash the app or show blank screens
Create `frontend/src/lib/mockData.ts` with realistic mock responses for every endpoint: `/shocks`, `/shocks/:id/war-room`, `/graph`, `/query`.
**Fix 2: Loading States**
Every page that fetches data must show the custom `<LoadingShock />` component (the scanline loader) while loading, not a blank screen or default spinner.
**Fix 3: Empty States**
If the shocks list is empty, show an illustrated empty state: a dark card with a pulsing radar circle animation and text "No active shocks detected β system monitoring". Not a blank div.
**Fix 4: Mobile Responsiveness (basic)**
The judges may view on a tablet. Add responsive breakpoints:
- Nav collapses to hamburger below 768px
- Dashboard grid goes to 1 column
- War Room stacks vertically (action ladder moves below shock summary)
- Graph Explorer shows a message "Best viewed on desktop" with a simplified node list fallback
**Fix 5: Page Transitions**
Wrap all `<Route>` components in a fade transition using Framer Motion `<AnimatePresence>`. Each page enters with `opacity: 0 β 1` + `translateY: 8px β 0` over 250ms. This makes navigation feel polished and intentional.
**Fix 6: Navigation Active States**
The nav currently doesn't clearly show which page is active. Add: active page gets a left border accent in teal + background highlight. Non-active items have a hover state.
**Fix 7: Number Formatting**
All risk scores, currency values, and percentages should be formatted consistently using `Intl.NumberFormat`. βΉ2340 Cr should display as "βΉ2,340 Cr". Risk score 82.3456 should display as "82.3".
**Fix 8: Favicon and Page Titles**
- Create a simple SVG favicon: a hexagon with a lightning bolt inside, in the teal accent color
- Set dynamic `document.title` per page: "War Room β Hebei Shock | ShockMap", "Dashboard | ShockMap", etc.
```
---
## 9. Demo Mode β Autopilot & Keyboard Shortcuts
```
Add a demo autopilot system to ShockMap for the hackathon presentation. This lets the presenter run a flawless demo hands-free.
**Component: `<DemoController />`**
Create `frontend/src/components/DemoController.tsx` β a floating controller (bottom-right corner, outside normal flow):
- A small "DEMO" pill button that expands on click to show controls
- **Autopilot mode**: walks through the golden path automatically:
1. Navigate to Dashboard (3s pause, HHI map animates in)
2. Navigate to Alerts, highlight the Hebei CRITICAL shock (2s)
3. Navigate to War Room for that shock (auto-opens)
4. Wait 3s, then auto-click "Run Simulation" on Action 1
5. Wait 3s, navigate to Graph Explorer, trigger the shock ripple animation
6. Wait 4s, navigate to Query, auto-type and submit "What should procurement do about the Hebei shutdown?"
7. Loop back to Dashboard
**Keyboard shortcuts** (active globally, shown in a help modal on `?` key):
- `D` β Dashboard
- `A` β Alerts
- `W` β War Room (most recent critical shock)
- `G` β Graph Explorer
- `Q` β Query
- `Space` β trigger shock ripple on Graph page (if open)
- `S` β run simulation on War Room (if open)
- `Escape` β close any open panel
**Demo Reset button**: One click resets all simulation states, clears query history, and returns to Dashboard. Useful between judge demos.
Show a subtle keyboard shortcut hint bar at the bottom of each page (dismissible, only shown in DEMO_MODE).
```
---
## 10. Deployment
```
Set up production deployment for ShockMap. Stack: React 19 + Vite (frontend), FastAPI + Python (backend). I want to deploy cheaply and reliably for the hackathon demo.
**Step 1: Docker Setup**
Create `backend/Dockerfile`:
- Base: `python:3.11-slim`
- Install deps from `requirements.txt`
- Expose port 8000
- Start with: `uvicorn app.main:app --host 0.0.0.0 --port 8000`
- Include a `.dockerignore` that excludes `__pycache__`, `.env`, `venv`, `*.pyc`
Create `frontend/Dockerfile`:
- Two-stage build: node:20-alpine for build, nginx:alpine for serve
- Build: `npm ci && npm run build`
- Copy `dist/` to nginx html dir
- Add `nginx.conf` that: serves static files, proxies `/api/` β `http://backend:8000/api/`, handles React Router (try_files fallback to index.html)
Create `docker-compose.yml` at project root:
- `backend` service: build from `./backend`, env_file `.env`, ports `8000:8000`
- `frontend` service: build from `./frontend`, ports `80:80`, depends_on backend
- A shared network `shockmap-net`
**Step 2: Environment Config**
Create `backend/.env.example`:
```
GEMINI_API_KEY=your_key_here
DEMO_MODE=true
ALLOWED_ORIGINS=http://localhost,https://your-domain.com
ENABLE_GNN=false
```
In the FastAPI app, load `.env` using `python-dotenv`. Add a startup check that logs which env vars are missing and continues with degraded mode (not crash).
**Step 3: Railway Deployment (recommended for hackathon)**
Create `railway.toml` at project root:
```toml
[build]
builder = "dockerfile"
[deploy]
startCommand = "uvicorn app.main:app --host 0.0.0.0 --port $PORT"
healthcheckPath = "/healthz"
healthcheckTimeout = 30
restartPolicyType = "on_failure"
```
Create `railway-frontend.toml` for the frontend service similarly.
Also create `frontend/vercel.json` for optional Vercel frontend deployment:
```json
{
"rewrites": [
{"source": "/api/:path*", "destination": "https://your-railway-backend.up.railway.app/api/:path*"},
{"source": "/(.*)", "destination": "/index.html"}
]
}
```
**Step 4: Health Check Endpoint**
Ensure `GET /healthz` returns:
```json
{
"status": "ok",
"demo_mode": true,
"engines": {"signal": "ok", "propagation": "ok", "action": "ok"},
"shocks_loaded": 6,
"timestamp": "2026-04-27T10:00:00Z"
}
```
**Step 5: Production Build Check**
Add a `scripts/check_build.sh`:
- Runs `npm run build` in frontend and checks for errors
- Runs `python -c "from app.main import app"` to check backend imports
- Prints "β
Build ready for deployment" or lists errors
**Step 6: README Update**
Update the root `README.md` to include:
- A "Deploy in 5 minutes" section with the Railway one-click instructions
- A "Demo credentials" section (if auth is added)
- Badges: build status, demo mode, license
- A GIF/screenshot placeholder section (add images later)
```
---
## Execution Order
Run these prompts in this sequence for best results:
```
1 β Design System (foundation, do first)
2 β Dashboard (first page judges see)
3 β Propagation Graph (the wow moment β most effort)
4 β War Room (core MVP value)
5 β Supply Map (visual depth)
8 β Bug Fixes (stability before showing anything else)
9 β Demo Mode (last before deployment)
10 β Deployment (final step)
6 β Query Interface (can be parallel with 5)
7 β Alerts Feed (can be parallel with 6)
```
---
## Rare Techniques Worth Mentioning to Judges
These are implemented in the prompts above but worth calling out explicitly during the demo:
| Technique | Where | Why It Impresses |
|---|---|---|
| **Personalized PageRank** | Engine 2 | Not just BFS β directional probabilistic influence flow |
| **Louvain Community Detection** | Engine 2 | Co-propagating cluster identification (graph theory) |
| **WebGL-rendered graph** (Sigma.js) | Graph Explorer | 60fps with hundreds of nodes β not a D3 toy |
| **Animated particle flow on edges** | Graph Explorer | Unique visual β shock literally "flows" through graph |
| **Schema-constrained Gemini output** | Engine 3 | Deterministic JSON from LLM β production-safe |
| **HHI concentration index** | Dashboard | Economic inequality metric applied to supply chains |
| **Propagation formula with decay** | Engine 2 | Physics-inspired: `R = PR * (1-S) * exp(-B/Ο) * C` |
| **Demo autopilot** | DemoController | Shows product thinking beyond just code |
---
*Built for Google Solution Challenge 2026 β Phase 1: ShockMap MVP*
|