{
  "steward": "react-di-steward",
  "project": "Azure-AI-RAG-CSharp-Semantic-Kernel-Functions",
  "runDate": "2026-03-21",
  "runId": "2026-03-21T00-00-00",
  "findings": [
    {
      "id": "RDI-HOOK-001",
      "title": "No custom hook abstraction for API calls",
      "severity": "notable",
      "category": "HOOK",
      "file": "src/web/src/SupportAgent/Agent.js",
      "line": 22,
      "description": "Both handleSession (GET /session) and handlePrompt (POST /chat) are implemented as inline functions inside Agent.js. API communication logic is directly coupled to the rendering component with no hook abstraction, making the logic untestable in isolation and non-reusable.",
      "recommendation": "Extract fetch logic into a custom hook useChatSession() that returns { session, messages, sendPrompt }. The hook should own URL resolution and AbortController cleanup, and optionally accept a fetcher argument to enable test injection.",
      "status": "open"
    },
    {
      "id": "RDI-TEST-001",
      "title": "Agent component is untestable without real network calls",
      "severity": "notable",
      "category": "TEST",
      "file": "src/web/src/SupportAgent/Agent.js",
      "line": 56,
      "description": "useEffect fires handleSession immediately on component mount. Because fetch is called directly with no injectable seam, rendering <SupportAgent /> in a test environment triggers a real HTTP request. There is no way to render the component in isolation without globally patching window.fetch.",
      "recommendation": "Extract fetch calls into a useChatSession hook. Mock the hook module in tests (jest.mock) to provide controlled state without any network access.",
      "status": "open"
    },
    {
      "id": "RDI-TEST-002",
      "title": "Existing test uses stale CRA scaffold assertion and will fail",
      "severity": "notable",
      "category": "TEST",
      "file": "src/web/src/App.test.js",
      "line": 5,
      "description": "App.test.js searches for the text 'learn react' which is the default CRA scaffold content and does not exist anywhere in the actual application. This test fails on every run. There are no tests for SupportAgent, ChatLayout, AzureFreeAccount, or AzureServiceCards.",
      "recommendation": "Replace the scaffold test with assertions against actual application content. Add ChatLayout.test.js (pure component, easily testable via props) and Agent.test.js once the hook abstraction from RDI-HOOK-001 is in place.",
      "status": "open"
    },
    {
      "id": "RDI-CONFIG-001",
      "title": "API base URL read inline from process.env at multiple call sites",
      "severity": "minor",
      "category": "CONFIG",
      "file": "src/web/src/SupportAgent/Agent.js",
      "line": 29,
      "description": "process.env.REACT_APP_API_HOST is accessed directly at two separate call sites inside Agent.js (lines 29 and 48). There is no centralized URL resolution, so any change to the API base URL or routing logic requires updating every call site individually.",
      "recommendation": "Define API_HOST in a central config module (src/config.js) and import it where needed. The useChatSession hook recommended in RDI-HOOK-001 should own this import, removing the environment variable read from the component entirely.",
      "status": "open"
    },
    {
      "id": "RDI-FETCH-001",
      "title": "No AbortController on in-flight fetch requests",
      "severity": "minor",
      "category": "FETCH",
      "file": "src/web/src/SupportAgent/Agent.js",
      "line": 29,
      "description": "Neither handleSession nor handlePrompt creates an AbortController. If the component unmounts while a fetch is in flight, the .then() callback will call setMessage or setSession on an unmounted component, causing a React state update warning and a potential memory leak.",
      "recommendation": "Use AbortController inside useEffect cleanup and the event handler, or encapsulate this automatically within the useChatSession hook's cleanup function.",
      "status": "open"
    },
    {
      "id": "RDI-CONTEXT-001",
      "title": "No React Context used; no established pattern for cross-cutting concerns",
      "severity": "info",
      "category": "CONTEXT",
      "file": "src/web/src/",
      "description": "The application has no React Context providers, useContext calls, or any established pattern for sharing services or configuration across components. At the current scale (one API-consuming component) this is not harmful, but there is no foundation to grow on without repeating inline access patterns.",
      "recommendation": "As the application grows beyond a single API consumer, introduce an ApiClientContext or AppConfigContext to provide the fetch wrapper and base URL to components. This also serves as the test injection point.",
      "status": "open"
    },
    {
      "id": "RDI-ARCH-001",
      "title": "ChatLayout is a clean, dependency-free presentational component",
      "severity": "info",
      "category": "ARCH",
      "file": "src/web/src/SupportAgent/ChatLayout.js",
      "description": "ChatLayout.js accepts all data through props (messages array) and has no side effects, context access, or service dependencies. It is straightforwardly testable and correctly separates rendering from data-fetching concerns.",
      "recommendation": "No action required. This is a positive finding and a pattern to follow when adding new components.",
      "status": "open"
    }
  ],
  "summary": {
    "critical": 0,
    "notable": 3,
    "minor": 2,
    "info": 2,
    "total": 7
  }
}
