Bernt Christian Egeland il y a 7 mois
Parent
commit
88527ed30f

+ 108 - 0
src/app/api/desktop/v1/vehicles/[id]/route.ts

@@ -0,0 +1,108 @@
+import { NextResponse } from "next/server";
+import { db } from "@/lib/db";
+import { withDesktopAuth } from "@/lib/with-desktop-auth";
+import { PermissionAction, PermissionSubject } from "@/lib/permissions";
+import { updateVehicleSchema } from "@/features/vehicles/Schema/vehicleSchema";
+
+export async function GET(
+  request: Request,
+  { params }: { params: Promise<{ id: string }> },
+) {
+  const { id } = await params;
+
+  return withDesktopAuth(
+    request,
+    async ({ organizationId }) => {
+      const vehicle = await db.vehicle.findFirst({
+        where: { id, organizationId },
+        include: {
+          customer: { select: { id: true, name: true, company: true, email: true, phone: true } },
+          _count: { select: { serviceRecords: true } },
+        },
+      });
+
+      if (!vehicle) {
+        return NextResponse.json({ error: "Vehicle not found" }, { status: 404 });
+      }
+
+      return NextResponse.json({ vehicle });
+    },
+    {
+      requiredPermissions: [
+        { action: PermissionAction.READ, subject: PermissionSubject.VEHICLES },
+      ],
+    },
+  );
+}
+
+export async function PUT(
+  request: Request,
+  { params }: { params: Promise<{ id: string }> },
+) {
+  const { id } = await params;
+
+  return withDesktopAuth(
+    request,
+    async ({ organizationId }) => {
+      const body = await request.json();
+      const { id: _schemaId, ...data } = updateVehicleSchema.parse({ ...body, id });
+
+      const result = await db.vehicle.updateMany({
+        where: { id, organizationId },
+        data: {
+          ...data,
+          vin: data.vin !== undefined ? (data.vin || null) : undefined,
+          licensePlate: data.licensePlate !== undefined ? (data.licensePlate || null) : undefined,
+          color: data.color !== undefined ? (data.color || null) : undefined,
+          fuelType: data.fuelType !== undefined ? (data.fuelType || null) : undefined,
+          transmission: data.transmission !== undefined ? (data.transmission || null) : undefined,
+          engineSize: data.engineSize !== undefined ? (data.engineSize || null) : undefined,
+          purchaseDate: data.purchaseDate ? new Date(data.purchaseDate) : undefined,
+          customerId: data.customerId !== undefined ? (data.customerId || null) : undefined,
+        },
+      });
+
+      if (result.count === 0) {
+        return NextResponse.json({ error: "Vehicle not found" }, { status: 404 });
+      }
+
+      const vehicle = await db.vehicle.findFirst({
+        where: { id, organizationId },
+      });
+
+      return NextResponse.json({ vehicle });
+    },
+    {
+      requiredPermissions: [
+        { action: PermissionAction.UPDATE, subject: PermissionSubject.VEHICLES },
+      ],
+    },
+  );
+}
+
+export async function DELETE(
+  request: Request,
+  { params }: { params: Promise<{ id: string }> },
+) {
+  const { id } = await params;
+
+  return withDesktopAuth(
+    request,
+    async ({ organizationId }) => {
+      const result = await db.vehicle.deleteMany({
+        where: { id, organizationId },
+      });
+
+      if (result.count === 0) {
+        return NextResponse.json({ error: "Vehicle not found" }, { status: 404 });
+      }
+
+      return new NextResponse(null, { status: 204 });
+    },
+    {
+      requiredPermissions: [
+        { action: PermissionAction.DELETE, subject: PermissionSubject.VEHICLES },
+      ],
+    },
+  );
+}

+ 89 - 0
src/app/api/desktop/v1/vehicles/route.ts

@@ -0,0 +1,89 @@
+import { NextResponse } from "next/server";
+import { db } from "@/lib/db";
+import { withDesktopAuth } from "@/lib/with-desktop-auth";
+import { PermissionAction, PermissionSubject } from "@/lib/permissions";
+import { createVehicleSchema } from "@/features/vehicles/Schema/vehicleSchema";
+
+export async function GET(request: Request) {
+  return withDesktopAuth(
+    request,
+    async ({ organizationId }) => {
+      const url = new URL(request.url);
+      const page = Math.max(1, parseInt(url.searchParams.get("page") || "1", 10));
+      const pageSize = Math.min(100, Math.max(1, parseInt(url.searchParams.get("pageSize") || "20", 10)));
+      const search = url.searchParams.get("search") || "";
+      const archived = url.searchParams.get("archived") === "true";
+      const skip = (page - 1) * pageSize;
+
+      // eslint-disable-next-line @typescript-eslint/no-explicit-any
+      const where: any = { organizationId, isArchived: archived };
+
+      if (search) {
+        where.OR = [
+          { make: { contains: search, mode: "insensitive" } },
+          { model: { contains: search, mode: "insensitive" } },
+          { licensePlate: { contains: search, mode: "insensitive" } },
+          { vin: { contains: search, mode: "insensitive" } },
+          { customer: { name: { contains: search, mode: "insensitive" } } },
+        ];
+        if (!isNaN(Number(search))) {
+          where.OR.push({ year: Number(search) });
+        }
+      }
+
+      const [vehicles, total] = await Promise.all([
+        db.vehicle.findMany({
+          where,
+          include: {
+            customer: { select: { id: true, name: true, company: true } },
+            _count: { select: { serviceRecords: true } },
+          },
+          orderBy: { updatedAt: "desc" },
+          skip,
+          take: pageSize,
+        }),
+        db.vehicle.count({ where }),
+      ]);
+
+      return NextResponse.json({
+        vehicles,
+        total,
+        page,
+        pageSize,
+        totalPages: Math.ceil(total / pageSize),
+      });
+    },
+    {
+      requiredPermissions: [
+        { action: PermissionAction.READ, subject: PermissionSubject.VEHICLES },
+      ],
+    },
+  );
+}
+
+export async function POST(request: Request) {
+  return withDesktopAuth(
+    request,
+    async ({ userId, organizationId }) => {
+      const body = await request.json();
+      const data = createVehicleSchema.parse(body);
+
+      const vehicle = await db.vehicle.create({
+        data: {
+          ...data,
+          purchaseDate: data.purchaseDate ? new Date(data.purchaseDate) : null,
+          customerId: data.customerId || null,
+          userId,
+          organizationId,
+        },
+      });
+
+      return NextResponse.json({ vehicle }, { status: 201 });
+    },
+    {
+      requiredPermissions: [
+        { action: PermissionAction.CREATE, subject: PermissionSubject.VEHICLES },
+      ],
+    },
+  );
+}