Files
sar/libs/shared/api-interface/src/lib/equipe.contract.ts
julian 9b855f63b2 feat(api,web): regras de desconto por pauta e cards de supervisor na equipe
Regras de Desconto (Politicas Comerciais):
- Nova dimensao de escopo por pauta de precos: cria 1 regra por pauta
  selecionada (idPautas[]), aplicada a todos os produtos da pauta.
- Coluna id_pauta em sar.regras_desconto (migration idempotente + schema
  canonico); motor de alcada (orders) casa regra<->pedido por idPauta.
- Remove a aba/endpoints "Desconto por Representante" (gestao de
  alcada_desconto); o teto por rep continua no motor (default 5%) e no
  carrinho (/politicas/alcada), agora liberado via Regra de Desconto.

Aba Equipe do gerente:
- GET /equipe/supervisores: cards de disputa por supervisor (faturamento,
  meta, positivacao, variacao mensal, reps ativos).
- SupervisorDetalheModal: detalhe do time (ranking + positivacao) reusando
  /dashboard/supervisor escopado por codSupervisor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:12:00 +00:00

46 lines
1.6 KiB
TypeScript

import { z } from 'zod';
export const RepStatsSchema = z.object({
codVendedor: z.number().int(),
nomeVendedor: z.string().nullable(),
pedidosMes: z.number().int(),
faturamentoMes: z.number(),
ticketMedio: z.number(),
pctMeta: z.number(),
});
export type RepStats = z.infer<typeof RepStatsSchema>;
export const EquipeResponseSchema = z.object({
reps: z.array(RepStatsSchema),
totalReps: z.number().int(),
syncedAt: z.iso.datetime(),
});
export type EquipeResponse = z.infer<typeof EquipeResponseSchema>;
// Card de disputa/análise por supervisor na aba Equipe (visão gerente/admin).
// Time = reps cujo cod_supervisor aponta para este supervisor + o próprio
// supervisor (mesma semântica de getTeamCodes). Métricas agregadas do time no mês.
export const SupervisorCardSchema = z.object({
codSupervisor: z.number().int(),
nomeSupervisor: z.string().nullable(),
faturamentoMes: z.number(),
faturamentoMesAnterior: z.number(),
variacaoPct: z.number().nullable(), // null quando não há base no mês anterior
pedidosMes: z.number().int(),
ticketMedio: z.number(),
metaTotal: z.number(),
pctMeta: z.number(),
totalClientes: z.number().int(),
clientesPositivados: z.number().int(),
pctPositivacao: z.number(),
repsTotal: z.number().int(),
repsAtivos: z.number().int(), // reps do time que faturaram no mês
});
export type SupervisorCard = z.infer<typeof SupervisorCardSchema>;
export const SupervisoresResponseSchema = z.object({
supervisores: z.array(SupervisorCardSchema),
syncedAt: z.iso.datetime(),
});
export type SupervisoresResponse = z.infer<typeof SupervisoresResponseSchema>;