← back to Dear Bubbe Nextjs

app/api/yiddish/route.ts

186 lines

import { NextRequest, NextResponse } from 'next/server'
import Database from 'better-sqlite3'
import path from 'path'

// Initialize database
const dbPath = path.join(process.cwd(), 'lib', 'yiddish-dictionary', 'yiddish_dictionary.sqlite')
let db: Database.Database | null = null

function getDb() {
  if (!db) {
    db = new Database(dbPath, { readonly: true })
  }
  return db
}

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams
  const action = searchParams.get('action')
  
  try {
    const database = getDb()
    
    switch (action) {
      case 'search': {
        const query = searchParams.get('q') || ''
        const lang = searchParams.get('lang') || 'english'
        const limit = parseInt(searchParams.get('limit') || '10')
        
        let stmt
        if (lang === 'yiddish') {
          stmt = database.prepare(`
            SELECT yiddish, yiddish_latin, english, pos, tags
            FROM entries
            WHERE (yiddish LIKE ? OR yiddish_latin LIKE ?)
              AND bubbe_approved = 1
            LIMIT ?
          `)
          return NextResponse.json(
            stmt.all(`%${query}%`, `%${query}%`, limit)
          )
        } else {
          stmt = database.prepare(`
            SELECT yiddish, yiddish_latin, english, pos, tags
            FROM entries
            WHERE english LIKE ?
              AND bubbe_approved = 1
            LIMIT ?
          `)
          return NextResponse.json(
            stmt.all(`%${query}%`, limit)
          )
        }
      }
      
      case 'random': {
        const type = searchParams.get('type') || 'expression'
        const intensity = searchParams.get('intensity')
        
        if (type === 'insult') {
          const stmt = database.prepare(`
            SELECT yiddish, yiddish_latin, english, tags
            FROM entries
            WHERE bubbe_approved = 1
              AND (tags LIKE '%insult%' OR tags LIKE '%scold%')
            ORDER BY RANDOM()
            LIMIT 1
          `)
          return NextResponse.json(stmt.get())
        } else if (type === 'favorite') {
          let query = `SELECT * FROM bubbe_favorites`
          const params = []
          
          if (intensity) {
            query += ` WHERE intensity >= ?`
            params.push(parseInt(intensity))
          }
          
          query += ` ORDER BY RANDOM() LIMIT 1`
          const stmt = database.prepare(query)
          return NextResponse.json(stmt.get(...params))
        } else {
          const stmt = database.prepare(`
            SELECT yiddish, yiddish_latin, english, tags
            FROM entries
            WHERE bubbe_approved = 1
            ORDER BY RANDOM()
            LIMIT 1
          `)
          return NextResponse.json(stmt.get())
        }
      }
      
      case 'suggestions': {
        const context = searchParams.get('context') || 'general'
        const limit = parseInt(searchParams.get('limit') || '5')
        
        const contextMap: Record<string, string> = {
          'greeting': '%greeting%',
          'insult': '%insult%',
          'complaint': '%complain%',
          'advice': '%advice%',
          'endearment': '%endearment%'
        }
        
        const tagPattern = contextMap[context] || '%common%'
        
        const stmt = database.prepare(`
          SELECT yiddish, yiddish_latin, english, tags
          FROM entries
          WHERE bubbe_approved = 1
            AND tags LIKE ?
          ORDER BY RANDOM()
          LIMIT ?
        `)
        
        return NextResponse.json(
          stmt.all(tagPattern, limit)
        )
      }
      
      case 'stats': {
        const stats = {
          totalEntries: database.prepare('SELECT COUNT(*) as count FROM entries').get() as any,
          approvedEntries: database.prepare('SELECT COUNT(*) as count FROM entries WHERE bubbe_approved = 1').get() as any,
          favorites: database.prepare('SELECT COUNT(*) as count FROM bubbe_favorites').get() as any,
          sources: database.prepare('SELECT COUNT(*) as count FROM sources').get() as any
        }
        
        return NextResponse.json({
          totalEntries: stats.totalEntries.count,
          approvedEntries: stats.approvedEntries.count,
          favorites: stats.favorites.count,
          sources: stats.sources.count
        })
      }
      
      default: {
        return NextResponse.json(
          { error: 'Invalid action. Use: search, random, suggestions, or stats' },
          { status: 400 }
        )
      }
    }
  } catch (error) {
    console.error('Yiddish API error:', error)
    return NextResponse.json(
      { error: 'Database error' },
      { status: 500 }
    )
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const { term, context } = body
    
    if (!term) {
      return NextResponse.json(
        { error: 'Term is required' },
        { status: 400 }
      )
    }
    
    const database = getDb()
    
    // Record usage
    const stmt = database.prepare(`
      INSERT INTO usage_stats (term, context, usage_count, last_used)
      VALUES (?, ?, 1, datetime('now'))
      ON CONFLICT (term) DO UPDATE SET
        usage_count = usage_count + 1,
        last_used = datetime('now')
    `)
    
    stmt.run(term, context || null)
    
    return NextResponse.json({ success: true })
  } catch (error) {
    console.error('Usage tracking error:', error)
    return NextResponse.json(
      { error: 'Failed to track usage' },
      { status: 500 }
    )
  }
}