Index: src/app/api/invoices/[id]/route.ts
===================================================================
--- src/app/api/invoices/[id]/route.ts	(revision 5d6f37a75130aab7d9a67b5b430603eff2c0ca6e)
+++ src/app/api/invoices/[id]/route.ts	(revision 057453cdc828f504e8bcd813422d99221b3b5732)
@@ -1,10 +1,16 @@
 import { NextRequest, NextResponse } from 'next/server';
-import { invoiceSchema } from 'mvpmasters-shared';
+import { invoiceSchema, updateInvoiceSchema } from 'src/schemas';
 import prisma from 'src/lib/prisma';
 import { authenticateRequest } from 'src/lib/auth-middleware';
+import { Prisma } from '@prisma/client';
 
-export async function PATCH(request: NextRequest, { params }: { params: { id: string } }) {
+export async function GET(request: NextRequest, { params }: { params: { id: string } }) {
   try {
-    // Authenticate the request
+    // Validate ID format
+    if (!params.id || !/^[0-9a-fA-F-]+$/.test(params.id)) {
+      return NextResponse.json({ error: 'Invalid invoice ID format' }, { status: 400 });
+    }
+
+    // Authenticate request
     const authResult = await authenticateRequest(request);
     if (authResult instanceof NextResponse) {
@@ -13,32 +19,181 @@
     const { userId } = authResult;
 
-    const body = await request.json();
-    const validatedData = invoiceSchema.partial().parse(body);
-
-    const invoice = await prisma.invoice.update({
-      where: { id: params.id, userId },
-      data: {
-        ...validatedData,
-        items: validatedData.items
-          ? {
-              deleteMany: {},
-              create: validatedData.items,
-            }
-          : undefined,
+    // Fetch invoice with user check
+    const invoice = await prisma.invoice.findFirst({
+      where: {
+        id: params.id,
+        // invoiceFromId: userId,
       },
       include: {
-        items: {
-          include: {
-            service: true,
-          },
-        },
         invoiceFrom: true,
         invoiceTo: true,
+        items: true,
       },
     });
 
+    if (!invoice) {
+      return NextResponse.json({ error: 'Invoice not found or access denied' }, { status: 404 });
+    }
+
     return NextResponse.json(invoice);
   } catch (error) {
-    return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
+    console.error('Error fetching invoice:', error);
+
+    if (error instanceof Prisma.PrismaClientKnownRequestError) {
+      return NextResponse.json({ error: 'Database error occurred' }, { status: 500 });
+    }
+
+    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
   }
 }
+
+export async function PATCH(request: NextRequest, { params }: { params: { id: string } }) {
+  try {
+    // Validate ID format
+    if (!params.id || !/^[0-9a-fA-F-]+$/.test(params.id)) {
+      return NextResponse.json({ error: 'Invalid invoice ID format' }, { status: 400 });
+    }
+
+    // Authenticate request
+    const authResult = await authenticateRequest(request);
+    if (authResult instanceof NextResponse) {
+      return authResult;
+    }
+    const { userId } = authResult;
+
+    // Parse and validate request body
+    const body = await request.json();
+
+    const validation = updateInvoiceSchema.partial().safeParse(body);
+
+    if (!validation.success) {
+      return NextResponse.json(
+        { error: 'Invalid invoice data', details: validation.error.format() },
+        { status: 400 }
+      );
+    }
+
+    // Verify invoice exists and belongs to user
+    const existingInvoice = await prisma.invoice.findFirst({
+      where: {
+        id: params.id,
+        // invoiceFromId: userId,
+      },
+    });
+
+    if (!existingInvoice) {
+      return NextResponse.json({ error: 'Invoice not found or access denied' }, { status: 404 });
+    }
+
+    // Update invoice and related data
+    const updatedInvoice = await prisma.$transaction(async (tx) => {
+      // Conditionally delete and recreate items only if they are provided
+      if (validation.data.items) {
+        await tx.invoiceItem.deleteMany({
+          where: { invoiceId: params.id },
+        });
+      }
+
+      // Update the invoice and create new items if provided
+      return tx.invoice.update({
+        where: { id: params.id },
+        data: {
+          invoiceNumber: validation.data.invoiceNumber,
+          createDate: validation.data.createDate,
+          dueDate: validation.data.dueDate,
+          status: validation.data.status,
+          currency: validation.data.currency,
+          quantityType: validation.data.quantityType,
+          subTotal: validation.data.subTotal,
+          month: validation.data.month,
+          totalAmount: validation.data.totalAmount,
+          discount: validation.data.discount,
+          taxes: validation.data.taxes,
+          pdfRef: validation.data.pdfRef,
+          invoiceTo: {
+            update: validation.data.invoiceTo,
+          },
+          items: validation.data.items
+            ? {
+                create: validation.data.items.map((item) => ({
+                  ...item,
+                  service: {
+                    connect: { id: item.service.id },
+                  },
+                })),
+              }
+            : undefined,
+        },
+        include: {
+          invoiceFrom: true,
+          invoiceTo: true,
+          items: true,
+        },
+      });
+    });
+
+    return NextResponse.json(updatedInvoice);
+  } catch (error) {
+    console.error('Error updating invoice:', error);
+
+    if (error instanceof Prisma.PrismaClientKnownRequestError) {
+      return NextResponse.json({ error: 'Database error occurred' }, { status: 500 });
+    }
+
+    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
+  }
+}
+
+export async function DELETE(request: NextRequest, { params }: { params: { id: string } }) {
+  try {
+    // Validate ID format
+    if (!params.id || !/^[0-9a-fA-F-]+$/.test(params.id)) {
+      return NextResponse.json({ error: 'Invalid invoice ID format' }, { status: 400 });
+    }
+
+    // Authenticate request
+    const authResult = await authenticateRequest(request);
+    if (authResult instanceof NextResponse) {
+      return authResult;
+    }
+    const { userId } = authResult;
+    console.log('userId', userId);
+
+    // Verify invoice exists and belongs to user
+    const existingInvoice = await prisma.invoice.findFirst({
+      where: {
+        id: params.id,
+      },
+    });
+
+    if (!existingInvoice) {
+      return NextResponse.json({ error: 'Invoice not found or access denied' }, { status: 404 });
+    }
+
+    // Delete invoice and related items in a transaction
+    await prisma.$transaction(async (tx) => {
+      // Delete related items first
+      await tx.invoiceItem.deleteMany({
+        where: { invoiceId: params.id },
+      });
+
+      // Delete the invoice
+      await tx.invoice.delete({
+        where: { id: params.id },
+      });
+    });
+
+    return NextResponse.json({ message: 'Invoice deleted successfully' }, { status: 200 });
+  } catch (error) {
+    console.error('Error deleting invoice:', error);
+
+    if (error instanceof Prisma.PrismaClientKnownRequestError) {
+      if (error.code === 'P2025') {
+        return NextResponse.json({ error: 'Invoice not found' }, { status: 404 });
+      }
+      return NextResponse.json({ error: 'Database error occurred' }, { status: 500 });
+    }
+
+    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
+  }
+}
