feat(config): modulo Configuraciones admin + permisos por rol
- Tablas ConfiguracionSistema (7 configs) + RolConfiguracion (6 roles) - Endpoints: config/sistema GET/PATCH, config/roles GET/PATCH, config/usuarios GET/PATCH, config/reset-roles POST, config/acciones GET - modulosDeRol() async con fallback a MATRIZ estatica - auth/me devuelve acciones[] segun rol del usuario - saludMonday.estaDisponible() lee modo_local_forzado de DB (cache 30s) - Landing: vista Configuraciones con 4 tabs (Modo, Roles, Usuarios, Sistema) - Mi-dia: boton Descartar se deshabilita si !descartar_lead - 630 API tests + 24 landing tests + 20 mi-dia tests verdes Seed: npm run seed:config
This commit is contained in:
@@ -5,6 +5,7 @@ import { prisma } from './prisma.js'
|
||||
import { config } from '../config/index.js'
|
||||
import { modulosDeRol, type Modulo } from '../config/roles.js'
|
||||
import { AppError } from '../utils/errors.js'
|
||||
import * as configService from './config.service.js'
|
||||
|
||||
export interface UsuarioPublico {
|
||||
nombre: string
|
||||
@@ -14,6 +15,8 @@ export interface UsuarioPublico {
|
||||
mondayUserId: number | null
|
||||
// Módulos del ecosistema visibles para el rol (matriz de config/roles.ts)
|
||||
modulos: Modulo[]
|
||||
// Acciones granulares del rol (catálogo de config/acciones.ts)
|
||||
acciones: string[]
|
||||
}
|
||||
|
||||
export interface LoginResult {
|
||||
@@ -34,13 +37,23 @@ export function normalizarUsername(nombre: string): string {
|
||||
.replace(/\s+/g, ' ')
|
||||
}
|
||||
|
||||
export function aPublico(usuario: Usuario): UsuarioPublico {
|
||||
export async function aPublico(usuario: Usuario): Promise<UsuarioPublico> {
|
||||
let acciones: string[] = []
|
||||
try {
|
||||
const acc = await configService.obtenerAcciones(usuario.rol)
|
||||
acciones = Object.entries(acc)
|
||||
.filter(([, v]) => v)
|
||||
.map(([k]) => k)
|
||||
} catch {
|
||||
// Si falla la lectura de config, devuelve acciones vacías (no rompe)
|
||||
}
|
||||
return {
|
||||
nombre: usuario.nombre,
|
||||
rol: usuario.rol,
|
||||
asignacion: usuario.asignacion,
|
||||
mondayUserId: usuario.mondayUserId,
|
||||
modulos: modulosDeRol(usuario.rol),
|
||||
modulos: await modulosDeRol(usuario.rol),
|
||||
acciones,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +77,7 @@ export async function login(username: string, password: string): Promise<LoginRe
|
||||
config.auth.jwtSecret,
|
||||
{ expiresIn: config.auth.jwtExpiresIn } as jwt.SignOptions,
|
||||
)
|
||||
return { token, usuario: aPublico(usuario) }
|
||||
return { token, usuario: await aPublico(usuario) }
|
||||
}
|
||||
|
||||
/** Payload del JWT emitido por login() */
|
||||
|
||||
Reference in New Issue
Block a user