Initial commit - Horux Despachos NL
This commit is contained in:
86
apps/api/src/controllers/admin-addons.controller.ts
Normal file
86
apps/api/src/controllers/admin-addons.controller.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
import { z } from 'zod';
|
||||
import { prisma } from '../config/database.js';
|
||||
import { isPlatformStaff } from '../utils/platform-admin.js';
|
||||
import { AppError } from '../middlewares/error.middleware.js';
|
||||
import { auditFromReq } from '../utils/audit.js';
|
||||
|
||||
async function requireStaff(req: Request) {
|
||||
if (!req.user?.userId) throw new AppError(401, 'No autenticado');
|
||||
const isStaff = await isPlatformStaff(req.user.userId);
|
||||
if (!isStaff) throw new AppError(403, 'Acceso restringido a staff de plataforma');
|
||||
}
|
||||
|
||||
const updateSchema = z.object({
|
||||
nombre: z.string().min(1).max(200).optional(),
|
||||
precio: z.number().nonnegative().optional(),
|
||||
active: z.boolean().optional(),
|
||||
});
|
||||
|
||||
/** Lista todo el catálogo de add-ons (incluye inactivos). */
|
||||
export async function listCatalogo(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
await requireStaff(req);
|
||||
const items = await prisma.planAddonCatalogo.findMany({
|
||||
orderBy: { codename: 'asc' },
|
||||
include: {
|
||||
_count: { select: { subscriptionAddons: { where: { status: { in: ['authorized', 'pending'] } } } } },
|
||||
},
|
||||
});
|
||||
return res.json({
|
||||
data: items.map(i => ({
|
||||
id: i.id,
|
||||
codename: i.codename,
|
||||
nombre: i.nombre,
|
||||
verticalProfile: i.verticalProfile,
|
||||
precio: Number(i.precio),
|
||||
frecuencia: i.frecuencia,
|
||||
active: i.active,
|
||||
delta: i.delta,
|
||||
createdAt: i.createdAt.toISOString(),
|
||||
suscripcionesActivas: i._count.subscriptionAddons,
|
||||
})),
|
||||
});
|
||||
} catch (err) { return next(err); }
|
||||
}
|
||||
|
||||
export async function updateCatalogoItem(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
await requireStaff(req);
|
||||
const id = String(req.params.id);
|
||||
const data = updateSchema.parse(req.body);
|
||||
const before = await prisma.planAddonCatalogo.findUnique({ where: { id } });
|
||||
if (!before) throw new AppError(404, 'Add-on no encontrado');
|
||||
|
||||
const updated = await prisma.planAddonCatalogo.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...(data.nombre !== undefined ? { nombre: data.nombre } : {}),
|
||||
...(data.precio !== undefined ? { precio: data.precio } : {}),
|
||||
...(data.active !== undefined ? { active: data.active } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
auditFromReq(req, 'addon.catalogo_updated', {
|
||||
entityType: 'PlanAddonCatalogo',
|
||||
entityId: id,
|
||||
metadata: {
|
||||
codename: before.codename,
|
||||
before: { nombre: before.nombre, precio: Number(before.precio), active: before.active },
|
||||
after: { nombre: updated.nombre, precio: Number(updated.precio), active: updated.active },
|
||||
},
|
||||
});
|
||||
|
||||
return res.json({
|
||||
id: updated.id,
|
||||
codename: updated.codename,
|
||||
nombre: updated.nombre,
|
||||
precio: Number(updated.precio),
|
||||
frecuencia: updated.frecuencia,
|
||||
active: updated.active,
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err instanceof z.ZodError) return next(new AppError(400, err.errors[0].message));
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user