codenuk_backend_mine/services/ai-analysis-service/INTEGRATION_EXAMPLE.md
2025-10-17 10:33:14 +05:30

9.3 KiB

AI Analysis Service Integration Example

Overview

This document shows how to integrate the AI Analysis Service with the Git Integration Service using the direct file access approach.

New API Endpoints

1. Repository Analysis by ID

Endpoint: POST /analyze-repository Purpose: Analyze a repository using its ID from the git-integration service

Request:

{
  "repository_id": "uuid-123",
  "user_id": "user-456",
  "output_format": "pdf",
  "max_files": 100
}

Response:

{
  "success": true,
  "message": "Repository analysis completed successfully",
  "analysis_id": "repo_analysis_uuid-123_20241201_143022",
  "report_path": "/app/reports/repo_analysis_uuid-123_20241201_143022_analysis.pdf",
  "stats": {
    "repository_id": "uuid-123",
    "total_files": 85,
    "total_lines": 15420,
    "languages": ["typescript", "javascript", "python"],
    "code_quality_score": 7.8,
    "high_quality_files": 45,
    "medium_quality_files": 30,
    "low_quality_files": 10,
    "total_issues": 23
  }
}

2. Repository Information

Endpoint: GET /repository/{repository_id}/info?user_id={user_id} Purpose: Get repository information from git-integration service

Response:

{
  "success": true,
  "repository_info": {
    "id": "uuid-123",
    "name": "my-repo",
    "full_name": "owner/my-repo",
    "local_path": "/app/git-repos/owner__my-repo__main",
    "description": "My awesome repository",
    "language": "typescript",
    "size": 1024000
  }
}

Frontend Integration Example

TypeScript Interface

interface RepositoryAnalysisRequest {
  repository_id: string;
  user_id: string;
  output_format: 'pdf' | 'json';
  max_files?: number;
}

interface AnalysisResponse {
  success: boolean;
  message: string;
  analysis_id?: string;
  report_path?: string;
  stats?: {
    repository_id: string;
    total_files: number;
    total_lines: number;
    languages: string[];
    code_quality_score: number;
    high_quality_files: number;
    medium_quality_files: number;
    low_quality_files: number;
    total_issues: number;
  };
}

API Service Function

class AIAnalysisService {
  private baseUrl = process.env.NEXT_PUBLIC_AI_ANALYSIS_SERVICE_URL || 'http://localhost:8022';

  async analyzeRepository(request: RepositoryAnalysisRequest): Promise<AnalysisResponse> {
    const response = await fetch(`${this.baseUrl}/analyze-repository`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(request)
    });

    if (!response.ok) {
      throw new Error(`Analysis failed: ${response.statusText}`);
    }

    return response.json();
  }

  async getRepositoryInfo(repositoryId: string, userId: string) {
    const response = await fetch(
      `${this.baseUrl}/repository/${repositoryId}/info?user_id=${userId}`
    );

    if (!response.ok) {
      throw new Error(`Failed to get repository info: ${response.statusText}`);
    }

    return response.json();
  }

  async downloadReport(filename: string): Promise<Blob> {
    const response = await fetch(`${this.baseUrl}/reports/${filename}`);
    
    if (!response.ok) {
      throw new Error(`Failed to download report: ${response.statusText}`);
    }

    return response.blob();
  }
}

React Component Example

import React, { useState } from 'react';

