← 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 }
)
}
}