refactor(assets): move workflows into use cases

This commit is contained in:
2026-06-04 22:10:43 +02:00
parent e88fb2e6d4
commit 2b908b24f6
8 changed files with 648 additions and 222 deletions
-198
View File
@@ -1,198 +0,0 @@
"use server"
import { revalidatePath } from "next/cache"
import {
createAssignment,
updateAssignment,
} from "@/lib/actions/assignament.actions"
import {
type CreateAssetFormType,
createAssetSchema,
type UpdateAssetFormType,
updateAssetSchema,
} from "@/lib/schemas/asset.schemas"
import { AssetService } from "@/services/asset.service"
import { AssignmentService } from "@/services/assignment.service"
import { ItemService } from "@/services/item.service"
import { MovementService } from "@/services/movement.service"
export async function createAssetAction(formData: CreateAssetFormType) {
try {
const validatedFields = createAssetSchema.safeParse(formData)
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
}
}
const { itemId, serialNumber, deliveryNote, status, notes, recipientId } =
validatedFields.data
const item = await ItemService.findByIdWithCategory(itemId)
if (!item) {
return {
success: false,
errors: { itemId: ["Item not found"] },
}
}
const existentAsset = await AssetService.findBySerialNumber(serialNumber)
if (existentAsset) {
return {
success: false,
errors: {
serialNumber: ["This serial number already exists"],
},
}
}
const newAsset = await AssetService.create({
item: { connect: { id: itemId } },
serialNumber,
deliveryNote,
status,
notes,
})
await MovementService.create({
itemId,
assetId: newAsset?.id,
quantity: 1,
type: status === "ASSIGNED" ? "ASSIGNMENT" : "IN",
})
if (status === "AVAILABLE") {
await ItemService.update(itemId, {
stock: item.stock + 1,
name: item.name,
category: { connect: { id: item.category?.id } },
})
}
if (status === "ASSIGNED" && recipientId) {
await AssignmentService.create({
notes: "",
itemId,
assetId: newAsset?.id,
quantity: 1,
recipientId,
assignmentDate: new Date(),
})
}
revalidatePath("/inventory/assets")
return {
success: true,
message: "Asset created successfully",
}
} catch (error) {
console.error("Database error:", error)
return {
success: false,
message: "Error creating asset",
}
}
}
export async function updateAssetAction(formData: UpdateAssetFormType) {
const validatedFields = updateAssetSchema.safeParse(formData)
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
}
}
const { id, itemId, serialNumber, deliveryNote, status, notes, recipientId } =
validatedFields.data
try {
const item = await ItemService.findByIdWithCategory(itemId)
if (!item) {
return {
success: false,
errors: { itemId: ["Item not found"] },
}
}
const existentAsset = await AssetService.findBySerialNumber(serialNumber)
if (
existentAsset &&
id !== existentAsset.id &&
existentAsset.serialNumber === serialNumber
) {
return {
success: false,
errors: {
serialNumber: ["This serial number already exists"],
},
}
}
await AssetService.update(id, {
item: { connect: { id: itemId } },
serialNumber,
deliveryNote,
status,
notes,
})
await MovementService.create({
itemId,
assetId: id,
quantity: 1,
type: status === "ASSIGNED" ? "ASSIGNMENT" : "IN",
})
if (status === "AVAILABLE") {
await ItemService.update(itemId, {
stock: item.stock + 1,
name: item.name,
category: { connect: { id: item.category?.id } },
})
}
if (status === "ASSIGNED" && recipientId) {
if (!recipientId) {
return {
success: false,
errors: { recipientId: ["Recipient is required for assignment"] },
}
}
if (existentAsset?.assignment) {
await updateAssignment({
id: existentAsset.assignment.id,
recipientId,
quantity: 1,
})
} else {
await createAssignment({
itemId,
assetId: id,
quantity: 1,
recipientId,
assignmentDate: new Date(),
})
}
}
return {
success: true,
message: "Asset updated successfully",
}
} catch (error) {
console.error("Database error:", error)
return {
success: false,
message: "Error updating asset",
}
}
}
+11 -1
View File
@@ -3,7 +3,17 @@ const isDemo = process.env.DEMO_MODE === "true"
export const ENVIRONMENT = isDemo
? "demo"
: process.env.NODE_ENV || "development"
export const SIGN_IN_URL = "/login"
export const TOKEN_EXPIRATION_SECONDS = 60 * 60 * 2 // 2 hour
export const ITEM_STATUS = {
AVAILABLE: "AVAILABLE",
ASSIGNED: "ASSIGNED",
RESERVED: "RESERVED",
IN_REPAIR: "IN_REPAIR",
BROKEN: "BROKEN",
STOLEN: "STOLEN",
DISPOSED: "DISPOSED",
} as const
-29
View File
@@ -1,29 +0,0 @@
import { z } from "zod"
export const assetSchema = z.object({
id: z.string().optional(),
itemId: z.string().min(1, {
error: "Item is required"
}),
serialNumber: z.string().min(1, {
error: "Serial number is required"
}),
deliveryNote: z.string().optional(),
notes: z.string().optional(),
recipientId: z.string().optional(),
})
export const createAssetSchema = assetSchema.extend({
status: z.enum(["AVAILABLE", "ASSIGNED"]),
})
export type CreateAssetFormType = z.infer<typeof createAssetSchema>
export const updateAssetSchema = assetSchema.extend({
id: z.string().min(1, {
error: "ID is required"
}),
status: z.enum(["AVAILABLE", "ASSIGNED", "RESERVED", "IN_REPAIR"]),
})
export type UpdateAssetFormType = z.infer<typeof updateAssetSchema>