Skip to content

feat: Implement AI-Powered Doubt De-duplication System - #1074

Merged
knoxiboy merged 3 commits into
knoxiboy:mainfrom
Yogender-verma:a1
Jul 29, 2026
Merged

feat: Implement AI-Powered Doubt De-duplication System#1074
knoxiboy merged 3 commits into
knoxiboy:mainfrom
Yogender-verma:a1

Conversation

@Yogender-verma

@Yogender-verma Yogender-verma commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Description

This PR implements an AI-powered doubt de-duplication system using pgvector for semantic similarity search. It intercepts duplicate questions as students type, providing immediate feedback of existing similar doubts, thereby improving user experience and saving AI/server resources.

Related Issue

Closes #1066

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update (README, guides, comments)
  • Style / UI change (no logic change)
  • Code refactor (no behavior change)
  • Test addition or update
  • Breaking change (fix or feature that would cause existing functionality to change)

Screenshots (if UI change)

Before After
(N/A) (N/A)

How Has This Been Tested?

  • Tested locally with npm run dev
  • Verified on mobile viewport (375px)
  • Verified on desktop viewport (1024px+)
  • Unit tests added for /api/doubts/check-duplicate route and embeddings utility functions.
  • Verified build integrity with npx tsc --noEmit.

Checklist

  • I have tested my changes locally (npm run dev)
  • My code follows the existing code style
  • I have not introduced unrelated changes
  • I have added comments where necessary
  • My branch is up to date with main
  • I have linked the related issue above

Summary by CodeRabbit

  • New Features

    • Added duplicate-question detection when asking a doubt.
    • Identifies semantically similar questions and provides similarity scores.
    • Includes solved answers when available.
    • Supports classroom-specific checks with authentication and rate limiting.
  • Bug Fixes

    • Improved handling of unavailable AI services and failed similarity checks.
    • Added safer responses for unauthorized, anonymous, and rate-limited requests.
  • Tests

    • Added coverage for duplicate detection, embeddings, authentication, rate limits, and AI failures.

@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

@Yogender-verma is attempting to deploy a commit to the Karan Mani Tripathi 's projects Team on Vercel.

A member of the Team first needs to authorize it.

@codeant-ai

codeant-ai Bot commented Jul 26, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 0bea2e5 Jul 26, 2026 · 17:17 17:20

@codeant-ai

codeant-ai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@github-actions github-actions Bot added gssoc'26 GSSoC program issue level:intermediate Intermediate level task type:bug Bug fix type:feature New feature labels Jul 26, 2026
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Yogender-verma, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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 reviews.

How do review limits work?

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

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, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ad260fb0-7e4d-4c8b-a706-8ae1e2c123b8

📥 Commits

Reviewing files that changed from the base of the PR and between 0bea2e5 and f182dab.

📒 Files selected for processing (4)
  • src/__tests__/api/doubts-check-duplicate.test.ts
  • src/__tests__/lib/embeddings.test.ts
  • src/app/api/doubts/check-duplicate/route.ts
  • src/components/classroom/AskDoubt.tsx

Walkthrough

Adds a duplicate-check API route using embedding and Groq similarity workflows, connects AskDoubt to the route, and adds Jest coverage for endpoint access controls and embedding failure handling. It also adjusts a boundary in the flagged-doubt transaction.

Changes

Duplicate detection flow

Layer / File(s) Summary
Route contract and access control
src/app/api/doubts/check-duplicate/route.ts
Defines SimilarDoubt and implements validation, anonymous limits, authentication, membership checks, and classroom rate limiting.
Semantic and LLM matching
src/app/api/doubts/check-duplicate/route.ts, src/__tests__/lib/embeddings.test.ts
Attempts semantic vector matching, falls back to recent-doubt retrieval and Groq classification, resolves solved answers, and returns sorted matches with error handling.
Client wiring and endpoint tests
src/components/classroom/AskDoubt.tsx, src/__tests__/api/doubts-check-duplicate.test.ts
Routes similarity checks to /api/doubts/check-duplicate and tests anonymous, rate-limited, and authenticated request behavior.

Flag transaction maintenance

Layer / File(s) Summary
Auto-hide transaction boundary
src/app/api/doubts/flag/route.ts
Adjusts the boundary around the row-lock query and empty-lock guard without changing the transaction flow.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AskDoubt
  participant DuplicateRoute as POST /api/doubts/check-duplicate
  participant Embeddings as findSemanticDuplicates
  participant Database as db
  participant Groq
  AskDoubt->>DuplicateRoute: Submit content and classroomId
  DuplicateRoute->>Embeddings: Search semantic duplicates
  Embeddings->>Groq: Create embedding
  Embeddings->>Database: Query vector matches
  DuplicateRoute->>Database: Fetch recent doubts if needed
  DuplicateRoute->>Groq: Classify similarity matches
  DuplicateRoute-->>AskDoubt: Return similarDoubts
Loading

Possibly related issues

  • knoxiboy/DoubtDesk issue 1047 — Covers the semantic duplicate-prevention functionality implemented by this route and its AskDoubt integration.

Possibly related PRs

Suggested labels: backend, type:testing

Suggested reviewers: knoxiboy

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The route and tests are added, but the PR does not show the required schema/pgvector changes, debounced popover UI, or Playwright coverage, and the threshold differs from 90%. Add the pgvector extension and vector column in schema, debounce AskDoubt input with the popover UI, align the similarity threshold to >90%, and add the requested Playwright test.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: AI-powered doubt de-duplication.
Out of Scope Changes check ✅ Passed The changes stay focused on duplicate-detection routing, AskDoubt integration, and related tests; no clear unrelated feature work stands out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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.

@github-actions

Copy link
Copy Markdown

@coderabbitai review
@codeantai review

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/classroom/AskDoubt.tsx (1)

138-161: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

No error/failure feedback when the duplicate check fails.

checkSimilarity only updates state on res.ok (Line 151); on 401/429/503/5xx responses, isCheckingSimilarity resets but similarityChecked stays false, so neither the "no similar doubts" nor the "similar doubts found" panel renders, and the user gets no indication the check failed. Given this feature exists specifically to prevent duplicate submissions, a silent failure defeats the purpose without any visible fallback state.

♻️ Proposed fix: surface an error state
         setIsCheckingSimilarity(true);
         try {
             const res = await fetch("/api/doubts/check-duplicate", {
                 method: "POST",
                 headers: { "Content-Type": "application/json" },
                 body: JSON.stringify({ content: text, classroomId }),
             });
             if (res.ok) {
                 const data = await res.json();
                 setSimilarDoubts(data.similarDoubts || []);
                 setSimilarityChecked(true);
+            } else {
+                setSimilarDoubts([]);
+                setSimilarityChecked(false);
+                // surface a non-blocking notice, e.g. toast or inline message
             }
         } catch (err) {
             console.error("Similarity check failed:", err);
+            setSimilarDoubts([]);
+            setSimilarityChecked(false);
         } finally {
             setIsCheckingSimilarity(false);
         }

As per path instructions, **/*.tsx files should be reviewed for "Missing loading/error states."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/classroom/AskDoubt.tsx` around lines 138 - 161, Update
checkSimilarity in AskDoubt to track and expose a similarity-check error when
the response is non-OK or the request throws, clearing any stale error before
each new request. Add the corresponding visible fallback in the duplicate-check
UI so users are informed that the check failed and can retry, while preserving
the existing similar-doubts and no-results states for successful responses.

Source: Path instructions

🧹 Nitpick comments (4)
src/__tests__/lib/embeddings.test.ts (1)

15-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

createDbMock is dead code.

Defined but never invoked; the actual jest.mock("@/configs/db", ...) factory (Lines 26-35) duplicates its shape inline instead of calling it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/lib/embeddings.test.ts` around lines 15 - 24, Remove the unused
createDbMock helper and update the jest.mock("`@/configs/db`", ...) factory to
reuse it instead of duplicating the database mock shape inline.
src/__tests__/api/doubts-check-duplicate.test.ts (2)

60-69: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Unnecessary groq-sdk mock.

@/lib/ai/groq-client is already fully mocked (Lines 6-17), so nothing in the tested code path touches the real groq-sdk module; this mock appears to be leftover/unused.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/api/doubts-check-duplicate.test.ts` around lines 60 - 69,
Remove the redundant groq-sdk jest.mock declaration from the test, keeping the
existing `@/lib/ai/groq-client` mock unchanged so the tested code path remains
isolated.

71-135: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No coverage for the authenticated/membership success path.

All three tests cover anonymous, rate-limited, and unauthenticated-classroom flows, but none exercise a successful classroomId request with a valid member (Lines 50-71 of route.ts). That path contains the duplicate rate-limit bug flagged in route.ts — a test hitting it would have caught it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/api/doubts-check-duplicate.test.ts` around lines 71 - 135, The
test suite lacks coverage for the authenticated classroom success path. Add a
test in the “Doubt check-duplicate API endpoint” suite that mocks currentUser as
a valid classroom member, configures the database query needed by POST, submits
a request with classroomId, and asserts the successful response and
duplicate-check behavior, including the relevant rate-limit interaction so the
bug in the classroom branch is detected.
src/app/api/doubts/check-duplicate/route.ts (1)

23-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate SimilarDoubt type definitions across client and server. Both files independently declare the same shape for the API response; centralizing it avoids drift as the contract evolves.

  • src/app/api/doubts/check-duplicate/route.ts#L23-L30: keep this as the canonical exported SimilarDoubt type.
  • src/components/classroom/AskDoubt.tsx#L26-L33: remove the local interface and import SimilarDoubt from the route module (or a shared types file) instead of redeclaring it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/doubts/check-duplicate/route.ts` around lines 23 - 30, Keep the
exported SimilarDoubt interface in src/app/api/doubts/check-duplicate/route.ts
as the canonical definition. In src/components/classroom/AskDoubt.tsx, remove
the duplicate local interface and import and use SimilarDoubt from the route
module or an appropriate shared types file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/api/doubts/check-duplicate/route.ts`:
- Around line 50-71: Remove the redundant direct aiLimiter.limit(email) block
from the classroom branch of the duplicate-check handler. Keep
enforceApiRateLimit(aiLimiter, email, "ai") as the sole rate-limit enforcement
before membership validation, preserving its response and error-handling
behavior.
- Around line 73-88: Move the enforceAiAvailability(aiQuotaIdentifier) guard to
execute before findSemanticDuplicates in the duplicate-check flow, ensuring
AI-disabled and quota-blocked requests cannot reach Groq embeddings. Keep the
existing guard behavior before the LLM fallback without duplicating the check
unnecessarily, and preserve the semantic-duplicate response and fallback
handling.
- Line 78: Raise the duplicate-matching threshold from 80 to 90 throughout the
check-duplicate flow: update the similarityThreshold value, LLM fallback
similarity comparison, related default threshold, and prompt text. Ensure
AskDoubt.tsx receives only matches meeting the 90% threshold.

---

Outside diff comments:
In `@src/components/classroom/AskDoubt.tsx`:
- Around line 138-161: Update checkSimilarity in AskDoubt to track and expose a
similarity-check error when the response is non-OK or the request throws,
clearing any stale error before each new request. Add the corresponding visible
fallback in the duplicate-check UI so users are informed that the check failed
and can retry, while preserving the existing similar-doubts and no-results
states for successful responses.

---

Nitpick comments:
In `@src/__tests__/api/doubts-check-duplicate.test.ts`:
- Around line 60-69: Remove the redundant groq-sdk jest.mock declaration from
the test, keeping the existing `@/lib/ai/groq-client` mock unchanged so the tested
code path remains isolated.
- Around line 71-135: The test suite lacks coverage for the authenticated
classroom success path. Add a test in the “Doubt check-duplicate API endpoint”
suite that mocks currentUser as a valid classroom member, configures the
database query needed by POST, submits a request with classroomId, and asserts
the successful response and duplicate-check behavior, including the relevant
rate-limit interaction so the bug in the classroom branch is detected.

In `@src/__tests__/lib/embeddings.test.ts`:
- Around line 15-24: Remove the unused createDbMock helper and update the
jest.mock("`@/configs/db`", ...) factory to reuse it instead of duplicating the
database mock shape inline.

In `@src/app/api/doubts/check-duplicate/route.ts`:
- Around line 23-30: Keep the exported SimilarDoubt interface in
src/app/api/doubts/check-duplicate/route.ts as the canonical definition. In
src/components/classroom/AskDoubt.tsx, remove the duplicate local interface and
import and use SimilarDoubt from the route module or an appropriate shared types
file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f736527e-5b82-4116-95f8-76224262fdc2

📥 Commits

Reviewing files that changed from the base of the PR and between b5ab6a3 and 0bea2e5.

📒 Files selected for processing (5)
  • src/__tests__/api/doubts-check-duplicate.test.ts
  • src/__tests__/lib/embeddings.test.ts
  • src/app/api/doubts/check-duplicate/route.ts
  • src/app/api/doubts/flag/route.ts
  • src/components/classroom/AskDoubt.tsx
💤 Files with no reviewable changes (1)
  • src/app/api/doubts/flag/route.ts

Comment thread src/app/api/doubts/check-duplicate/route.ts
Comment thread src/app/api/doubts/check-duplicate/route.ts
Comment thread src/app/api/doubts/check-duplicate/route.ts Outdated
@knoxiboy knoxiboy added the quality:clean Clean code quality label Jul 29, 2026
@knoxiboy
knoxiboy merged commit 89e4cb6 into knoxiboy:main Jul 29, 2026
17 of 20 checks passed
@github-actions github-actions Bot added gssoc:approved Approved for GSSoC and removed size/l review-needed labels Jul 29, 2026
@knoxiboy knoxiboy added level:advanced Advanced level task and removed level:intermediate Intermediate level task labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved Approved for GSSoC gssoc'26 GSSoC program issue level:advanced Advanced level task quality:clean Clean code quality type:bug Bug fix type:feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement AI-Powered Doubt De-duplication System using pgvector

2 participants