← back to ClawCoder

src/app/api/analyze/route.ts

70 lines

import { NextResponse } from 'next/server'
import { prisma } from '@/lib/db'

export async function POST(request: Request) {
  try {
    const { content, source } = await request.json()

    if (!content || typeof content !== 'string') {
      return NextResponse.json({ error: 'content is required and must be a string' }, { status: 400 })
    }

    if (content.length > 100000) {
      return NextResponse.json({ error: 'Content too large (max 100KB)' }, { status: 400 })
    }

    // Dynamic import to handle Phase 2 not being built yet.
    // The analyzer module exports: analyzeClaudeMd(content) => AnalysisResult
    // The suggester module exports: generateSuggestions(content, analysis) => Suggestion[]
    // The matcher module exports: detectProfile(content) => string | null
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let analysis: any
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let suggestions: any
    let detectedProfile: string | null | undefined
    try {
      const scorerModule = await import('@/lib/analyzer/scorer')
      const suggesterModule = await import('@/lib/analyzer/suggester')
      const matcherModule = await import('@/lib/analyzer/matcher')

      analysis = scorerModule.analyzeClaudeMd(content)
      suggestions = suggesterModule.generateSuggestions(content, analysis)
      detectedProfile = matcherModule.detectProfile(content)
    } catch {
      return NextResponse.json({ error: 'Analyzer module not yet available' }, { status: 503 })
    }

    const saved = await prisma.analysis.create({
      data: {
        inputContent: content,
        inputSource: source || 'paste',
        overallScore: analysis.percentage,
        letterGrade: analysis.letterGrade,
        criteriaScores: analysis.criteria as object,
        pros: analysis.pros as object,
        cons: analysis.cons as object,
        suggestions: suggestions as object,
        detectedProfileSlug: detectedProfile ?? null,
      },
    })

    return NextResponse.json({
      id: saved.id,
      overallScore: analysis.overallScore,
      maxScore: analysis.maxScore,
      percentage: analysis.percentage,
      letterGrade: analysis.letterGrade,
      criteria: analysis.criteria,
      pros: analysis.pros,
      cons: analysis.cons,
      suggestions,
      detectedProfileSlug: detectedProfile ?? null,
      lineCount: analysis.lineCount,
    })
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : 'Analysis failed'
    console.error('Analyze error:', err)
    return NextResponse.json({ error: message }, { status: 500 })
  }
}