auditing
This commit is contained in:
@@ -25,6 +25,7 @@ import type {
|
||||
InventoryUnitOfMeasure,
|
||||
} from "@mrp/shared/dist/inventory/types.js";
|
||||
|
||||
import { logAuditEvent } from "../../lib/audit.js";
|
||||
import { prisma } from "../../lib/prisma.js";
|
||||
|
||||
type BomLineRecord = {
|
||||
@@ -841,6 +842,21 @@ export async function createInventoryTransaction(itemId: string, payload: Invent
|
||||
},
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId: createdById,
|
||||
entityType: "inventory-item",
|
||||
entityId: itemId,
|
||||
action: "transaction.created",
|
||||
summary: `Posted ${payload.transactionType.toLowerCase()} transaction for inventory item ${itemId}.`,
|
||||
metadata: {
|
||||
transactionType: payload.transactionType,
|
||||
quantity: payload.quantity,
|
||||
warehouseId: payload.warehouseId,
|
||||
locationId: payload.locationId,
|
||||
reference: payload.reference.trim(),
|
||||
},
|
||||
});
|
||||
|
||||
const nextDetail = await getInventoryItemById(itemId);
|
||||
return nextDetail ? { ok: true as const, item: nextDetail } : { ok: false as const, reason: "Unable to load updated inventory item." };
|
||||
}
|
||||
@@ -921,11 +937,26 @@ export async function createInventoryTransfer(itemId: string, payload: Inventory
|
||||
});
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId: createdById,
|
||||
entityType: "inventory-item",
|
||||
entityId: itemId,
|
||||
action: "transfer.created",
|
||||
summary: `Transferred ${payload.quantity} units for inventory item ${itemId}.`,
|
||||
metadata: {
|
||||
quantity: payload.quantity,
|
||||
fromWarehouseId: payload.fromWarehouseId,
|
||||
fromLocationId: payload.fromLocationId,
|
||||
toWarehouseId: payload.toWarehouseId,
|
||||
toLocationId: payload.toLocationId,
|
||||
},
|
||||
});
|
||||
|
||||
const nextDetail = await getInventoryItemById(itemId);
|
||||
return nextDetail ? { ok: true as const, item: nextDetail } : { ok: false as const, reason: "Unable to load updated inventory item." };
|
||||
}
|
||||
|
||||
export async function createInventoryReservation(itemId: string, payload: InventoryReservationInput) {
|
||||
export async function createInventoryReservation(itemId: string, payload: InventoryReservationInput, createdById?: string | null) {
|
||||
const item = await prisma.inventoryItem.findUnique({
|
||||
where: { id: itemId },
|
||||
select: { id: true },
|
||||
@@ -969,11 +1000,25 @@ export async function createInventoryReservation(itemId: string, payload: Invent
|
||||
},
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId: createdById,
|
||||
entityType: "inventory-item",
|
||||
entityId: itemId,
|
||||
action: "reservation.created",
|
||||
summary: `Created manual reservation for inventory item ${itemId}.`,
|
||||
metadata: {
|
||||
quantity: payload.quantity,
|
||||
warehouseId: payload.warehouseId,
|
||||
locationId: payload.locationId,
|
||||
sourceType: "MANUAL",
|
||||
},
|
||||
});
|
||||
|
||||
const nextDetail = await getInventoryItemById(itemId);
|
||||
return nextDetail ? { ok: true as const, item: nextDetail } : { ok: false as const, reason: "Unable to load updated inventory item." };
|
||||
}
|
||||
|
||||
export async function createInventoryItem(payload: InventoryItemInput) {
|
||||
export async function createInventoryItem(payload: InventoryItemInput, actorId?: string | null) {
|
||||
const validatedBom = await validateBomLines(null, payload.bomLines);
|
||||
if (!validatedBom.ok) {
|
||||
return null;
|
||||
@@ -1012,10 +1057,24 @@ export async function createInventoryItem(payload: InventoryItemInput) {
|
||||
},
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId,
|
||||
entityType: "inventory-item",
|
||||
entityId: item.id,
|
||||
action: "created",
|
||||
summary: `Created inventory item ${payload.sku}.`,
|
||||
metadata: {
|
||||
sku: payload.sku,
|
||||
name: payload.name,
|
||||
type: payload.type,
|
||||
status: payload.status,
|
||||
},
|
||||
});
|
||||
|
||||
return getInventoryItemById(item.id);
|
||||
}
|
||||
|
||||
export async function updateInventoryItem(itemId: string, payload: InventoryItemInput) {
|
||||
export async function updateInventoryItem(itemId: string, payload: InventoryItemInput, actorId?: string | null) {
|
||||
const existingItem = await prisma.inventoryItem.findUnique({
|
||||
where: { id: itemId },
|
||||
});
|
||||
@@ -1061,6 +1120,20 @@ export async function updateInventoryItem(itemId: string, payload: InventoryItem
|
||||
},
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId,
|
||||
entityType: "inventory-item",
|
||||
entityId: item.id,
|
||||
action: "updated",
|
||||
summary: `Updated inventory item ${payload.sku}.`,
|
||||
metadata: {
|
||||
sku: payload.sku,
|
||||
name: payload.name,
|
||||
type: payload.type,
|
||||
status: payload.status,
|
||||
},
|
||||
});
|
||||
|
||||
return getInventoryItemById(item.id);
|
||||
}
|
||||
|
||||
@@ -1092,7 +1165,7 @@ export async function getWarehouseById(warehouseId: string) {
|
||||
return warehouse ? mapWarehouseDetail(warehouse) : null;
|
||||
}
|
||||
|
||||
export async function createWarehouse(payload: WarehouseInput) {
|
||||
export async function createWarehouse(payload: WarehouseInput, actorId?: string | null) {
|
||||
const locations = normalizeWarehouseLocations(payload.locations);
|
||||
|
||||
const warehouse = await prisma.warehouse.create({
|
||||
@@ -1113,10 +1186,23 @@ export async function createWarehouse(payload: WarehouseInput) {
|
||||
},
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId,
|
||||
entityType: "warehouse",
|
||||
entityId: warehouse.id,
|
||||
action: "created",
|
||||
summary: `Created warehouse ${warehouse.code}.`,
|
||||
metadata: {
|
||||
code: warehouse.code,
|
||||
name: warehouse.name,
|
||||
locationCount: warehouse.locations.length,
|
||||
},
|
||||
});
|
||||
|
||||
return mapWarehouseDetail(warehouse);
|
||||
}
|
||||
|
||||
export async function updateWarehouse(warehouseId: string, payload: WarehouseInput) {
|
||||
export async function updateWarehouse(warehouseId: string, payload: WarehouseInput, actorId?: string | null) {
|
||||
const existingWarehouse = await prisma.warehouse.findUnique({
|
||||
where: { id: warehouseId },
|
||||
});
|
||||
@@ -1145,5 +1231,18 @@ export async function updateWarehouse(warehouseId: string, payload: WarehouseInp
|
||||
},
|
||||
});
|
||||
|
||||
await logAuditEvent({
|
||||
actorId,
|
||||
entityType: "warehouse",
|
||||
entityId: warehouse.id,
|
||||
action: "updated",
|
||||
summary: `Updated warehouse ${warehouse.code}.`,
|
||||
metadata: {
|
||||
code: warehouse.code,
|
||||
name: warehouse.name,
|
||||
locationCount: warehouse.locations.length,
|
||||
},
|
||||
});
|
||||
|
||||
return mapWarehouseDetail(warehouse);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user