Files
perauset-e2e-mrfz8msi/packages/functions/src/functions/inventory/review-inventory-request.function.ts
2026-07-11 08:21:55 +02:00

52 lines
1.7 KiB
TypeScript

import { z } from 'zod'
import { pikkuFunc } from '#pikku/pikku-types.gen.js'
import { setAuditContext } from '../../lib/audit-context.js'
import { NotFoundError } from '../../lib/errors.js'
import { validateTransition } from '../../lib/state-machine.js'
export const ReviewInventoryRequestInput = z.object({
requestId: z.string().uuid().describe('Inventory request ID to review'),
status: z.enum(['approved', 'rejected']).describe('Review decision'),
reviewNotes: z.string().optional().describe('Notes about the review decision'),
})
export const ReviewInventoryRequestOutput = z.object({
requestId: z.string().describe('Reviewed request ID'),
status: z.string().describe('New request status'),
})
export const reviewInventoryRequest = pikkuFunc({
expose: true,
approvalRequired: true,
tags: ['inventory.manage'],
input: ReviewInventoryRequestInput,
output: ReviewInventoryRequestOutput,
func: async ({ kysely }, { requestId, status, reviewNotes }, { session }) => {
const request = await kysely
.selectFrom('inventoryRequest')
.select(['requestId', 'status'])
.where('requestId', '=', requestId)
.executeTakeFirst()
if (!request) throw new NotFoundError('Inventory request not found')
validateTransition('inventory_request', request.status, status)
await setAuditContext(kysely, session!.userId)
await kysely
.updateTable('inventoryRequest')
.set({
status,
reviewedByUserId: session!.userId,
reviewedAt: new Date(),
reviewNotes: reviewNotes ?? null,
updatedAt: new Date(),
})
.where('requestId', '=', requestId)
.execute()
return { requestId, status }
},
})