# Externalize OpenWeatherMap API key

**Task**: AZ-448_refactor_owm_api_key
**Name**: Externalize OWM API key to VITE_OWM_API_KEY
**Description**: Move the hardcoded OpenWeatherMap API key from `flightPlanUtils.ts` into a Vite-driven env var so it can be redacted in source and overridden in the test profiles.
**Complexity**: 2 points
**Dependencies**: None
**Component**: `src/features/flights/flightPlanUtils.ts`, `.env.example`, `src/vite-env.d.ts`
**Tracker**: AZ-448
**Epic**: AZ-447

## Problem

`src/features/flights/flightPlanUtils.ts:60` inlines `const apiKey = '335799082893fad97fa36118b131f919'`. The literal:

- Violates restriction O6 (no hardcoded credentials) and AC-O6 (`acceptance_criteria.md`).
- Blocks the security static check NFT-SEC-09 (results_report.md row 63 — quarantined until this fix lands).
- Prevents the e2e profile's `owm-stub` from intercepting OWM calls deterministically.

## Outcome

- Source tree has no literal OWM key string after the change.
- The fast and e2e test profiles can supply test-time keys via env vars without touching source.
- NFT-SEC-09 source-string check (`scripts/run-tests.sh --static-only`) passes.

## Scope

### Included
- Reading `import.meta.env.VITE_OWM_API_KEY` at call time inside `getWeatherData`.
- Adding `.env.example` (workspace-root) documenting the variable.
- Extending the `ImportMetaEnv` type in `src/vite-env.d.ts`.

### Excluded
- Changing the `getWeatherData(lat, lon)` signature or callers.
- Reworking the weather-fetch error handling — only the key sourcing changes.
- Touching the OWM base URL (that is C02 / AZ-449).

## Acceptance Criteria

**AC-1: Key sourcing**
Given the SPA is built with `VITE_OWM_API_KEY=<key>` in the environment,
When `getWeatherData(lat, lon)` is invoked,
Then the resulting HTTP request URL contains `appid=<key>`.

**AC-2: No literal in source**
Given a `grep -r "335799082893fad97fa36118b131f919" src/` after the change,
When the grep runs,
Then the literal key produces no matches.

**AC-3: Missing-env tolerance**
Given the SPA is built with `VITE_OWM_API_KEY` unset,
When `getWeatherData(lat, lon)` is invoked,
Then it returns `null` (matches the existing try/catch fallback) and does NOT throw.

**AC-4: Type declaration**
Given a TypeScript build (`bun run build`),
When the env interface is resolved,
Then `ImportMetaEnv` in `src/vite-env.d.ts` declares `readonly VITE_OWM_API_KEY: string | undefined`.

## Non-Functional Requirements

**Compatibility**
- Build tooling pinned to Vite 6 (S3) — `import.meta.env` is built-in; no new dependency.

**Security**
- `.env.example` MUST use a placeholder (`<your-key>`) — never check in the production key.

## Blackbox Tests

| AC Ref | Initial Data / Conditions | What to Test | Expected Behavior | NFR References |
|--------|--------------------------|--------------|-------------------|----------------|
| AC-1   | `VITE_OWM_API_KEY=test-key-123` set at build; `getWeatherData(0, 0)` called | Outbound fetch URL contains `appid=test-key-123` | Pass | — |
| AC-2   | Repo state after task lands | `grep -r "335799082893fad97fa36118b131f919" src/` | No matches | Security |
| AC-3   | `VITE_OWM_API_KEY` undefined at build; `getWeatherData(0, 0)` called | Function returns null without throwing | Pass | — |
| AC-4   | Repo state after task lands | `src/vite-env.d.ts` extends `ImportMetaEnv` with the field | Declaration present | Compat |

## Constraints

- Adhere to S3 (Vite 6) and the existing project tooling — no new dependency, no `process.env` polyfill.
- Adhere to AC-N4 (no signature library) — env-driven config only.

## Risks & Mitigation

**Risk 1: Build-time leakage**
- *Risk*: Vite inlines `import.meta.env.VITE_*` at build time, so a build run with the production key embedded into `dist/` leaks the key into the bundle.
- *Mitigation*: This is a known Vite behavior, identical to today's hardcoded key. Long-term fix is to proxy OWM through the suite's `loader/` (per E10) — out of scope for this testability task; flagged for Phase B.
