diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index d55446b..9984076 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -1401,8 +1401,8 @@ export default function AdminPage() {
Keine Beiträge.
) : ( (() => { - // Filter contributions - exclude timeline type (those go to timeline section) - let filtered = timelineContributions.filter(c => c.type !== 'timeline') + // Show all contribution types + let filtered = [...timelineContributions] if (contributionFilter === 'review') { filtered = filtered.filter(c => c.status === 'pending' || c.status === 'flagged') } else if (contributionFilter !== 'all') { diff --git a/src/app/api/contributions/route.ts b/src/app/api/contributions/route.ts index ffb00b8..4df1491 100644 --- a/src/app/api/contributions/route.ts +++ b/src/app/api/contributions/route.ts @@ -38,46 +38,45 @@ async function moderateWithAI(contributionId: number, content: string) { if (foundBadWord) { console.log(`[AI-Mod] ⚠️ INSTANT FLAG: "${foundBadWord}" detected!`) const db = getDb() - const flagResult = db.prepare(` + db.prepare(` UPDATE contributions SET status = 'flagged', moderation_reason = ? WHERE id = ? `).run(`Unangemessene Sprache: "${foundBadWord}"`, contributionId) - console.log(`[AI-Mod] ✅ FLAGGED ${contributionId} instantly:`, flagResult.changes, 'rows') - return // Done, no AI needed + console.log(`[AI-Mod] ✅ FLAGGED ${contributionId} instantly`) + return } - // Step 2: AI check for subtle issues + // Step 2: AI check for subtle issues (irrelevant content, hidden insults etc.) console.log(`[AI-Mod] No bad words, asking AI...`) try { - const prompt = `Ist dieser Text unangemessen für eine Gedenkseite? + const prompt = `Ist dieser Text angemessen für eine Gedenkseite einer verstorbenen Großmutter? "${content}" -ERLAUBT: Liebe, Vermissen, Trauer -VERBOTEN: Beleidigungen, Spam, Hassrede - -Antworte NUR mit JSON (keine Erklärung): -{"appropriate": true} oder {"appropriate": false, "reason": "..."} +ERLAUBT: Liebe, Vermissen, Trauer, Erinnerungen, persönliche Geschichten, Beileidsbekundungen +VERBOTEN: Beleidigungen, Spam, Hassrede, Werbung, völlig zusammenhanglose oder sinnlose Texte ohne Bezug +Antworte NUR mit JSON: +{"appropriate": true} oder {"appropriate": false, "reason": "kurze Begründung"} JSON:` const controller = new AbortController() - setTimeout(() => controller.abort(), 10000) // 10sec timeout + setTimeout(() => controller.abort(), 15000) const res = await fetch('http://localhost:11434/api/generate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, signal: controller.signal, body: JSON.stringify({ - model: 'qwen3:4b', + model: 'llama3.2:latest', prompt, stream: false, options: { temperature: 0.1, - num_predict: 50, - num_ctx: 256 + num_predict: 60, + num_ctx: 512 } }) }) @@ -102,22 +101,25 @@ JSON:` console.error(`[AI-Mod] Parse error:`, e) } - // Update DB if inappropriate + // Flag if inappropriate if (result && result.appropriate === false) { const db = getDb() - const updateResult = db.prepare(` + db.prepare(` UPDATE contributions SET status = 'flagged', moderation_reason = ? WHERE id = ? `).run(result.reason || 'KI-Warnung', contributionId) - - console.log(`[AI-Mod] ✅ FLAGGED ${contributionId}:`, updateResult) + console.log(`[AI-Mod] ⚠️ FLAGGED ${contributionId}: ${result.reason}`) } else { console.log(`[AI-Mod] ✅ Passed ${contributionId}`) } } catch (error: any) { - console.error(`[AI-Mod] Error for ${contributionId}:`, error.message) + if (error.name === 'AbortError') { + console.warn(`[AI-Mod] Timeout for ${contributionId}`) + } else { + console.error(`[AI-Mod] Error for ${contributionId}:`, error.message) + } } } @@ -135,9 +137,9 @@ export async function POST(request: Request) { const db = getDb() - // 1. Check bad words instantly + // 1. Check bad words instantly - clean content is auto-approved const badWordCheck = hasBadWords(content + ' ' + (title || '')) - const initialStatus = badWordCheck.flag ? 'flagged' : 'pending' + const initialStatus = badWordCheck.flag ? 'flagged' : 'approved' const moderationReason = badWordCheck.flag ? badWordCheck.reason : null // 2. Insert contribution diff --git a/src/app/page.tsx b/src/app/page.tsx index 8bf9b45..beeedf0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -218,6 +218,9 @@ export default async function HomePage() { {/* Photo Upload */}