import { NextRequest, NextResponse } from 'next/server' import TopicModel, { transformToTopic } from '@/models/topic' import { authMiddleware } from '@/lib/auth-middleware' import { uploadFile, moveToPermStorage, getFileUrl, generateUniqueFilename } from '@/lib/file-vault' import { z } from 'zod' // Validation schema for topic updates const topicUpdateSchema = z.object({ title: z.string().min(1).max(100).optional(), author: z.string().min(1).optional(), excerpt: z.string().min(1).max(200).optional(), content: z.string().min(1).optional(), contentRTE: z.unknown().optional(), contentImages: z.array(z.string()).optional(), tags: z .array( z.object({ id: z.string().optional(), name: z.string(), }) ) .min(1) .optional(), featured: z.boolean().optional(), isDraft: z.boolean().optional(), coverImage: z.string().url().optional(), coverImageKey: z.string().optional(), }) // GET /api/topic/[id] - Get topic by ID export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { try { const { id } = await params const topic = await TopicModel.findOne({ id }).lean() if (!topic) { return NextResponse.json( { success: false, error: { message: 'Topic not found', code: 'NOT_FOUND' }, }, { status: 404 } ) } // Check if topic is draft and user is not the owner if (topic.isDraft) { const user = await authMiddleware(request) if (!user || user.id !== topic.authorId) { return NextResponse.json( { success: false, error: { message: 'Topic not found', code: 'NOT_FOUND' }, }, { status: 404 } ) } } const transformedTopic = transformToTopic(topic) return NextResponse.json( { success: true, data: transformedTopic, }, { status: 200 } ) } catch (error) { console.error('Error fetching topic:', error) return NextResponse.json( { success: false, error: { message: 'Failed to fetch topic', code: 'SERVER_ERROR' }, }, { status: 500 } ) } } // PUT /api/topic/[id] - Update topic by ID export async function PUT(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { try { // Authentication required for updating topics const user = await authMiddleware(request) if (!user) { return NextResponse.json( { success: false, error: { message: 'Authentication required', code: 'AUTH_REQUIRED' }, }, { status: 401 } ) } const { id } = await params // Find the topic first const existingTopic = await TopicModel.findOne({ id }) if (!existingTopic) { return NextResponse.json( { success: false, error: { message: 'Topic not found', code: 'NOT_FOUND' }, }, { status: 404 } ) } // Check ownership - users can only update their own topics if (existingTopic.authorId !== user.id) { return NextResponse.json( { success: false, error: { message: 'You can only edit your own topics', code: 'FORBIDDEN' }, }, { status: 403 } ) } const body = await request.json() // Validate request body const validatedData = topicUpdateSchema.parse(body) console.log('Updating topic for user:', user.id, 'Topic ID:', id) try { // Update the topic with new data Object.assign(existingTopic, validatedData) existingTopic.publishedAt = Date.now() // Update timestamp const updatedTopic = await existingTopic.save() console.log('Topic updated successfully:', updatedTopic.id) return NextResponse.json( { success: true, data: updatedTopic, }, { status: 200 } ) } catch (error) { console.error('Failed to update topic:', error) if (error.code === 11000) { return NextResponse.json( { success: false, error: { message: 'A topic with this slug already exists', code: 'DUPLICATE_SLUG' }, }, { status: 409 } ) } throw error } } catch (error) { console.error('Error updating topic:', error) if (error instanceof z.ZodError) { return NextResponse.json( { success: false, error: { message: 'Validation failed', code: 'VALIDATION_ERROR', details: error.issues, }, }, { status: 400 } ) } return NextResponse.json( { success: false, error: { message: 'Failed to update topic', code: 'SERVER_ERROR' }, }, { status: 500 } ) } } // DELETE /api/topic/[id] - Delete topic by ID export async function DELETE( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { // Authentication required for deleting topics const user = await authMiddleware(request) if (!user) { return NextResponse.json( { success: false, error: { message: 'Authentication required', code: 'AUTH_REQUIRED' }, }, { status: 401 } ) } const { id } = await params // Find the topic first const existingTopic = await TopicModel.findOne({ id }) if (!existingTopic) { return NextResponse.json( { success: false, error: { message: 'Topic not found', code: 'NOT_FOUND' }, }, { status: 404 } ) } // Check ownership - users can only delete their own topics if (existingTopic.authorId !== user.id) { return NextResponse.json( { success: false, error: { message: 'You can only delete your own topics', code: 'FORBIDDEN' }, }, { status: 403 } ) } console.log('Deleting topic for user:', user.id, 'Topic ID:', id) try { await TopicModel.deleteOne({ id }) console.log('Topic deleted successfully:', id) return NextResponse.json( { success: true, message: 'Topic deleted successfully', }, { status: 200 } ) } catch (error) { console.error('Failed to delete topic:', error) throw error } } catch (error) { console.error('Error deleting topic:', error) return NextResponse.json( { success: false, error: { message: 'Failed to delete topic', code: 'SERVER_ERROR' }, }, { status: 500 } ) } }