src/app/api/admin/vitrine/versions/route.ts
Annotation non disponible
Lance npm run annotate (nécessite ANTHROPIC_API_KEY dans .env.local) pour générer une annotation française par Claude Haiku 4.5.
Concepts détectés — comprends la théorie
ORM Prisma
6 occurrencesCe fichier accède à la base de données via Prisma. Prisma est l'ORM utilisé côté backend pour les requêtes typées sur PostgreSQL.
Voir l'article général
Route API Next.js
4 occurrencesCe fichier est une route API Next.js (App Router). Voir le contrat API complet pour les conventions de réponse et d'auth.
Voir l'article général
2 exports
GETPOST
Code source· typescript
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma/client'
import { getSession } from '@/lib/auth/session'
// Lister les versions
export async function GET() {
try {
const session = await getSession()
if (!session) return NextResponse.json({ error: 'Non autorise' }, { status: 401 })
const tenantId = session.tenantId as string
const snapshots = await prisma.vitrineSnapshot.findMany({
where: { tenantId },
orderBy: { createdAt: 'desc' },
take: 13,
select: { id: true, label: true, statut: true, isAutosave: true, previewToken: true, previewTokenExpiry: true, createdAt: true }
})
return NextResponse.json({ snapshots })
} catch (e) {
console.error(e)
return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 })
}
}
// Creer un snapshot depuis la DB live
export async function POST(req: NextRequest) {
try {
const session = await getSession()
if (!session) return NextResponse.json({ error: 'Non autorise' }, { status: 401 })
const tenantId = session.tenantId as string
const { label, statut, isAutosave } = await req.json()
// Capturer l'etat complet de la DB live
const pages = await prisma.vitrinePage.findMany({
where: { tenantId },
include: {
sections: {
orderBy: { ordre: 'asc' },
include: { blocs: { orderBy: { ordre: 'asc' } } }
}
},
orderBy: { ordre: 'asc' }
})
// Config navbar
const navbarPage = pages.find(p => p.type === 'GLOBALE' && p.slug === 'navbar')
const navbarConfig = navbarPage?.sections?.[0]?.config ?? {}
// Config footer
const footerPage = pages.find(p => p.type === 'GLOBALE' && p.slug === 'footer')
const footerConfig = footerPage?.sections?.[0]?.config ?? {}
// Si on publie, archiver l'ancien PUBLISHED
if (statut === 'PUBLISHED') {
await prisma.vitrineSnapshot.updateMany({
where: { tenantId, statut: 'PUBLISHED' },
data: { statut: 'DRAFT' }
})
}
// Limiter a 10 versions — supprimer les plus anciennes DRAFT
const count = await prisma.vitrineSnapshot.count({ where: { tenantId } })
if (count >= 10) {
const oldest = await prisma.vitrineSnapshot.findMany({
where: { tenantId, statut: 'DRAFT' },
orderBy: { createdAt: 'asc' },
take: count - 9,
select: { id: true }
})
if (oldest.length > 0) {
await prisma.vitrineSnapshot.deleteMany({
where: { id: { in: oldest.map(s => s.id) } }
})
}
}
const snapshot = await prisma.vitrineSnapshot.create({
data: {
tenantId,
label: label || new Date().toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }),
statut: statut || 'DRAFT',
data: { pages, navbarConfig, footerConfig }
}
})
return NextResponse.json({ snapshot })
} catch (e) {
console.error(e)
return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 })
}
}
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma/client'
import { getSession } from '@/lib/auth/session'
// Lister les versions
export async function GET() {
try {
const session = await getSession()
if (!session) return NextResponse.json({ error: 'Non autorise' }, { status: 401 })
const tenantId = session.tenantId as string
const snapshots = await prisma.vitrineSnapshot.findMany({
where: { tenantId },
orderBy: { createdAt: 'desc' },
take: 13,
select: { id: true, label: true, statut: true, isAutosave: true, previewToken: true, previewTokenExpiry: true, createdAt: true }
})
return NextResponse.json({ snapshots })
} catch (e) {
console.error(e)
return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 })
}
}
// Creer un snapshot depuis la DB live
export async function POST(req: NextRequest) {
try {
const session = await getSession()
if (!session) return NextResponse.json({ error: 'Non autorise' }, { status: 401 })
const tenantId = session.tenantId as string
const { label, statut, isAutosave } = await req.json()
// Capturer l'etat complet de la DB live
const pages = await prisma.vitrinePage.findMany({
where: { tenantId },
include: {
sections: {
orderBy: { ordre: 'asc' },
include: { blocs: { orderBy: { ordre: 'asc' } } }
}
},
orderBy: { ordre: 'asc' }
})
// Config navbar
const navbarPage = pages.find(p => p.type === 'GLOBALE' && p.slug === 'navbar')
const navbarConfig = navbarPage?.sections?.[0]?.config ?? {}
// Config footer
const footerPage = pages.find(p => p.type === 'GLOBALE' && p.slug === 'footer')
const footerConfig = footerPage?.sections?.[0]?.config ?? {}
// Si on publie, archiver l'ancien PUBLISHED
if (statut === 'PUBLISHED') {
await prisma.vitrineSnapshot.updateMany({
where: { tenantId, statut: 'PUBLISHED' },
data: { statut: 'DRAFT' }
})
}
// Limiter a 10 versions — supprimer les plus anciennes DRAFT
const count = await prisma.vitrineSnapshot.count({ where: { tenantId } })
if (count >= 10) {
const oldest = await prisma.vitrineSnapshot.findMany({
where: { tenantId, statut: 'DRAFT' },
orderBy: { createdAt: 'asc' },
take: count - 9,
select: { id: true }
})
if (oldest.length > 0) {
await prisma.vitrineSnapshot.deleteMany({
where: { id: { in: oldest.map(s => s.id) } }
})
}
}
const snapshot = await prisma.vitrineSnapshot.create({
data: {
tenantId,
label: label || new Date().toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }),
statut: statut || 'DRAFT',
data: { pages, navbarConfig, footerConfig }
}
})
return NextResponse.json({ snapshot })
} catch (e) {
console.error(e)
return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 })
}
}