const RepositoryAnalysis: React.FC<{ repositoryId: string; userId: string }> = ({ 
  repositoryId, 
  userId 
}) => {
  const [isAnalyzing, setIsAnalyzing] = useState(false);
  const [analysisResult, setAnalysisResult] = useState<AnalysisResponse | null>(null);
  const [error, setError] = useState<string | null>(null);

  const aiAnalysisService = new AIAnalysisService();

  const handleAnalyze = async () => {
    setIsAnalyzing(true);
    setError(null);

    try {
      const result = await aiAnalysisService.analyzeRepository({
        repository_id: repositoryId,
        user_id: userId,
        output_format: 'pdf',
        max_files: 100
      });

      setAnalysisResult(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Analysis failed');
    } finally {
      setIsAnalyzing(false);
    }
  };

  const handleDownloadReport = async () => {
    if (!analysisResult?.report_path) return;

    try {
      const filename = analysisResult.report_path.split('/').pop();
      const blob = await aiAnalysisService.downloadReport(filename!);
      
      // Create download link
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename!;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    } catch (err) {
      setError('Failed to download report');
    }
  };

  return (
    <div className="repository-analysis">
      <h2>Repository Analysis</h2>
      
      <button 
        onClick={handleAnalyze} 
        disabled={isAnalyzing}
        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
      >
        {isAnalyzing ? 'Analyzing...' : 'Analyze Repository'}
      </button>

      {error && (
        <div className="error-message text-red-500 mt-4">
          {error}
        </div>
      )}

      {analysisResult && (
        <div className="analysis-results mt-6">
          <h3>Analysis Results</h3>
          
          <div className="stats grid grid-cols-2 gap-4 mt-4">
            <div className="stat">
              <strong>Total Files:</strong> {analysisResult.stats?.total_files}
            </div>
            <div className="stat">
              <strong>Total Lines:</strong> {analysisResult.stats?.total_lines}
            </div>
            <div className="stat">
              <strong>Code Quality Score:</strong> {analysisResult.stats?.code_quality_score}/10
            </div>
            <div className="stat">
              <strong>Languages:</strong> {analysisResult.stats?.languages?.join(', ')}
            </div>
          </div>

          <div className="quality-breakdown mt-4">
            <h4>Quality Breakdown</h4>
            <div className="grid grid-cols-3 gap-4">
              <div className="text-green-600">
                High Quality: {analysisResult.stats?.high_quality_files} files
              </div>
              <div className="text-yellow-600">
                Medium Quality: {analysisResult.stats?.medium_quality_files} files
              </div>
              <div className="text-red-600">
                Low Quality: {analysisResult.stats?.low_quality_files} files
              </div>
            </div>
          </div>

          <button 
            onClick={handleDownloadReport}
            className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded mt-4"
          >
            Download Report
          </button>
        </div>
      )}
    </div>
  );
};

export default RepositoryAnalysis;

Key Features Implemented

1. Rate Limiting

  • Claude API Rate Limiting: 90 requests per minute with proper queuing
  • Request Tracking: Tracks API requests to prevent rate limit violations
  • Dynamic Delays: Automatically adjusts delays based on request frequency

2. Content Optimization

  • Large File Handling: Truncates files larger than 32KB tokens
  • Important Line Extraction: Keeps imports, functions, classes, and exports
  • Smart Truncation: Preserves code structure while reducing size

3. Caching System

  • Redis-based Caching: Caches analysis results for 24 hours
  • File Hash-based Keys: Uses SHA-256 hashes for cache keys
  • Automatic Cache Invalidation: Handles cache misses gracefully

4. Error Handling

  • Graceful Degradation: Continues analysis even if some files fail
  • Retry Logic: Built-in retry mechanisms for API failures
  • Progress Tracking: Real-time progress updates during analysis

5. Service Integration

  • Git Integration Communication: HTTP API calls to git-integration service
  • Repository Info Retrieval: Gets local paths and metadata
  • Direct File Access: Uses local file system for analysis

Performance Improvements

Before (Original Implementation)

  • Time for 1000 files: 33-50 hours
  • Rate Limit Issues: Would exceed Claude API limits
  • No Caching: Re-analyzed files on every request
  • No Optimization: Sent full file content to API

After (Optimized Implementation)

  • Time for 1000 files: 2-4 hours
  • Rate Limit Compliance: Respects 90 requests/minute limit
  • Intelligent Caching: Avoids re-analysis of unchanged files
  • Content Optimization: Sends only essential code to API

Usage Flow

  1. Frontend calls /analyze-repository with repository ID
  2. AI Analysis Service gets repository info from git-integration service
  3. AI Analysis Service accesses files directly from local storage
  4. Rate Limiting ensures compliance with Claude API limits
  5. Caching checks for existing analysis results
  6. Content Optimization truncates large files intelligently
  7. Analysis processes files with memory integration
  8. Report Generation creates PDF or JSON reports
  9. Response returns analysis results and report path

This implementation provides a robust, scalable solution for repository analysis while maintaining service independence and optimal performance.