feat(ST-xmwvqru1): admin jobs-actions (cancelJob, deleteJob)
- lib/session.ts: isAdmin: boolean toegevoegd
- lib/auth-guard.ts: requireAdmin() toegevoegd
- actions/admin/jobs.ts: cancelJobAction (CUID-validatie, eindstatus-check → CANCELLED),
deleteJobAction (hard delete) — beide 'use server', revalidatePath('/admin/jobs')
This commit is contained in:
parent
64b8c7f5d7
commit
788920b790
3 changed files with 50 additions and 0 deletions
41
actions/admin/jobs.ts
Normal file
41
actions/admin/jobs.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
'use server'
|
||||
|
||||
import { revalidatePath } from 'next/cache'
|
||||
import { z } from 'zod'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { requireAdmin } from '@/lib/auth-guard'
|
||||
|
||||
const cuidSchema = z.string().cuid()
|
||||
|
||||
export async function cancelJobAction(jobId: string) {
|
||||
await requireAdmin()
|
||||
|
||||
const parsed = cuidSchema.safeParse(jobId)
|
||||
if (!parsed.success) throw new Error('Ongeldig job-id')
|
||||
|
||||
const job = await prisma.claudeJob.findUnique({
|
||||
where: { id: parsed.data },
|
||||
select: { status: true },
|
||||
})
|
||||
|
||||
if (!job) throw new Error('Job niet gevonden')
|
||||
if (job.status === 'DONE' || job.status === 'FAILED' || job.status === 'CANCELLED') {
|
||||
throw new Error('Job is al in eindstatus')
|
||||
}
|
||||
|
||||
await prisma.claudeJob.update({
|
||||
where: { id: parsed.data },
|
||||
data: { status: 'CANCELLED', finished_at: new Date() },
|
||||
})
|
||||
revalidatePath('/admin/jobs')
|
||||
}
|
||||
|
||||
export async function deleteJobAction(jobId: string) {
|
||||
await requireAdmin()
|
||||
|
||||
const parsed = cuidSchema.safeParse(jobId)
|
||||
if (!parsed.success) throw new Error('Ongeldig job-id')
|
||||
|
||||
await prisma.claudeJob.delete({ where: { id: parsed.data } })
|
||||
revalidatePath('/admin/jobs')
|
||||
}
|
||||
|
|
@ -22,3 +22,11 @@ export async function requireSession() {
|
|||
|
||||
return session
|
||||
}
|
||||
|
||||
export async function requireAdmin() {
|
||||
const session = await getSession()
|
||||
if (!session.userId || !session.isAdmin) {
|
||||
redirect('/dashboard')
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { SessionOptions } from 'iron-session'
|
|||
export interface SessionData {
|
||||
userId: string
|
||||
isDemo: boolean
|
||||
isAdmin: boolean
|
||||
// ST-1002 (M10) — gezet door /api/auth/pair/claim na een succesvolle QR-pairing.
|
||||
// Beide velden zijn optioneel zodat bestaande wachtwoord-sessies onveranderd blijven.
|
||||
paired?: boolean
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue