1+ import { NextRequest , NextResponse } from 'next/server'
2+ import { supabase } from '@/lib/supabase'
3+
4+ interface CodeAnalysisRequest {
5+ code : string
6+ language : string
7+ file : string
8+ cursorPosition : { line : number ; column : number }
9+ }
10+
11+ interface CodeSuggestion {
12+ id : string
13+ type : 'completion' | 'refactor' | 'fix' | 'optimize'
14+ line : number
15+ column : number
16+ text : string
17+ replacement : string
18+ confidence : number
19+ description : string
20+ }
21+
22+ interface Diagnostic {
23+ id : string
24+ type : 'error' | 'warning' | 'info'
25+ line : number
26+ column : number
27+ message : string
28+ suggestion ?: string
29+ }
30+
31+ export async function POST ( request : NextRequest ) {
32+ try {
33+ const authHeader = request . headers . get ( 'authorization' )
34+ if ( ! authHeader ) {
35+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
36+ }
37+
38+ const token = authHeader . replace ( 'Bearer ' , '' )
39+ const { data : { user } , error : authError } = await supabase . auth . getUser ( token )
40+ if ( authError || ! user ) {
41+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
42+ }
43+
44+ const body : CodeAnalysisRequest = await request . json ( )
45+ const { code, language, file, cursorPosition } = body
46+
47+ if ( ! code || ! language ) {
48+ return NextResponse . json ( { error : 'Missing required fields' } , { status : 400 } )
49+ }
50+
51+ // Analyze code using AI
52+ const analysis = await analyzeCodeWithAI ( code , language , file , cursorPosition )
53+
54+ return NextResponse . json ( {
55+ suggestions : analysis . suggestions ,
56+ diagnostics : analysis . diagnostics ,
57+ metrics : analysis . metrics
58+ } )
59+
60+ } catch ( error ) {
61+ console . error ( 'Code analysis error:' , error )
62+ return NextResponse . json (
63+ { error : 'Failed to analyze code' } ,
64+ { status : 500 }
65+ )
66+ }
67+ }
68+
69+ async function analyzeCodeWithAI (
70+ code : string ,
71+ language : string ,
72+ file : string ,
73+ cursorPosition : { line : number ; column : number }
74+ ) : Promise < {
75+ suggestions : CodeSuggestion [ ]
76+ diagnostics : Diagnostic [ ]
77+ metrics : any
78+ } > {
79+ // Get OpenAI API key from environment
80+ const apiKey = process . env . OPENAI_API_KEY
81+ if ( ! apiKey ) {
82+ throw new Error ( 'OpenAI API key not configured' )
83+ }
84+
85+ const lines = code . split ( '\n' )
86+ const currentLine = lines [ cursorPosition . line - 1 ] || ''
87+ const context = lines . slice ( Math . max ( 0 , cursorPosition . line - 5 ) , cursorPosition . line + 5 ) . join ( '\n' )
88+
89+ try {
90+ const response = await fetch ( 'https://api.openai.com/v1/chat/completions' , {
91+ method : 'POST' ,
92+ headers : {
93+ 'Authorization' : `Bearer ${ apiKey } ` ,
94+ 'Content-Type' : 'application/json' ,
95+ } ,
96+ body : JSON . stringify ( {
97+ model : 'gpt-4' ,
98+ messages : [
99+ {
100+ role : 'system' ,
101+ content : `You are an expert code analyst and assistant. Analyze the provided ${ language } code and provide:
102+
103+ 1. **Code Suggestions**: Improvements, optimizations, refactoring opportunities
104+ 2. **Diagnostics**: Potential errors, warnings, and issues
105+ 3. **Best Practices**: Adherence to ${ language } conventions and patterns
106+
107+ Focus on:
108+ - Performance optimizations
109+ - Code quality improvements
110+ - Security vulnerabilities
111+ - Best practice violations
112+ - Type safety (for TypeScript)
113+ - Modern syntax usage
114+ - Error handling improvements
115+
116+ Return your analysis as JSON in this exact format:
117+ {
118+ "suggestions": [
119+ {
120+ "id": "unique-id",
121+ "type": "completion|refactor|fix|optimize",
122+ "line": number,
123+ "column": number,
124+ "text": "original text",
125+ "replacement": "suggested replacement",
126+ "confidence": 0.0-1.0,
127+ "description": "brief description"
128+ }
129+ ],
130+ "diagnostics": [
131+ {
132+ "id": "unique-id",
133+ "type": "error|warning|info",
134+ "line": number,
135+ "column": number,
136+ "message": "diagnostic message",
137+ "suggestion": "optional fix suggestion"
138+ }
139+ ]
140+ }`
141+ } ,
142+ {
143+ role : 'user' ,
144+ content : `Analyze this ${ language } code from file "${ file } ":
145+
146+ \`\`\`${ language }
147+ ${ code }
148+ \`\`\`
149+
150+ Current cursor position: Line ${ cursorPosition . line } , Column ${ cursorPosition . column }
151+ Current line context: "${ currentLine } "
152+
153+ Provide analysis focusing on the area around the cursor and overall code quality.`
154+ }
155+ ] ,
156+ temperature : 0.3 ,
157+ max_tokens : 2000 ,
158+ } ) ,
159+ } )
160+
161+ if ( ! response . ok ) {
162+ throw new Error ( `OpenAI API error: ${ response . statusText } ` )
163+ }
164+
165+ const result = await response . json ( )
166+ const analysisText = result . choices [ 0 ] ?. message ?. content
167+
168+ if ( ! analysisText ) {
169+ throw new Error ( 'No analysis returned from OpenAI' )
170+ }
171+
172+ // Parse the JSON response
173+ try {
174+ const analysis = JSON . parse ( analysisText )
175+
176+ // Add IDs if missing
177+ analysis . suggestions = analysis . suggestions ?. map ( ( s : any , i : number ) => ( {
178+ ...s ,
179+ id : s . id || `suggestion-${ Date . now ( ) } -${ i } `
180+ } ) ) || [ ]
181+
182+ analysis . diagnostics = analysis . diagnostics ?. map ( ( d : any , i : number ) => ( {
183+ ...d ,
184+ id : d . id || `diagnostic-${ Date . now ( ) } -${ i } `
185+ } ) ) || [ ]
186+
187+ return {
188+ suggestions : analysis . suggestions ,
189+ diagnostics : analysis . diagnostics ,
190+ metrics : {
191+ complexity : calculateComplexity ( code ) ,
192+ linesOfCode : lines . length ,
193+ analysisTimestamp : new Date ( ) . toISOString ( )
194+ }
195+ }
196+ } catch ( parseError ) {
197+ console . error ( 'Failed to parse AI analysis:' , parseError )
198+ return {
199+ suggestions : [ ] ,
200+ diagnostics : [ ] ,
201+ metrics : {
202+ complexity : calculateComplexity ( code ) ,
203+ linesOfCode : lines . length ,
204+ analysisTimestamp : new Date ( ) . toISOString ( )
205+ }
206+ }
207+ }
208+
209+ } catch ( error ) {
210+ console . error ( 'AI analysis failed:' , error )
211+ return {
212+ suggestions : [ ] ,
213+ diagnostics : [ ] ,
214+ metrics : {
215+ complexity : calculateComplexity ( code ) ,
216+ linesOfCode : lines . length ,
217+ analysisTimestamp : new Date ( ) . toISOString ( )
218+ }
219+ }
220+ }
221+ }
222+
223+ function calculateComplexity ( code : string ) : number {
224+ // Simple cyclomatic complexity calculation
225+ const complexityKeywords = [
226+ 'if' , 'else' , 'elif' , 'while' , 'for' , 'switch' , 'case' ,
227+ 'catch' , 'try' , 'throw' , '&&' , '||' , '?' , ':'
228+ ]
229+
230+ let complexity = 1 // Base complexity
231+
232+ for ( const keyword of complexityKeywords ) {
233+ const regex = new RegExp ( `\\b${ keyword } \\b` , 'g' )
234+ const matches = code . match ( regex )
235+ complexity += matches ? matches . length : 0
236+ }
237+
238+ return complexity
239+ }
0 commit comments