Skip to content

Conversation

@justin-phxm
Copy link
Collaborator

@justin-phxm justin-phxm commented Feb 7, 2026

…andlers

Summary by CodeRabbit

  • New Features

    • Refresh button and improved loading, no-data, and retry UI for ML correlation visuals.
    • App-wide query provider for consistent, cached ML data and devtools for debugging.
  • Refactor

    • Centralized data-fetching flow using a query-based hook and theme-aware rendering adjustments.
    • Centralized API route constants and standardized backend API client.
  • Documentation

    • Added comprehensive API usage and integration guidelines.
  • Chores

    • Added HTTP client and query-related dependencies.

@justin-phxm justin-phxm self-assigned this Feb 7, 2026
@justin-phxm justin-phxm requested a review from a team as a code owner February 7, 2026 21:49
@vercel
Copy link

vercel bot commented Feb 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
helios-telemetry Ready Ready Preview, Comment Feb 8, 2026 0:04am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

Adds TanStack React Query and axios, centralizes API and backend route constants, provides a shared Axios client, introduces a theme-aware useMLCorrelationMatrix hook, refactors MLContainer to use the hook (with loading/error/refetch UI), updates Next API handlers to use backendApi, and wraps the app in a QueryClientProvider.

Changes

Cohort / File(s) Summary
Dependencies & App Provider
packages/client/package.json, packages/client/src/pages/_app.tsx
Added @tanstack/react-query, axios, @tanstack/react-query-devtools; created module-level QueryClient and wrapped the app with QueryClientProvider + ReactQueryDevtools.
API Route Constants
packages/client/src/constants/apiRoutes.ts
New read-only API_ROUTES and BACKEND_ROUTES exports plus ApiRoute and BackendRoute types for centralized route management.
HTTP client
packages/client/src/lib/api.ts
New preconfigured api Axios instance, backendApi helper and DEFAULT_TIMEOUT (30s); request/response interceptor scaffolding and lazy backend API initialization.
ML hook
packages/client/src/hooks/useMLCorrelationMatrix.ts
New useMLCorrelationMatrix hook and PlotTypes; uses api + TanStack Query to fetch correlation matrices, applies theme-aware layout transform, configures retries/timeouts, exposes transformed data, status, and refetch.
Component refactor
packages/client/src/components/containers/MLContainer.tsx
Replaced manual fetch/useEffect with useMLCorrelationMatrix; removed local fetch state; added loading/error/no-data states, Retry/Refresh controls, and uses API_ROUTES for default plotType.
Next API handlers
packages/client/src/pages/api/getPacketCorrelationMatrix.ts, packages/client/src/pages/api/getLapCorrelationMatrix.ts
Replaced direct fetch/prodURL usage with backendApi.get and BACKEND_ROUTES usage; standardized success path to res.status(200).json(data).
Documentation
rules/api-architecture.md
New API architecture and usage guide describing route constants, Axios usage, TanStack Query patterns, error handling, migration checklist, and examples.
Devtools
packages/client/src/pages/_app.tsx
Added React Query Devtools with initialIsOpen: false.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant MLContainer
    participant Hook as useMLCorrelationMatrix
    participant Query as ReactQuery
    participant Axios as api
    participant Server as API_Server

    User->>MLContainer: mount / request plot
    MLContainer->>Hook: call useMLCorrelationMatrix(plotType)
    Hook->>Query: useQuery(fetchCorrelationMatrix)
    Query->>Axios: GET /api/ml/...
    Axios->>Server: network request
    Server-->>Axios: JSON (plot params)
    Axios-->>Query: resolved data
    Query->>Hook: data / status / refetch
    Hook->>MLContainer: transformed data, isLoading, error, refetch
    alt Loading
        MLContainer->>User: show loading UI
    else Error
        MLContainer->>User: show error + Retry
        User->>MLContainer: click Retry
        MLContainer->>Hook: refetch()
    else Success
        MLContainer->>User: render Plotly + Refresh
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • dastine0308
  • burtonjong

Poem

