Skip to content

fix(gateway): implement proxy routes and schemas for Study Hub features#570

Merged
FireFistisDead merged 1 commit into
FireFistisDead:masterfrom
Sandeep6135:fix/api-gateway-study-hub-mismatch
Jun 18, 2026
Merged

fix(gateway): implement proxy routes and schemas for Study Hub features#570
FireFistisDead merged 1 commit into
FireFistisDead:masterfrom
Sandeep6135:fix/api-gateway-study-hub-mismatch

Conversation

@Sandeep6135

Copy link
Copy Markdown
Contributor

Pull Request: Resolve API Gateway Proxy Omission & Mismatch for Study Hub Features

Closes #563

📌 Classification & Priority

Metric Value
Change Type bug-fix
Severity Level critical
Target Service api-gateway
Integration Quality Impact exceptional-proxy-resolution
Fix Strategy Routing Policy / Gateway Schemas Insertion

📖 Summary

Important

This PR resolves a critical system integration failure where Study Hub features (Knowledge Gaps, Flashcard Generation, and Flashcard Progress updates) were completely non-functional in production due to a missing proxy layer in the Node.js API Gateway (server.js) and mismatched endpoint naming conventions.

🔴 Problem

The React frontend attempts to call /knowledge-gaps, /sessions/flashcards, and /sessions/flashcards/progress on the API Gateway. However, server.js lacked definitions, rate limits, slow-down configs, and validation schemas for these routes, causing all requests to fail with 404 Route not found. In addition, if the requests were passed through directly, they would fail at the backend because the Python service expects /sessions/flashcards/generate and /sessions/flashcards/update-progress respectively.

🟢 Solution

Exposed and defined the three proxy endpoints inside server.js with correct mapping logic:

  1. Imported generateFlashcardsSchema and updateFlashcardProgressSchema from ./validators/schemas to perform structural validation.
  2. Created the /knowledge-gaps proxy route mapping to the Python RAG service's /knowledge-gaps endpoint.
  3. Created the /sessions/flashcards proxy route mapping to the Python RAG service's /sessions/flashcards/generate endpoint.
  4. Created the /sessions/flashcards/progress proxy route mapping to the Python RAG service's /sessions/flashcards/update-progress endpoint.
  5. Wired the rate limiters (inferenceLimiter) and request slowing handlers (inferenceSlowDown) to protect the new endpoints against brute force and resource exhaustion.

🧪 Steps to Reproduce

  1. Launch the React frontend, Express API Gateway, and Python RAG service.
  2. Navigate to the Study Hub tab on the UI.
  3. Perform a flashcard generation request or fetch knowledge gaps.
  4. Observe that the gateway now correctly proxies the request, processes the body validations, forwards it to the Python service with the correct X-Internal-Token header, and returns a successful JSON payload.

🔍 Expected Behaviour

All Study Hub UI actions (flashcard generation, study progression rating, and prerequisite concept mapping) execute successfully and fetch context-relevant details from the backend without 404 errors.

❌ Actual Behaviour (Before Fix)

The Express server rejected all incoming Study Hub requests with 404 Route Not Found, rendering the features entirely broken.


🛠️ Code Diff Walkthrough

server.js

@@ -20,6 +20,8 @@ const {
   summarizeCredentialSchema,
   sessionsLookupSchema,
   knowledgeGapsSchema,
+  generateFlashcardsSchema,
+  updateFlashcardProgressSchema,
   MAX_QUESTION_LENGTH,
 } = require("./validators/schemas");
 const { clientIpFromRequest } = require("./security/ip");
@@ -1601,6 +1603,114 @@ app.post("/summarize", inferenceSlowDown, inferenceLimiter, async (req, res) =>
   }
 });
 
+app.post("/knowledge-gaps", inferenceSlowDown, inferenceLimiter, async (req, res) => {
+  const resolvedSessionSecret = await resolveSessionSecret(
+    req,
+    req.body?.session_id,
+    req.body?.session_secret
+  );
+
+  const validation = knowledgeGapsSchema.safeParse({
+    ...req.body,
+    session_secret: resolvedSessionSecret,
+  });
+
+  if (!validation.success) {
+    return res.status(400).json({
+      error: "Validation failed",
+      details: validation.error.flatten(),
+    });
+  }
+
+  try {
+    const response = await axios.post(
+      `${RAG_SERVICE_URL}/knowledge-gaps`,
+      validation.data,
+      {
+        headers: ragAuthHeaders(),
+      }
+    );
+
+    return res.json(response.data);
+  } catch (err) {
+    console.error(
+      "Knowledge gaps mapping failed:",
+      extractServiceDetails(err, "Error mapping knowledge gaps")
+    );
+    return propagateRagError(err, res, "Error mapping knowledge gaps");
+  }
+});
+
+app.post("/sessions/flashcards", inferenceSlowDown, inferenceLimiter, async (req, res) => {
+  const resolvedSessionSecret = await resolveSessionSecret(
+    req,
+    req.body?.session_id,
+    req.body?.session_secret
+  );
+
+  const validation = generateFlashcardsSchema.safeParse({
+    ...req.body,
+    session_secret: resolvedSessionSecret,
+  });
+
+  if (!validation.success) {
+    return res.status(400).json({
+      error: "Validation failed",
+      details: validation.error.flatten(),
+    });
+  }
+
+  try {
+    const response = await axios.post(
+      `${RAG_SERVICE_URL}/sessions/flashcards/generate`,
+      validation.data,
+      {
+        headers: ragAuthHeaders(),
+      }
+    );
+
+    return res.json(response.data);
+  } catch (err) {
+    console.error(
+      "Flashcard generation failed:",
+      extractServiceDetails(err, "Error generating flashcards")
+    );
+    return propagateRagError(err, res, "Error generating flashcards");
+  }
+});
+
+app.post("/sessions/flashcards/progress", inferenceSlowDown, inferenceLimiter, async (req, res) => {
+  const resolvedSessionSecret = await resolveSessionSecret(
+    req,
+    req.body?.session_id,
+    req.body?.session_secret
+  );
+
+  const validation = updateFlashcardProgressSchema.safeParse({
+    ...req.body,
+    session_secret: resolvedSessionSecret,
+  });
+
+  if (!validation.success) {
+    return res.status(400).json({
+      error: "Validation failed",
+      details: validation.error.flatten(),
+    });
+  }
+
+  try {
+    const response = await axios.post(
+      `${RAG_SERVICE_URL}/sessions/flashcards/update-progress`,
+      validation.data,
+      {
+        headers: ragAuthHeaders(),
+      }
+    );
+
+    return res.json(response.data);
+  } catch (err) {
+    console.error(
+      "Flashcard progress update failed:",
+      extractServiceDetails(err, "Error updating flashcard progress")
+    );
+    return propagateRagError(err, res, "Error updating flashcard progress");
+  }
+});
+
 app.get("/sessions", async (req, res) => {
   return res.status(410).json({
     error: "Endpoint removed. Use /sessions/lookup with session_id + session_secret.",

Copilot AI review requested due to automatic review settings June 18, 2026 17:37
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

@Sandeep6135 is attempting to deploy a commit to the firefistisdead's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Sandeep6135, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 47 minutes and 39 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 34923905-9b7d-4b01-937e-b524a4b34be2

📥 Commits

Reviewing files that changed from the base of the PR and between 5590b87 and 85a42e7.

📒 Files selected for processing (1)
  • server.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions Bot added backend Express or API gateway work bug Something isn't working enhancement New feature or request feature A new feature or improvement fix A targeted fix or cleanup frontend Frontend-related work level:critical question Further information is requested rag-service FastAPI / model service work type:security labels Jun 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes missing API Gateway (Express) proxy routes for the “Study Hub” frontend features by adding three new POST endpoints that validate request bodies and forward calls to the Python RAG service using the correct upstream paths.

Changes:

  • Added /knowledge-gaps proxy route with request validation via knowledgeGapsSchema.
  • Added /sessions/flashcards proxy route that maps to the upstream /sessions/flashcards/generate endpoint and validates via generateFlashcardsSchema.
  • Added /sessions/flashcards/progress proxy route that maps to the upstream /sessions/flashcards/update-progress endpoint and validates via updateFlashcardProgressSchema.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server.js
Comment on lines +1606 to +1609
app.post("/knowledge-gaps", inferenceSlowDown, inferenceLimiter, async (req, res) => {
const resolvedSessionSecret = await resolveSessionSecret(
req,
req.body?.session_id,
@FireFistisDead FireFistisDead merged commit 53eb4fb into FireFistisDead:master Jun 18, 2026
9 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Express or API gateway work bug Something isn't working enhancement New feature or request feature A new feature or improvement fix A targeted fix or cleanup frontend Frontend-related work gssoc:approved level:beginner quality:exceptional question Further information is requested rag-service FastAPI / model service work type:security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: API Gateway Proxy Omission and Path Mismatch for Study Hub

3 participants