[← Back to Reviews Index](../Stewards%20Reviews%20Index.md)

# React Telemetry Review — Azure-AI-RAG-CSharp-Semantic-Kernel-Functions

**Steward:** React Telemetry Steward
**Project:** Azure-AI-RAG-CSharp-Semantic-Kernel-Functions
**Run date:** 2026-03-21
**Scope:** React frontend at `src/web/`

---

## 1. Frontend Telemetry Overview

The React frontend is a single-page application built with Create React App (React 18, React Router v6, MUI v5). It consists of seven source files:

| File | Role |
|---|---|
| `src/index.js` | App bootstrap |
| `src/App.js` | Root router |
| `src/Main.js` | Page shell |
| `src/SupportAgent/Agent.js` | Core chat interaction component |
| `src/SupportAgent/ChatLayout.js` | Message rendering |
| `src/AzureFreeAccount.js` | Promotional banner |
| `src/AzureServiceCards.js` | Promotional cards |
| `src/reportWebVitals.js` | Web Vitals hook (not wired to any endpoint) |

**Telemetry status: Zero business-event telemetry is implemented.** No analytics library (Application Insights, Google Analytics, Mixpanel, Segment, Amplitude, Datadog RUM, or any equivalent) is installed, imported, or called anywhere in the application source. The `package.json` lists no telemetry dependency. The `reportWebVitals` function is scaffolded by Create React App but is called without a callback in `index.js`, so no data is collected or forwarded. The only runtime observation present is a single `console.log(res)` in `Agent.js` — a development debug statement, not a telemetry call.

---

## 2. Business Event Coverage Map

| User Interaction | Expected Event Name | Status |
|---|---|---|
| Application loaded / page view | `page_view` | Missing |
| Session created (on mount) | `session_created` | Missing |
| Chat message submitted by user | `chat_message_sent` | Missing |
| AI response received (success) | `chat_response_received` | Missing |
| AI response failed (network/API error) | `chat_response_failed` | Missing |
| Session fetch failed | `session_fetch_failed` | Missing |
| Chat input changed (typing started) | `chat_input_started` | Missing |
| CTA button clicked ("Start free") | `cta_clicked` | Missing |
| CTA button clicked ("Pay as you go") | `cta_clicked` | Missing |
| "View all services" link clicked | `service_link_clicked` | Missing |

All interactions: **0 of 10 tracked (0%).**

---

## 3. Event Naming Assessment

No events exist to evaluate. For reference, the recommended naming convention for this application is `snake_case` verb-noun (e.g., `chat_message_sent`, `session_created`, `chat_response_received`). This convention is consistent with common analytics platforms (Application Insights custom events, GA4, Segment) and avoids implementation-detail names.

---

## 4. Payload Quality Assessment

No events exist to evaluate. For the events that should be added, the recommended minimum payload is:

```json
{
  "sessionId": "<session_id from API>",
  "timestamp": "<ISO 8601>",
  "properties": {
    // event-specific fields — see §7
  }
}
```

**Sensitive data risk:** `Agent.js` sends the full user prompt text to the API (`body: JSON.stringify({ input: prompt, sessionid: session })`). If telemetry were naively added by logging the full `prompt` value, it could capture free-text user input containing PII. Any telemetry addition must anonymize or omit message content, logging only metadata (prompt length, session ID, response time).

---

## 5. User Journey Coverage Assessment

The primary user journey for this application:

```
1. Land on page
2. Session initialized (auto, on mount)
3. User types a message
4. User submits message (clicks Submit)
5. API call in flight
6. Response rendered in chat
```

| Journey Step | Telemetry Present | Notes |
|---|---|---|
| 1. Page load | No | No page-view event |
| 2. Session initialized | No | `handleSession()` fires silently on mount |
| 3. User types message | No | `onChange` handler only updates state |
| 4. Message submitted | No | `handlePrompt()` fires no telemetry |
| 5. API response received | No | `.then()` only updates state |
| 6. API error | No | No `.catch()` handler exists at all — errors are silently swallowed |

Funnel tracking is impossible: there is no data to identify where users drop off, how many users send messages, or whether the AI responses succeed.

The absence of any `.catch()` on the two `fetch()` calls in `Agent.js` is particularly significant: network errors and non-2xx responses without a JSON body will cause unhandled promise rejections with no user feedback and no error telemetry.

---

## 6. Findings

### RTEL-COVERAGE-001 — No business-event telemetry on primary user journey
**Severity:** 🔴 Critical

The entire primary user journey (page load → session creation → message send → response receive) has zero telemetry instrumentation. There is no analytics library installed and no tracking calls anywhere in the React source. It is impossible to measure usage, success rates, error rates, or user drop-off for this application.

**File:** `src/web/src/SupportAgent/Agent.js`

---

### RTEL-COVERAGE-002 — No telemetry library installed
**Severity:** 🔴 Critical