🐰 I hopped through routes and sipped some tea,
Axios fetched graphs for all to see,
Query cached whispers, theme-tinted light,
Retry and refresh kept data bright,
I munched a carrot and bounded off with glee 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: refactoring ML containers to use TanStack Query and refactoring API route handlers, matching the core objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-to-tanstack-query

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
packages/client/src/pages/api/getPacketCorrelationMatrix.ts (1)

15-18: Axios error messages may leak internal backend URLs to the client.

AxiosError.message can include the full request URL (e.g., "Request failed with status code 500" or connection errors with the backend host). Consider returning a generic message to the client and logging the full error server-side instead.

Suggested approach
   } catch (err) {
+    console.error("getPacketCorrelationMatrix error:", err);
     res.status(500).json({
-      error: `Failed to load data: ${err instanceof Error ? err.message : String(err)}`,
+      error: "Failed to load packet correlation matrix data",
     });
   }
packages/client/src/pages/api/getLapCorrelationMatrix.ts (1)

15-18: Same error-leakage concern as getPacketCorrelationMatrix.ts.

Consider sanitizing the error message returned to the client here as well, to avoid exposing internal backend details from Axios errors.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…ble types'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/client/src/constants/apiRoutes.ts`:
- Around line 93-97: ApiRoute and BackendRoute currently alias (typeof
API_ROUTES)[keyof typeof API_ROUTES], which picks the top-level nested objects
instead of the leaf route string values; change them to extract leaf string
values from the nested route objects (e.g., introduce a recursive mapped type
like ValueOfDeep<T> or LeafRouteValues<T> and then define ApiRoute =
ValueOfDeep<typeof API_ROUTES> and BackendRoute = ValueOfDeep<typeof
BACKEND_ROUTES>) so the resulting types are a union of the route string paths
rather than sub-objects; update references to ApiRoute and BackendRoute
accordingly.

In `@packages/client/src/hooks/useMLCorrelationMatrix.ts`:
- Around line 29-38: In fetchCorrelationMatrix, remove the redundant JSON.parse
by calling api.get with the correct generic type (PlotParams) and return
response.data directly (locate the function fetchCorrelationMatrix and the
api.get usage); also simplify the redundant theme check by replacing the
`!!resolvedTheme && resolvedTheme !== undefined` condition with a single truthy
check like `resolvedTheme` (locate the resolvedTheme condition around line 62)
so you don't repeat undefined checks.
🧹 Nitpick comments (6)
packages/client/src/pages/_app.tsx (1)

15-34: Module-level QueryClient is risky in Next.js Pages Router with SSR.

In Next.js Pages Router, _app.tsx executes on the server for SSR'd pages, and a module-level QueryClient is shared across all incoming requests — potentially leaking cached data between users. The standard pattern is to create it inside the component via useState or useRef:

-const queryClient = new QueryClient({
-  defaultOptions: { ... },
-});
-
 export default function App({ Component, pageProps }: AppProps) {
+  const [queryClient] = useState(() => new QueryClient({
+    defaultOptions: { ... },
+  }));
   return (

Currently this is safe because queries are gated by enabled: !!resolvedTheme (always falsy server-side), but future hooks without that guard will silently inherit the shared cache.

packages/client/src/lib/api.ts (2)

62-95: backendApi isn't actually lazy — and require() is unnecessary here.

getBackendApi() is called immediately on line 95, so the singleton is created at module-import time — the lazy wrapper adds complexity without benefit. Additionally, prodURL is a simple compile-time constant derived from process.env.NODE_ENV; a static import is simpler and works with tree-shaking/bundler analysis:

♻️ Suggested simplification
-import axios, { type AxiosInstance } from "axios";
+import axios, { type AxiosInstance } from "axios";
+import { prodURL } from "@shared/helios-types";

-const createBackendApi = (): AxiosInstance => {
-  // Dynamic import to handle environment-specific URLs
-  // eslint-disable-next-line `@typescript-eslint/no-var-requires`
-  const { prodURL } = require("@shared/helios-types");
-
-  return axios.create({
-    baseURL: prodURL,
-    headers: {
-      Accept: "application/json",
-      "Content-Type": "application/json",
-    },
-    timeout: DEFAULT_TIMEOUT,
-  });
-};
-
-let backendApiInstance: AxiosInstance | null = null;
-
-const getBackendApi = (): AxiosInstance => {
-  if (!backendApiInstance) {
-    backendApiInstance = createBackendApi();
-  }
-  return backendApiInstance;
-};
-
-export const backendApi = getBackendApi();
+export const backendApi: AxiosInstance = axios.create({
+  baseURL: prodURL,
+  headers: {
+    Accept: "application/json",
+    "Content-Type": "application/json",
+  },
+  timeout: DEFAULT_TIMEOUT,
+});

100-123: No-op interceptors add boilerplate without behavior.

Both the request and response interceptors are pass-through. Consider removing them until actual logic is needed — they can always be added later. Dead scaffolding accumulates noise.

packages/client/src/hooks/useMLCorrelationMatrix.ts (1)

62-62: Redundant condition: !!resolvedTheme already handles undefined.

!!resolvedTheme && resolvedTheme !== undefined — the second clause is always true when the first is true. Simplify to:

-    enabled: !!resolvedTheme && resolvedTheme !== undefined,
+    enabled: !!resolvedTheme,
packages/client/src/components/containers/MLContainer.tsx (2)

33-40: Loading message branching is subtly correct but worth a comment.

isFetching is always true when isLoading is true for a normal query. However, because the hook overrides isLoading to include !resolvedTheme, the "Loading..." fallback actually fires when the theme hasn't resolved yet (query disabled). A brief inline comment would prevent a future developer from "fixing" this seemingly dead branch.


1-1: "use client" is unnecessary in Next.js Pages Router.

This project uses pages/_app.tsx (Pages Router), where all components are client-side by default. The "use client" directive is only meaningful in the App Router (app/ directory). It's harmless here but adds noise and is inconsistently used across the codebase (only 3 components use it, while others with hooks don't).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@rules/api-architecture.md`:
- Around line 436-441: Update the "Response Caching" bullet to reflect that
TanStack Query is already integrated in this PR by changing the phrasing from a
future enhancement to current state and referencing the added hook
(useMLCorrelationMatrix) as an example; edit the line that currently reads
"Integrate with TanStack Query for intelligent caching" to something like
"Integrated with TanStack Query (e.g., useMLCorrelationMatrix) for intelligent
response caching" so the docs match the codebase.
- Around line 22-28: The examples reuse the identifier "const response" in the
same scope causing TypeScript redeclaration errors; update each snippet that
calls api.get (e.g., calls using API_ROUTES.ml.packetCorrelationMatrix and
API_ROUTES.drivers.base or other API_ROUTES entries) to use unique variable
names (like packetCorrelationResponse, driversResponse) or split examples into
separate independent code blocks so each "const response" is in its own scope;
search for other occurrences of "const response" in these examples and apply the
same renaming or scoping change to eliminate duplicate declarations.
🧹 Nitpick comments (3)
packages/client/src/lib/api.ts (2)

60-83: No-op interceptors add dead code; consider removing until needed.

These interceptors are pure pass-through — they don't modify requests or responses. Scaffolding placeholder code increases noise and gives a false sense of "centralized error handling" (as claimed in the module docstring). Remove them and add real interceptors when there's an actual requirement (e.g., attaching auth tokens, global error toasts).


29-29: DEFAULT_TIMEOUT is declared then re-exported; simplify to a single export const.

The constant is declared on Line 29 without export, then re-exported on Line 88. Since it's already used internally on Line 54, just add export at the declaration site and drop the redundant re-export.

Proposed fix
-const DEFAULT_TIMEOUT = 30000;
+export const DEFAULT_TIMEOUT = 30000;

And remove lines 85-88.

Also applies to: 88-88

rules/api-architecture.md (1)

1-467: Document is heavily repetitive — the same rules are restated 3-4 times across sections.

The "Critical Rules" (Lines 16-134), "Common Mistakes" (Lines 275-359), and "Migration Guide" (Lines 363-394) sections all convey the same information with slightly different framing. Consider consolidating into a single rules section with one concise example each, plus the migration guide. This would cut the document roughly in half and make it more likely to actually be read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant