feat: vínculo con usuario Monday en landing + alta prellenada desde leads
API: - GET /api/monday/usuarios: usuarios activos no-guest del workspace - PATCH /api/usuarios/me/monday: vincula/desvincula el mondayUserId del usuario autenticado (valida contra el workspace) - GET /api/leads/buscar?q=: búsqueda de leads por nombre/teléfono/email (sin acentos, orden updatedAt desc, límite 15) - aPublico/me ahora incluyen mondayUserId Landing (/): - Nueva sección 'Configuración de cuenta': login inline, selector del usuario de Monday, guardar/desvincular, cerrar sesión Alta de clientes (/client): - Búsqueda de leads de Monday con debounce en la pantalla de entrada; al elegir uno prellena nombre/email/celular y guarda leadMondayId - El picker (borradores + alta nueva + búsqueda de lead) es ahora siempre la pantalla de entrada Tests: api 294, landing 8, alta-clientes 96 — todos verdes
This commit is contained in:
44
api-gateway/src/controllers/usuarios.controller.ts
Normal file
44
api-gateway/src/controllers/usuarios.controller.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { Request, Response } from 'express'
|
||||
import { z } from 'zod'
|
||||
import { mondayService } from '../services/monday.service.js'
|
||||
import { prisma } from '../services/prisma.js'
|
||||
import { aPublico } from '../services/auth.service.js'
|
||||
import { BadRequestError } from '../utils/errors.js'
|
||||
|
||||
/**
|
||||
* Vínculo usuario del ecosistema ↔ usuario de Monday (people). Es el mapeo
|
||||
* que alimenta round-robin, mis-leads, actividades y alertas; el usuario lo
|
||||
* elige él mismo desde la landing (Configuración de cuenta).
|
||||
*/
|
||||
|
||||
/** GET /api/monday/usuarios (Bearer) → usuarios activos del workspace */
|
||||
export async function listarUsuariosMondayEndpoint(_req: Request, res: Response): Promise<void> {
|
||||
const usuarios = await mondayService.getUsuariosWorkspace()
|
||||
res.json(usuarios.map((u) => ({ id: u.id, nombre: u.nombre, email: u.email })))
|
||||
}
|
||||
|
||||
const vinculoMondaySchema = z.object({
|
||||
mondayUserId: z.number().int().positive().nullable(),
|
||||
})
|
||||
|
||||
/**
|
||||
* PATCH /api/usuarios/me/monday (Bearer) { mondayUserId: number | null }
|
||||
* null desvincula. Un id que no existe en el workspace → 400.
|
||||
*/
|
||||
export async function actualizarVinculoMondayEndpoint(req: Request, res: Response): Promise<void> {
|
||||
if (!req.usuarioToken) throw new BadRequestError('Falta el token verificado')
|
||||
const { mondayUserId } = vinculoMondaySchema.parse(req.body)
|
||||
|
||||
if (mondayUserId !== null) {
|
||||
const usuarios = await mondayService.getUsuariosWorkspace()
|
||||
if (!usuarios.some((u) => u.id === mondayUserId)) {
|
||||
throw new BadRequestError(`El usuario de Monday ${mondayUserId} no existe en el workspace`)
|
||||
}
|
||||
}
|
||||
|
||||
const usuario = await prisma.usuario.update({
|
||||
where: { id: req.usuarioToken.sub },
|
||||
data: { mondayUserId },
|
||||
})
|
||||
res.json(aPublico(usuario))
|
||||
}
|
||||
Reference in New Issue
Block a user