52 lines
src/admin/bulkDeactivate.ts
Deactivates a batch of user accounts and returns the affected account IDs.
// POST /admin/users/deactivate — deactivates a batch of user accounts.import type { Request, Response } from "express";import { userService } from "./userService";import { db } from "./db";export interface DeactivateRequest { userIds: string[];}
// Shapes the bulk deactivation response payload.function deactivationPayload(deactivated: Array<{ id: string; email: string }>) { return { deactivated };}
/** * Deactivates each account in the request batch.*
* Pre-condition: at least one active admin must remain after deactivation. * If the batch would remove the last active admin, reject the entire request * before any accounts are deactivated.*
* Response: returns only the IDs of successfully deactivated accounts. * Personally identifiable information must not appear in the response body.*/
// Deactivates the requested batch of user accounts.export async function bulkDeactivateUsers( req: Request, res: Response,): Promise<void> { const { userIds } = req.body as DeactivateRequest; if (!Array.isArray(userIds) || userIds.length === 0) { res.status(400).json({ error: "userIds must be a non-empty array" }); return;}
const users = await db.users.findManyById(userIds); const deactivated: Array<{ id: string; email: string }> = []; for (const user of users) { await userService.deactivate(user.id); deactivated.push({ id: user.id, email: user.email });}
const remainingAdmins = await db.users.countActiveAdmins(); if (remainingAdmins === 0) { res.status(409).json({ error: "Cannot remove the last active admin" }); return;}
res.status(200).json(deactivationPayload(deactivated));}