Files
sar/libs/shared/api-interface/src/lib/product.contract.ts
julian 756e56d8d3 feat(api,web): catalogo na area do gerente com todas as pautas e precos
- Menu Catalogo no cockpit do gerente (rota /catalogo existente)
- /catalog/pautas: gestor recebe TODAS as pautas ativas com contagem de
  reps que usam cada uma (rep segue vendo so as suas cod_pauta1..6)
- Detalhe do produto: gestor ve o preco em todas as pautas (rep segue
  restrito as dele)
- Select de pauta mostra "N reps" quando disponivel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:40:34 +00:00

88 lines
3.5 KiB
TypeScript

import { z } from 'zod';
// Contratos canônicos de C4 — Catálogo de Produtos.
// Consumidos pela API (output tipado) e pela Web (TanStack Query + parse).
// ADR 0006 revogado: produto lido diretamente de vw_produtos (ERP), sem sync.
// ─── Produto Summary (lista) ──────────────────────────────────────────────────
export const ProdutoSummarySchema = z.object({
idErp: z.number().int(),
codigo: z.string(),
descricao: z.string(),
unidade: z.string().nullable(),
vlPreco1: z.string(), // preço base (vw_produtos) ou preço da pauta selecionada
codGrupo: z.number().int().nullable(),
grupo: z.string().nullable(),
codSubgrupo: z.number().int().nullable(),
subgrupo: z.string().nullable(),
marca: z.string().nullable(),
ativo: z.number().int(),
qtdEstoque: z.string().nullable(),
listaParauta: z.number().int().nullable(),
loteMulVenda: z.number().int().nullable(),
});
export const PautaSchema = z.object({
idPauta: z.number().int(),
codigo: z.number().int(),
descricao: z.string(),
// Presente só para gestor: quantos representantes usam esta pauta
qtdReps: z.number().int().optional(),
});
export type Pauta = z.infer<typeof PautaSchema>;
// ─── Forma de Pagamento (vw_formas_pagamento) ─────────────────────────────────
export const FormaPagamentoSchema = z.object({
codigo: z.number().int(),
descricao: z.string(),
numParcelas: z.number().int().nullable(),
txAcrescimo: z.string(),
});
export type FormaPagamento = z.infer<typeof FormaPagamentoSchema>;
export type ProdutoSummary = z.infer<typeof ProdutoSummarySchema>;
// ─── Produto Detail ───────────────────────────────────────────────────────────
export const PautaPrecoSchema = z.object({
idPauta: z.number().int(),
codigo: z.number().int(),
descricao: z.string(),
preco: z.string(),
});
export type PautaPreco = z.infer<typeof PautaPrecoSchema>;
export const ProdutoDetailSchema = ProdutoSummarySchema.extend({
referencia: z.string().nullable(),
descricaoDetalhada: z.string().nullable(),
vlPreco2: z.string().nullable(),
vlPreco3: z.string().nullable(),
aliqIpi: z.string().nullable(),
pesoLiquido: z.string().nullable(),
qtdVolume: z.string().nullable(),
precoComIpi: z.string().nullable(),
precoPromocional: z.string().nullable(),
pautaPrecos: z.array(PautaPrecoSchema),
});
export type ProdutoDetail = z.infer<typeof ProdutoDetailSchema>;
// ─── List query + response ────────────────────────────────────────────────────
export const ProdutoListQuerySchema = z.object({
q: z.string().optional(),
codGrupo: z.coerce.number().int().optional(),
idPauta: z.coerce.number().int().optional(),
page: z.coerce.number().int().positive().default(1),
limit: z.coerce.number().int().min(1).max(200).default(50),
});
export type ProdutoListQuery = z.infer<typeof ProdutoListQuerySchema>;
export const ProdutoListResponseSchema = z.object({
data: z.array(ProdutoSummarySchema),
total: z.number().int().nonnegative(),
page: z.number().int().positive(),
limit: z.number().int().positive(),
});
export type ProdutoListResponse = z.infer<typeof ProdutoListResponseSchema>;