Skip to content

Conversation

@DecodeX15
Copy link

@DecodeX15 DecodeX15 commented Nov 13, 2025

This pr solving issue describe in #170

📝 Description

This PR implements the missing backend API endpoint required by the landing page's "Analyze Repository" feature. The frontend sends a POST request to /api/repo-stats, but this route did not exist, causing a 404 error and preventing repository indexing via CodeGraph.

To fix this, I created a new controller that calls RepoService.index_repo(), which performs repository cloning, graph indexing, and metadata storage. This now allows the landing page to successfully analyze GitHub repositories.

A short walkthrough video of the implementation is included.


🔧 Changes Made

  • Added a new API route: POST /api/repo-stats
  • Implemented controller logic that forwards the repo_url to RepoService.index_repo()
  • Created backend/app/api/v1/repositories.py
  • Registered the new router in backend/app/api/router.py
  • Updated frontend LandingPage.tsx to call the correct API route
  • Integrated CodeGraph indexing pipeline end-to-end for the web platform

📌 How It Works

  1. User enters a GitHub repo URL on the landing page
  2. Frontend triggers:
    axios.post("http://localhost:8000/api/repo-stats", { repo_url });

3 .Backend receives the URL in the new controller and calls: RepoService().index_repo(repo_url)
4 . Repo is cloned, analyzed, and indexed into FalkorDB CodeGraph
5. After successfull anaysis ,User is navigated to the dashboard with indexed repo data

U can watch demo here

Screen.Recording.2025-11-13.204131.mp4

Summary by CodeRabbit

  • New Features

    • Added repository analysis functionality enabling users to submit repository URLs and receive statistics and analysis results through a new endpoint.
  • Chores

    • Updated development environment configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Walkthrough

The PR adds a new REST API endpoint for repository analysis at POST /api/repo-stats, registers it in the API router, introduces a RepoRequest model for the endpoint payload, modifies the RepoService.index_repo method to use a default parameter value, and updates the VSCode Python formatter configuration.

Changes

Cohort / File(s) Summary
Configuration
[.vscode/settings.json]
Updated Python formatter from ms-python.autopep8 to trunk.io while keeping formatOnSave enabled.
API Router Registration
[backend/app/api/router.py]
Added import and inclusion of repo_router from app.api.v1.repositories to the main API router.
Repository Endpoint
[backend/app/api/v1/repositories.py]
New router module defining a FastAPI endpoint for POST /api/repo-stats with RepoRequest model and analyze_repository handler that invokes RepoService.index_repo and returns stats or 500 error on failure.
Service Layer
[backend/app/services/codegraph/repo_service.py]
Added default parameter value "web_user" for discord_id in the index_repo method.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Endpoint as POST /api/repo-stats
    participant Service as RepoService
    participant Error as Error Handler

    Client->>Endpoint: POST RepoRequest {repo_url}
    Endpoint->>Endpoint: Log repo_url
    Endpoint->>Service: index_repo(repo_url, discord_id="web_user")
    
    alt Success
        Service-->>Endpoint: Returns stats Dict
        Endpoint-->>Client: 200 {message, repository, stats}
    else Failure
        Service->>Error: Exception raised
        Error->>Endpoint: Log traceback
        Endpoint-->>Client: 500 {detail: error_string}
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • The changes follow a consistent pattern: new router registration, straightforward endpoint implementation, and a simple parameter modification.
  • Most edits are additive and non-overlapping, reducing cognitive load.

Areas that may require extra attention:

  • Verify error handling in the endpoint catches all expected exceptions from RepoService.index_repo.
  • Confirm the async/await pattern is correctly applied in analyze_repository.
  • Check that "web_user" as the default discord_id is semantically correct for unauthenticated web requests.

Possibly related issues

Poem

🐰 A router hops in with pride so keen,
New endpoints bloom where none had been!
Repo stats flow like fresh spring grass,
With trunk.io formatting—a stylish pass! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 change: implementing the missing backend API endpoint to fix the GitHub repo analysis feature on the landing page.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

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

🧹 Nitpick comments (2)
backend/app/api/v1/repositories.py (2)

8-9: Consider adding field validation and documentation.

While the current model works, adding Pydantic Field annotations would improve API documentation and provide better error messages.

Apply this diff to enhance the model:

-class RepoRequest(BaseModel):
-    repo_url: str
+from pydantic import Field
+
+class RepoRequest(BaseModel):
+    repo_url: str = Field(
+        ...,
+        description="GitHub repository URL (e.g., 'https://github.com/owner/repo') or owner/repo format",
+        example="AOSSIE-Org/Devr.AI"
+    )

16-16: Consider using dependency injection for RepoService.

While the current approach works, creating a new RepoService instance for each request is inefficient. Consider using FastAPI's dependency injection to reuse the service instance.

Example using dependency injection:

from fastapi import Depends

def get_repo_service():
    return RepoService()

