feat(notificaciones): configuración de notificaciones por rol

- Nueva tabla tenant notification_role_preferences para guardar (email_type, role, enabled).
- Migración 051 aplicada a todos los tenants.
- Backend expone endpoint /notificaciones con matriz de preferencias por rol.
- Filtrado por rol en documento_subido, weekly_update, subscription_expiring,
  alertas_nuevas y recordatorio_proximo.
- Frontend rediseñado como tabla notificación × rol con toggles inmediatos.
This commit is contained in:
Horux Dev
2026-06-17 00:04:37 +00:00
parent 8a1fbceb38
commit b217342a96
8 changed files with 380 additions and 192 deletions

View File

@@ -3,29 +3,42 @@ import { z } from 'zod';
import { AppError } from '../middlewares/error.middleware.js';
import {
EMAIL_TYPES,
getEmailPreferencesPorContribuyente,
setContribuyenteEmailPreferences,
NOTIFICATION_ROLES,
getRoleEmailPreferences,
setRoleEmailPreference,
type EmailType,
type NotificationRole,
} from '../services/notification-preferences.service.js';
export async function listPreferences(req: Request, res: Response, next: NextFunction) {
try {
const data = await getEmailPreferencesPorContribuyente(req.tenantPool!);
res.json({ emailTypes: EMAIL_TYPES, data });
const preferences = await getRoleEmailPreferences(req.tenantPool!);
res.json({
emailTypes: EMAIL_TYPES,
roles: NOTIFICATION_ROLES,
preferences,
});
} catch (error) {
next(error);
}
}
const updateSchema = z.object({
contribuyenteId: z.string().uuid(),
preferences: z.record(z.string(), z.boolean()),
emailType: z.enum([...EMAIL_TYPES] as [string, ...string[]]),
role: z.enum([...NOTIFICATION_ROLES] as [string, ...string[]]),
enabled: z.boolean(),
});
export async function updatePreferences(req: Request, res: Response, next: NextFunction) {
try {
const { contribuyenteId, preferences } = updateSchema.parse(req.body);
const updated = await setContribuyenteEmailPreferences(req.tenantPool!, contribuyenteId, preferences);
res.json({ contribuyenteId, preferences: updated });
const { emailType, role, enabled } = updateSchema.parse(req.body);
const preferences = await setRoleEmailPreference(
req.tenantPool!,
emailType as EmailType,
role as NotificationRole,
enabled,
);
res.json({ preferences });
} catch (error) {
if (error instanceof z.ZodError) return next(new AppError(400, error.errors[0].message));
next(error);