You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
│ └── deploy.yml # Deploy to EC2 via SSH with rollback
@@ -171,21 +169,40 @@ GROQ_API_KEY=your_key_here
171
169
172
170
Get a free key at [console.groq.com](https://console.groq.com).
173
171
172
+
### How the AI Gets Context
173
+
174
+
The AI service uses a **context builder** (`_build_data_context`) that assembles a compact text summary of all SpaceX program data before sending it to the LLM. The context includes:
175
+
176
+
-**Missions** — Total launches, success rate, launches by year
177
+
-**Fleet** — Active boosters, landings, landing success rate
178
+
-**Starlink** — Total satellites tracked
179
+
-**Rockets** — Per-rocket launch stats and success rates
180
+
-**Emissions** — CO2 by vehicle, annual trends, fuel breakdown, reuse savings
181
+
-**Economics** — Spend by vehicle, annual trends, top customers, mass by orbit
When `generate_ai_insights` is called from the dashboard, it receives **prefetched data** (rockets, launches, starlink stats, fleet, launchpads) already fetched for the Overview page, avoiding redundant service calls. For chat and fun-fact, the context builder fetches fresh data from the cached services. All data is formatted with markdown-style section headers for the LLM to parse.
| Economics | 5 min | Derived from launches and rockets |
200
+
| Emissions | 5 min | Derived from launches and rockets |
201
+
| Cores | 24 h | Changes infrequently |
202
+
| Launchpads | 24 h | Static infrastructure data |
203
+
| History | 24 h | Historical events, rarely updated |
204
+
| Landing | 24 h | Pad data changes infrequently |
205
+
| Roadster | 24 h | Telemetry updates slowly |
189
206
190
207
**Stampede prevention:** On cache miss, a Redis `SET NX` lock is acquired before calling the SpaceX API. Concurrent requests wait briefly and read from cache once it is populated, avoiding redundant upstream calls.
191
208
@@ -204,7 +221,7 @@ The project maintains strict quality standards enforced through automated toolin
204
221
205
222
| Metric | Value |
206
223
|---|---|
207
-
| Total tests |**445** (203 backend + 242 frontend) |
224
+
| Total tests |**450** (208 backend + 242 frontend) |
| Frontend lint errors |**0** (ESLint, 1 intentional warning for `v-html` in AI chat markdown) |
@@ -222,6 +239,14 @@ The project maintains strict quality standards enforced through automated toolin
222
239
223
240
The frontend is optimized for fast initial load and smooth navigation.
224
241
242
+
**Overview load optimizations (backend):**
243
+
244
+
-**Parallel fetches** — Rockets, launches, Starlink stats, fleet, and launchpads are fetched concurrently via `asyncio.gather`, reducing cold-cache load time by ~40–60%
245
+
-**Prefetched AI context** — When generating insights for the Overview, the AI service receives data already fetched for the dashboard instead of re-fetching, saving ~3–8 seconds
246
+
-**Dashboard cache** — The full `/api/dashboard` response is cached (5 min TTL); subsequent loads return in ~50–200 ms
247
+
-**Latest/next cache** — Latest and next launch endpoints are cached (2 min TTL) to avoid repeated SpaceX API calls
248
+
-**Starlink single request** — Starlink data uses `pagination: false` for one API call instead of 12+ paginated requests
249
+
225
250
**Lazy loading:**
226
251
227
252
- All 11 route views use dynamic `import()` for code splitting
@@ -275,7 +300,7 @@ This project was iteratively evaluated and improved through a structured AI-assi
275
300
| Tests & Coverage | 9.8 | 445 tests, 96% backend coverage, 47 frontend test files covering all views/charts |
|`LAUNCH_NEXT_TTL`|`120`| Next launch cache TTL (2 min) |
89
101
|`CORES_TTL`|`86400`| Cores/fleet cache TTL |
90
102
|`LAUNCHPADS_TTL`|`86400`| Launchpads cache TTL |
91
103
|`HISTORY_TTL`|`86400`| History cache TTL |
@@ -203,7 +215,9 @@ All values can be set via environment variables or a `.env` file. See [.env.exam
203
215
}
204
216
```
205
217
206
-
The AI service uses Groq (Llama 3.3 70B) to generate responses grounded in real SpaceX data. The chat context includes data from all dashboard sources: missions, rockets, fleet/booster stats, Starlink satellites, economics, emissions, historical milestones, landing pads, launch sites, and Roadster telemetry. Chat responses are formatted with markdown (bold, lists, paragraphs). The fun-fact endpoint generates a short, surprising curiosity (max ~25 words) that varies on each call. If `GROQ_API_KEY` is not set, the status endpoint returns `{ "available": false }` and the other AI endpoints return a 503 or helpful message.
218
+
The AI service uses Groq (Llama 3.3 70B) to generate responses grounded in real SpaceX data. Chat responses are formatted with markdown (bold, lists, paragraphs). The fun-fact endpoint generates a short, surprising curiosity (max ~25 words) that varies on each call. If `GROQ_API_KEY` is not set, the status endpoint returns `{ "available": false }` and the other AI endpoints return a 503 or helpful message.
219
+
220
+
**How the AI gets context:** The `_build_data_context` function assembles a compact text summary from all dashboard data sources: missions, rockets, fleet, Starlink, emissions, economics, history, landing pads, launch sites, and Roadster telemetry. When `generate_ai_insights` is called from the dashboard, it receives prefetched data (rockets, launches, starlink stats, fleet, launchpads) already fetched for the Overview, avoiding redundant service calls. For chat and fun-fact, the context builder fetches fresh data from the cached services.
207
221
208
222
**Input sanitization:** The `ChatRequest` schema enforces a 2,000 character limit on messages and uses a `field_validator` to strip common prompt-injection patterns (e.g., `ignore previous instructions`, `system:`, `[INST]`) before the message reaches the LLM. AI endpoints also have dedicated rate limits: chat is limited to 20 requests per minute and fun-fact to 10 requests per minute.
209
223
@@ -257,19 +271,21 @@ Every cacheable resource uses the same pattern:
257
271
258
272
This prevents cache stampedes where many requests would simultaneously hit the upstream API.
0 commit comments