@router.post("/repo-stats")
async def analyze_repository(
    request: RepoRequest,
    repo_service: RepoService = Depends(get_repo_service)
):
    logger.info(f"Repository analysis requested: {request.repo_url}")
    
    try:
        result = await repo_service.index_repo(request.repo_url)
        # ... rest of the code
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8eeacad and 9185080.

📒 Files selected for processing (4)
  • .vscode/settings.json (1 hunks)
  • backend/app/api/router.py (2 hunks)
  • backend/app/api/v1/repositories.py (1 hunks)
  • backend/app/services/codegraph/repo_service.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/app/api/v1/repositories.py (1)
backend/app/services/codegraph/repo_service.py (2)
  • RepoService (12-292)
  • index_repo (47-155)
🪛 Ruff (0.14.4)
backend/app/api/v1/repositories.py

17-21: Consider moving this statement to an else block

(TRY300)

🔇 Additional comments (5)
.vscode/settings.json (1)

4-4: LGTM!

The formatter change to trunk.io is a reasonable preference update that aligns with the project's tooling choices.

backend/app/api/router.py (2)

5-5: LGTM!

The import follows the established pattern for router imports in this file.


25-25: LGTM!

The router inclusion correctly relies on the prefix and tags defined in the repo_router itself (prefix="/api", tags=["repositories"]), which will expose the endpoint at /api/repo-stats.

backend/app/services/codegraph/repo_service.py (1)

47-47: LGTM! Backward-compatible default parameter.

The default value "web_user" appropriately distinguishes web-based indexing from Discord bot-based indexing, and the change remains backward compatible with existing calls that explicitly pass discord_id.

backend/app/api/v1/repositories.py (1)

1-6: LGTM!

The imports and router configuration are properly structured. The /api prefix aligns with the PR's goal of exposing the endpoint at /api/repo-stats.


@router.post("/repo-stats")
async def analyze_repository(request: RepoRequest):
print(f" repo aa gayi : {request.repo_url}")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Replace debug print with proper logging.

Debug print statements should not appear in production code and won't be captured by centralized logging systems.

Apply this diff to use proper logging:

+import logging
+
+logger = logging.getLogger(__name__)
+
 router = APIRouter(prefix="/api", tags=["repositories"])
 
 class RepoRequest(BaseModel):
     repo_url: str
 
 @router.post("/repo-stats")
 async def analyze_repository(request: RepoRequest):
-    print(f" repo aa gayi : {request.repo_url}")
+    logger.info(f"Repository analysis requested: {request.repo_url}")
🤖 Prompt for AI Agents
In backend/app/api/v1/repositories.py around line 13, replace the debug print
statement "print(f\" repo aa gayi : {request.repo_url}\")" with a proper logger
call (e.g., logger.debug or logger.info) that includes the repo URL and any
relevant request context; ensure the module imports or accesses the configured
logger (from your app logging setup or using logging.getLogger(__name__)),
remove the print, and use structured/clear message text so the event is captured
by centralized logs.

Comment on lines +15 to +24
try:
result = await RepoService().index_repo(request.repo_url)
return {
"message": "Repository indexed successfully",
"repository": request.repo_url,
"stats": result
}
except Exception as e:
print(traceback.format_exc())
raise HTTPException(status_code=500, detail=str(e)) from e
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Improve exception handling and logging.

Two issues with the current exception handling:

  1. Line 23 uses print() instead of proper logging
  2. Line 24 returns HTTP 500 for all exceptions, including client errors like ValueError from invalid repo URLs

Apply this diff to fix both issues:

+import logging
+
+logger = logging.getLogger(__name__)
+
 @router.post("/repo-stats")
 async def analyze_repository(request: RepoRequest):
-    print(f" repo aa gayi : {request.repo_url}")
+    logger.info(f"Repository analysis requested: {request.repo_url}")
 
     try:
         result = await RepoService().index_repo(request.repo_url)
         return {
             "message": "Repository indexed successfully",
             "repository": request.repo_url,
             "stats": result
         }
+    except ValueError as e:
+        logger.warning(f"Invalid repository URL: {request.repo_url} - {str(e)}")
+        raise HTTPException(status_code=400, detail=str(e)) from e
     except Exception as e:
-        print(traceback.format_exc()) 
+        logger.exception(f"Failed to index repository: {request.repo_url}")
         raise HTTPException(status_code=500, detail=str(e)) from e

Note: You can also remove the traceback import after this change.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.14.4)

17-21: Consider moving this statement to an else block

(TRY300)

🤖 Prompt for AI Agents
In backend/app/api/v1/repositories.py around lines 15 to 24, replace the
print(traceback.format_exc()) and blanket HTTP 500 handling with proper logging
and selective HTTP responses: import and use the module logger (e.g., from
logging import getLogger; logger = getLogger(__name__)), call
logger.exception(...) to log the full stack trace, catch specific client errors
like ValueError and raise HTTPException(status_code=400, detail=str(e)) for
those, and keep a generic HTTPException(status_code=500, detail="Internal server
error") for unexpected exceptions; also remove the now-unneeded traceback
import.

@DecodeX15
Copy link
Author

@smokeyScraper sir please review this

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