`package.json` lists no analytics or telemetry dependency. Nothing in `@microsoft/applicationinsights-web`, `@azure/monitor-opentelemetry`, Google Analytics, Segment, Mixpanel, Amplitude, or any equivalent is present. The `reportWebVitals` scaffold is the only hint of observability intent, and it is not wired to any endpoint.

**File:** `src/web/package.json`

---

### RTEL-ERROR-001 — API errors are silently swallowed — no error telemetry possible
**Severity:** 🔴 Critical

Both `fetch()` calls in `Agent.js` — the session fetch (`handleSession`) and the chat fetch (`handlePrompt`) — have no `.catch()` handler. A network failure, CORS error, or non-JSON response will produce an unhandled promise rejection. The user receives no feedback, and there is no error telemetry pathway. Even if telemetry were added, there is no hook to emit `chat_response_failed` or `session_fetch_failed` events.

**File:** `src/web/src/SupportAgent/Agent.js`, lines 29–44 and 48–52

---

### RTEL-COVERAGE-003 — Session lifecycle has no telemetry
**Severity:** 🟡 Notable

The `handleSession()` function on mount is the entry point that initializes every user's interaction context. Neither a successful session creation nor a failure is tracked. Without a `session_created` event (carrying the session ID and a timestamp), it is impossible to correlate downstream chat events to individual sessions or measure session creation failure rates.

**File:** `src/web/src/SupportAgent/Agent.js`, lines 47–53

---

### RTEL-COVERAGE-004 — Chat message submission has no telemetry
**Severity:** 🟡 Notable

`handlePrompt()` is the core user-facing action in this application. Submitting a message is the primary conversion event. No `chat_message_sent` event is emitted before the fetch, and no `chat_response_received` or `chat_response_failed` event is emitted after. There is no way to measure message volume, response latency, or success rate.

**File:** `src/web/src/SupportAgent/Agent.js`, lines 22–45

---

### RTEL-VITALS-001 — Web Vitals scaffold is wired to no endpoint
**Severity:** 🟢 Minor

`reportWebVitals` is scaffolded and imported correctly, but `index.js` calls `reportWebVitals()` with no callback. The CLS, FID, FCP, LCP, and TTFB metrics are imported but discarded. This means even the performance telemetry that CRA provides out of the box is not collected.

**File:** `src/web/src/index.js`, line 20

---

### RTEL-NAMING-001 — Debug console.log left in production chat handler
**Severity:** 🟢 Minor

`Agent.js` line 38 contains `console.log(res)` inside the chat response handler. This is a development debug statement. It logs the full API response object to the browser console in production builds. While not a telemetry call, it indicates instrumentation was considered but implemented only at debug level rather than through a proper telemetry channel.

**File:** `src/web/src/SupportAgent/Agent.js`, line 38

---

### RTEL-PAYLOAD-001 — Full user prompt text must not appear in telemetry payloads
**Severity:** ℹ️ Info (pre-emptive risk notice)

When telemetry is added, the `prompt` variable in `handlePrompt()` contains raw, free-text user input. This text must not be included as-is in any telemetry event payload, as it may contain PII. Telemetry events should log only metadata: prompt character length, session ID, a request correlation ID, and response latency.

**File:** `src/web/src/SupportAgent/Agent.js`, line 23

---

## 7. Recommended Telemetry Additions

The following additions address all findings. The recommended telemetry library is `@microsoft/applicationinsights-web`, consistent with the Azure-native stack used in this project.

### 7.1 Install Application Insights (or equivalent)

```
npm install @microsoft/applicationinsights-web
```

Create a singleton telemetry client (e.g., `src/telemetry.js`) initialized with the Instrumentation Key or Connection String from environment config (`REACT_APP_APPINSIGHTS_CONNECTION_STRING`). Do not hardcode connection strings.

### 7.2 Wire Web Vitals to the telemetry endpoint

In `index.js`:
```js
reportWebVitals(metric => appInsights.trackMetric({ name: metric.name, average: metric.value }));
```

### 7.3 Track page view on app load

In `App.js` or `index.js`, emit a `page_view` event once on mount.

### 7.4 Track session lifecycle in `Agent.js`

In `handleSession()`:
- On success: emit `session_created` with `{ sessionId, timestamp }`.
- On error (in a `.catch()` handler): emit `session_fetch_failed` with `{ error: error.message, timestamp }`.

### 7.5 Track chat message submission in `Agent.js`

In `handlePrompt()`:
- Before the fetch: emit `chat_message_sent` with `{ sessionId, promptLength: prompt.length, timestamp }`. Do not include prompt text.
- On success response: emit `chat_response_received` with `{ sessionId, responseLength: res.resp?.length, durationMs, timestamp }`.
- In a `.catch()` handler (new): emit `chat_response_failed` with `{ sessionId, errorMessage: error.message, timestamp }`.

### 7.6 Minimum event payload contract

All events must include:
```json
{
  "sessionId": "<string>",
  "timestamp": "<ISO 8601 string>",
  "properties": { /* event-specific */ }
}
```

Events must never include: raw message text, auth tokens, or full API response bodies.

---

*Review generated by React Telemetry Steward — 2026-03-21*
