Page publique (/p/[slug]): - Design éditorial moderne (Source Serif 4 + Inter, couleurs Momento) - KaTeX rendu côté serveur (plus de 3184089 en brut) - Callouts colorés, toggles, colonnes, code blocks rendus correctement - Barre sticky avec logo + bouton Signaler - Temps de lecture estimé - Footer Momento - Responsive Modération: - content-moderation.service.ts — IA classe safe/flagged/blocked - Sera appelée automatiquement à la publication Signalement: - Page /p/[slug]/report — formulaire de signalement public - API /api/notes/report — stocke notification au propriétaire + admins - 8 motifs: illegal, haine, violence, sexuel, harcèlement, copyright, spam, autre i18n: FR/EN
52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import prisma from '@/lib/prisma'
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const { slug, reason, details } = await request.json()
|
|
if (!slug || !reason) {
|
|
return NextResponse.json({ error: 'slug and reason required' }, { status: 400 })
|
|
}
|
|
|
|
const note = await prisma.note.findFirst({
|
|
where: { publicSlug: slug, isPublic: true },
|
|
select: { id: true, userId: true },
|
|
})
|
|
if (!note) return NextResponse.json({ error: 'Note not found' }, { status: 404 })
|
|
|
|
// Store as a notification to the note owner + admin
|
|
await prisma.notification.create({
|
|
data: {
|
|
userId: note.userId,
|
|
type: 'content_report',
|
|
title: `Signalement : ${reason}`,
|
|
message: details || `Un visiteur a signalé votre note publiée pour: ${reason}`,
|
|
actionUrl: `/p/${slug}`,
|
|
relatedId: note.id,
|
|
},
|
|
}).catch(() => {})
|
|
|
|
// Also notify admins
|
|
const admins = await prisma.user.findMany({
|
|
where: { role: 'ADMIN' },
|
|
select: { id: true },
|
|
})
|
|
for (const admin of admins) {
|
|
await prisma.notification.create({
|
|
data: {
|
|
userId: admin.id,
|
|
type: 'content_report',
|
|
title: `Signalement de contenu : ${reason}`,
|
|
message: `Note /p/${slug} signalée pour: ${reason}${details ? ` — ${details}` : ''}`,
|
|
actionUrl: `/admin/published`,
|
|
relatedId: note.id,
|
|
},
|
|
}).catch(() => {})
|
|
}
|
|
|
|
return NextResponse.json({ success: true })
|
|
} catch (error: any) {
|
|
return NextResponse.json({ error: error.message }, { status: 500 })
|
|
}
|
|
}
|