# Architecture

## 1. High-Level View

MarketPulse is a client-side SPA in a single HTML document.

```text
Browser UI (HTML + Bootstrap)
        |
State + Event Handlers (JS in dash.html)
        |
  Finnhub REST API
```

## 2. Layers

### Presentation Layer

- Dashboard cards
- Watchlist management views
- Preferences and API test panels
- Debug console

### Application Layer

- Refresh coordinator (`refreshAll`)
- Preference manager (`loadPrefs`, `savePref`)
- Watchlist selection/render flow
- Error/partial-success reporting

### Data Layer

- Local storage/session storage wrappers
- In-memory caches (`quoteCache`)
- Remote API retrieval via fetch wrappers
- Dedicated DJI endpoint (`api/getDji.php`) for dashboard Dow card
- Generic index endpoint (`api/getIndex.php`) for dashboard index cards

## 2.1 DJI Quote Path

The dashboard's Dow Jones card uses a small server endpoint first, then falls back to provider quotes:

1. `fetchIndices()` calls `fetchDjiFromEndpoint()`.
2. `fetchDjiFromEndpoint()` queries `api/getDji.php?id=a6qja2` (with path fallbacks).
3. Endpoint returns `{ close, change, pct }` sourced from MSN Finance Quotes.
4. UI maps values to `setIdx('DJI', close, change, pct)`.
5. If endpoint fetch fails, app falls back to `getQuote('DJI' or '^DJI')`.

## 2.2 Multi-Index Endpoint Path

The dashboard now applies the endpoint-first pattern across index cards:

1. `fetchIndices()` calls `fetchIndexFromEndpoint()` for `dji`, `nasdaq`, `sp500`, and `vix`.
2. `fetchIndexFromEndpoint()` queries `api/getIndex.php?index=<key>` (with path fallbacks).
3. Endpoint maps known MSN IDs for `dji`, `nasdaq`, and `sp500` and returns `{ close, change, pct }`.
4. UI maps values via `setIdx()`.
5. If endpoint fetch fails (or mapping is not configured, such as current `vix`), app falls back to provider quotes.

## 3. Refresh Flow

1. `refreshAll()` acquires in-flight lock.
2. Fetch market status.
3. Conditionally enqueue panel fetches by preferences.
4. Fetch watchlist cards for selected lists.
5. Await all with `Promise.allSettled`.
6. Render status and detailed diagnostics.

## 4. Persistence Model

- `mp_api_key`: API key
- `mp_wl2`: watchlist map
- `mp_prefs2`: UI and behavior preferences

## 5. Error Handling Strategy

- Per-component try/catch where practical.
- Null checks before DOM updates.
- Settled promise aggregation for partial results.
- Debug logging with context-rich messages.

## 6. Security Notes

- API key is stored in browser storage (client-side risk accepted for local/private use).
- No server-side proxy/token shielding in current architecture.

## 7. Evolution Path

- Move API key handling behind server proxy.
- Break script into modules.
- Add automated unit/integration tests.
- Add typed contracts (TypeScript or JSDoc + linting).
