File size: 4,926 Bytes
16a41ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""

api/models.py β€” Pydantic request/response schemas for every endpoint.



What Pydantic does:

  Pydantic validates incoming request data automatically.

  If a request body is missing a required field, or has the wrong type,

  FastAPI returns a clear 422 error BEFORE your route code even runs.

  No manual validation code needed.



  It also generates the JSON schema that powers the /docs Swagger UI β€”

  every field shows up with its type and description automatically.



Why one file for all models?

  Same reason as prompts.py β€” one place to change shapes.

  If the frontend changes what it sends, you update here, not in 5 routes.



Naming convention:

  *Request  β†’ what the frontend sends IN  (request body)

  *Response β†’ what the backend sends OUT (response body)

"""

from pydantic import BaseModel, HttpUrl, Field
from typing import Optional


# -----------------------------------------------------------------------
# INGEST β€” POST /api/v1/ingest
# Frontend sends a GitHub URL, backend runs the full pipeline.
# -----------------------------------------------------------------------

class IngestRequest(BaseModel):
    github_url: str = Field(
        ...,
        description="Public GitHub repository URL to analyse.",
        example="https://github.com/tiangolo/fastapi",
    )


class IngestResponse(BaseModel):
    status: str = Field(..., example="success")
    repo_name: str = Field(..., example="fastapi")
    files_indexed: int = Field(..., description="Number of source files found.")
    chunks_stored: int = Field(..., description="Number of code chunks embedded and stored.")
    graph_ready: bool = Field(..., description="True if dependency graph was built.")
    message: str = Field(..., example="Repository indexed successfully.")


# -----------------------------------------------------------------------
# QUERY β€” POST /api/v1/ask
# Frontend sends a question about a previously indexed repo.
# -----------------------------------------------------------------------

class AskRequest(BaseModel):
    repo_name: str = Field(
        ...,
        description="The repo name as returned by /ingest.",
        example="fastapi",
    )
    question: str = Field(
        ...,
        description="Natural language question about the codebase.",
        example="Where is the authentication logic handled?",
    )


class AskResponse(BaseModel):
    status: str = Field(..., example="success")
    repo_name: str
    question: str
    answer: str = Field(..., description="LLM-generated answer with file citations.")
    chunks_used: int = Field(..., description="Number of code chunks used as context.")


# -----------------------------------------------------------------------
# GRAPH β€” GET /api/v1/graph?repo_name=fastapi
# Returns the interactive dependency graph as an HTML string.
# -----------------------------------------------------------------------

class GraphResponse(BaseModel):
    status: str
    repo_name: str
    html: str = Field(..., description="Self-contained Pyvis HTML for iframe rendering.")
    stats: dict = Field(..., description="Graph statistics: nodes, edges, cycles, most_depended_on.")


# -----------------------------------------------------------------------
# BUGS β€” GET /api/v1/bugs?repo_name=fastapi
# Returns a list of detected issues in the codebase.
# -----------------------------------------------------------------------

class BugItem(BaseModel):
    file: str = Field(..., example="src/auth.py")
    line: int = Field(..., example=34)
    severity: str = Field(..., example="high")   # "high", "medium", "low"
    issue: str = Field(..., example="Unhandled exception in database call.")
    suggestion: str = Field(..., example="Wrap in try/except and log the error.")


class BugsResponse(BaseModel):
    status: str
    repo_name: str
    bugs: list[BugItem]
    total: int = Field(..., description="Total number of issues found.")


# -----------------------------------------------------------------------
# DIAGRAM β€” GET /api/v1/diagram?repo_name=fastapi
# Returns architecture summary + Mermaid diagram syntax.
# -----------------------------------------------------------------------

class DiagramResponse(BaseModel):
    status: str
    repo_name: str
    summary: str = Field(..., description="3-5 sentence architecture overview.")
    mermaid: str = Field(..., description="Mermaid flowchart syntax string for frontend rendering.")


# -----------------------------------------------------------------------
# ERROR β€” used by all routes when something goes wrong.
# Returned with appropriate HTTP status codes (400, 404, 500).
# -----------------------------------------------------------------------

class ErrorResponse(BaseModel):
    status: str = Field(default="error")
    message: str