Files
afrov2/app/api/businesses/route.ts
2026-04-11 23:30:14 +02:00

145 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { NextRequest, NextResponse } from 'next/server'
import prisma from '../../../lib/prisma'
import { MOCK_BUSINESSES } from '../../../lib/mockData'
// GET /api/businesses — List all businesses (Mock + DB)
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const category = searchParams.get('category')
const q = searchParams.get('q')?.toLowerCase()
const featured = searchParams.get('featured')
// 1. Fetch from Database
const where: any = {}
if (category && category !== 'All') where.category = category
if (featured === 'true') where.isFeatured = true
if (q) {
where.OR = [
{ name: { contains: q, mode: 'insensitive' } },
{ description: { contains: q, mode: 'insensitive' } },
// Simplified tags check
{ tags: { has: q } }
]
}
const dbBusinesses = await prisma.business.findMany({
where,
include: { owner: true, offers: true },
orderBy: { createdAt: 'desc' },
})
// 2. Filter Mock Businesses
const filteredMocks = MOCK_BUSINESSES.filter(biz => {
// Category filter
if (category && category !== 'All' && biz.category !== category) return false;
// Featured filter
if (featured === 'true' && !biz.isFeatured) return false;
// Search query filter
if (q) {
const matches =
biz.name.toLowerCase().includes(q) ||
biz.description.toLowerCase().includes(q) ||
biz.tags.some(t => t.toLowerCase().includes(q));
if (!matches) return false;
}
return true;
});
// 3. Combine and return
// Prioritize DB entries over mocks to show user-created data first
const combined = [...dbBusinesses, ...filteredMocks];
return NextResponse.json(combined)
} catch (error) {
console.error('GET /api/businesses error:', error)
return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 })
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const headerUserId = request.headers.get('x-user-id')
const { ownerId: bodyOwnerId, ...data } = body
const ownerId = bodyOwnerId || headerUserId
if (!ownerId) {
return NextResponse.json({ error: 'ownerId est requis (via body ou x-user-id header)' }, { status: 400 })
}
// 1. Sanitize data - ONLY pass fields that exist in the Prisma Business model
// We must exclude 'id', 'offers', 'owner', 'createdAt', 'updatedAt' from the data object
const cleanData: any = {
name: data.name || "Nouvelle Entreprise",
slug: data.slug || null,
category: data.category || "Autre",
location: data.location || "Ma Ville",
description: data.description || "",
logoUrl: data.logoUrl || "https://picsum.photos/200/200?random=default",
videoUrl: data.videoUrl || null,
contactEmail: data.contactEmail || "",
contactPhone: data.contactPhone || null,
socialLinks: data.socialLinks || {},
verified: data.verified ?? false,
viewCount: data.viewCount ?? 0,
rating: data.rating ?? 0,
tags: Array.isArray(data.tags) ? data.tags : [],
isFeatured: data.isFeatured ?? false,
founderName: data.founderName || null,
founderImageUrl: data.founderImageUrl || null,
keyMetric: data.keyMetric || null,
}
// 2. Slug Uniqueness Check
if (cleanData.slug) {
const slugConflict = await prisma.business.findFirst({
where: {
slug: cleanData.slug,
NOT: { ownerId: ownerId } // Important: allow the owner to keep their own slug
}
});
if (slugConflict) {
return NextResponse.json({
error: `Le lien personnalisé "${cleanData.slug}" est déjà utilisé par une autre entreprise. Veuillez en choisir un autre.`
}, { status: 400 });
}
}
let business;
const existing = await prisma.business.findFirst({
where: { ownerId: ownerId }
});
console.log('Upserting business for ownerId:', ownerId, 'Existing:', !!existing);
if (existing) {
// When updating, we use the sanitized cleanData and the existing record's id
business = await prisma.business.update({
where: { id: existing.id },
data: cleanData,
include: { owner: true }
});
} else {
// When creating, we add the ownerId to the sanitized cleanData
business = await prisma.business.create({
data: {
...cleanData,
ownerId: ownerId
},
include: { owner: true }
});
}
console.log('Business saved successfully:', business.id);
return NextResponse.json(business, { status: 200 })
} catch (error) {
console.error('POST /api/businesses error:', error)
return NextResponse.json({ error: 'Erreur lors de lenregistrement' }, { status: 500 })
}
}