Pular para o conteúdo principal

Produtos — arquitetura, API e análise técnica

Análise estática do pepper-front e pepper-api em 08/10/2026, complementada pela renderização local dos componentes com dados fictícios. Os caminhos abaixo são relativos às raízes desses repositórios. Esta revisão documenta o comportamento encontrado; não altera código da aplicação nem comprova integrações em produção.

Entidades e responsabilidades​

EntidadeCampos / comportamento relevante
Productbusiness referencia ProfileBusiness, não Business. Nome, tipo, unidade, preço, quantidade padrão, links, imagem, endereços digitais e publicFlag.
AffiliationProduto, empresa proprietária, CPF/CNPJ do parceiro, comissão, status, limite, link e anexos. Índice único produto + documento.
LoteProduto, empresa, quantidade máxima e intervalo de datas.
FairProductAssociação área + produto, status, mistura de fornecedores e modelo de avaliação.
OrderProductProduto do pedido, valor, quantidade, desconto e referências complementares.
ProductAcquisitionÁrea, produto, usuário, lote opcional, posição, status e prazo da reserva.

Fornecedor (Product.provider) é texto. A propriedade é dada por Product.business. Afiliação não duplica nem transfere o produto.

Frontend: telas e serviços​

FluxoEvidência no pepper-front
Rotas all/new/edit/view e resoluçãosrc/app/product/product-routing.module.ts e módulos de cada página.
Catálogo, busca e contagenssrc/app/product/product.page.ts, product.page.html, product.service.ts.
Cartões próprios/afiliadossrc/app/product/product-shared/product-item/.
Cadastro e etapassrc/app/product/new/, product-local.ts; etapas locais via src/utils/Local/Local.ts.
Edição, upload, erros e endereçossrc/app/product/edit/; src/utils/Swipper.ts seleciona controles alterados.
Detalhes, clonagem, exclusão e abassrc/app/product/view/view.page.ts, view.service.ts.
Afiliaçãosrc/app/affiliation/affiliation.service.ts e product/view/affiliation-modal/.
Lotesproduct/view/lote-modal/.
Associação às áreassrc/app/fair/view/fair-products-modal/ e página de gerenciamento da área.
Marketplace, carrinho e checkoutsrc/app/public/view-public/, incluindo marketplace-cart.service.ts e checkout/.

A edição normaliza o objeto indexado de endereços digitais gerado pelo mecanismo de controles alterados para uma lista antes de enviar à API. O upload é um fluxo separado da atualização do documento.

Todas as rotas abaixo usam o prefixo /api/v1. As consultas retornam o envelope data e, quando paginadas, metadata.

Método e rotaUso / proteção observada
POST /productCadastro, validação, token e permissão product.write.
GET /product?business=…&pagination=…Próprios + afiliados; sem auth.checkToken nessa rota. Sem empresa válida devolve lista vazia.
GET /product/:productIdFicha; token e product.read.
PUT /product/:productIdAtualização; validação, token e product.write. business é obrigatório no corpo.
DELETE /product/:productIdExclusão; token e product.delete.
POST /product/:productId/cloneCópia; token e productClone.write. Ignora nome enviado e usa “Cópia de…”.
GET /product/:productId/videosVídeos a partir de endereços YouTube; sem auth.checkToken nessa rota.
GET /public/business/:businessId/productsCatálogo público, exige publicFlag = true; inclui afiliações elegíveis.
GET /order/by-product/:productId?business=…Pedidos relacionados, filtrados por empresa e sem soft delete.

Evidências: src/domains/Product/{routes,controller,validations,product.model,policies,permission}.js, src/domains/Public/routes.js e src/domains/Order/controller.js#getByProduct.

O backend exige empresa, nome, tipo e unidade no cadastro. Preço e quantidade não têm restrições positivas equivalentes a uma validação de negócio completa. Publicação começa falsa no modelo. Na edição, URL/descrição têm permissões para vazio/null que não são uniformes com os demais campos.

API de parcerias, lotes e áreas​

RecursoRotas
AfiliaçãoPOST/GET /affiliation, GET/PUT/DELETE /affiliation/:affiliationId. Token e permissões de afiliação.
LotePOST/GET /lote, PUT/DELETE /lote/:loteId. Token e permissões baseadas em Produtos.
AssociaçãoGET/POST /fair/:fairId/products, PUT /fair/:fairId/products/bulk, PUT/DELETE /fair/:fairId/products/:fairProductId.
DisponibilidadeGET /public/fair/:fairId/product/:productId/acquisition/availability.
Entrar na filaPOST /public/fair/:fairId/product/:productId/acquisition/queue.
Consultar/sair da filaGET/DELETE /public/fair/:fairId/product/:productId/acquisition/queue/:queueId.
Confirmar aquisiçãoPOST /public/fair/:fairId/product/:productId/acquisition/confirm, corpo com queueId.

Na fila, as operações do usuário exigem token; a disponibilidade é pública. FairProduct.bulkSet remove associações fora da seleção enviada e faz upsert das selecionadas. Uma seleção parcial, portanto, pode retirar itens existentes da área.

Evidências: src/domains/Affiliation/, src/domains/Lote/, src/domains/Fair/{routes,fairProduct.controller}.js, src/domains/ProductAcquisition/ e src/domains/Public/routes.js.

Descoberta de produtos afiliados​

Product.controller#get/getPublic resolve ProfileBusiness → Business, lê CPF/CNPJ, normaliza para dígitos e procura afiliações com status accepted ou progress. A consulta reúne IDs próprios e afiliados. O retorno inclui viaAffiliation, isOwnProduct, proprietário e afiliação correspondente; a listagem administrativa também informa contagem de afiliações ativas.

O catálogo público exige publicFlag inclusive para os itens afiliados. A consulta administrativa de produtos, sem token na rota, não filtra por esse campo. A indicação Privado descreve a publicação no marketplace, não uma garantia de confidencialidade do endpoint administrativo.

Disponibilidade e reserva​

A resolução de limite prioriza lote vigente com quantidade positiva e, na ausência dele, uma afiliação ativa com maxSales positivo. O saldo subtrai registros holding/confirmed por área e produto. A reserva expira em dez minutos e depende do scheduler para liberar/promover a fila.

Há diferenças entre a seleção de lotes do controlador, da listagem pública e do scheduler: nem todos os caminhos ordenam igualmente os lotes. A confirmação atualiza a aquisição, sem chamada de cobrança ou criação de pedido nesse método.

Permissões: limites da análise​

As rotas de mutação usam BasePermission. As policies de Produto e Afiliação resolvem a empresa por productId/affiliationId para operações por ID. Quando esses IDs não existem no recurso, alguns callbacks retornam permissão positiva sem resolver a empresa enviada no corpo/query.

Lotes reutilizam a policy de Produto, mas as rotas por ID usam loteId. Isso exige revisão da resolução do proprietário do lote. Há também callbacks permissivos para perfis de fornecedor/cliente no recurso Produto, enquanto clonagem e afiliação têm regras distintas.

Esses achados são pontos de revisão de escopo; a autorização final depende também do middleware e das permissões do perfil. Não foram feitos testes de exploração ou acessos a dados reais.

Achados e prioridades​

Prioridade propostaAchado verificávelConsequência / ajuste recomendado
AltaGET /product e vídeos sem autenticação explícita na rota; consulta administrativa inclui privados.Rever exposição, campos retornados e intenção de acesso público.
AltaOwnership das policies depende dos IDs presentes; criação/listagem e lotes exigem revisão de escopo.Validar empresa pelo recurso efetivo, corpo e query; cobrir cenários entre empresas.
AltaExclusão chama findByIdAndDelete antes de procurar pedidos; não limpa dependências.Verificar referências antes de remover, tratar produto inexistente e definir política de retenção/cascata. As rotas estão envolvidas pelo middleware global de transação (src/routes.js e src/middlewares/transactions.js), que prevê abortar em caso de erro; o rollback não foi exercitado nesta revisão.
AltaCheckoutPage.finish somente altera estado local, sem API.Integrar pedido, validação de preços, pagamentos e liberação antes de operar cobrança pública.
AltaLimites usam afiliação por produto, sem parceiro; saldo por área/produto, sem lote.Definir escopo de capacidade e consistência entre consumo e venda.
AltaFila usa contagens e posição calculadas em operações separadas.Validar concorrência, idempotência, ocupação e promoção com testes de integração. Não há prova de exclusividade atômica nesta revisão.
MédiaProductPage.getParams devolve query vazia; getItems substitui a lista.Manter empresa, avançar página e acumular resultados sem duplicar.
MédiaCadastro/edição usam regras divergentes para nulos, positivos e campos opcionais.Uniformizar normalização e validação do formulário/API.
MédiaClonagem ignora nome; modal não recebe configuração de inputs; copia publicação e timestamps.Corrigir contrato, escolher visibilidade inicial e regenerar metadados.
MédiaAbas mascaram erros como listas vazias; afiliações limitadas a 100 registros.Exibir erro/retry e paginar.
MédiaViewPage.formatDate converte data ISO para o fuso local; datas à meia-noite UTC podem aparecer no dia anterior.Normalizar apresentação de datas de calendário; conferir também o corte em UTC da vigência.
MédiaSeleção de lote no scheduler não segue necessariamente a mesma ordem das consultas.Centralizar resolução do limite e tratar múltiplos lotes.
MédiaEncerrar afiliação não remove associações existentes às áreas.Definir/revalidar elegibilidade por canal na operação.
BaixaQualquer status de pedido diferente de paid aparece como Pendente.Mapear estados financeiros completos na aba Vendas.
BaixaControllers de report/audit de Produtos retornam data: null.Não anunciar relatórios ou auditoria de produto concluídos; implementar ou retirar rotas vazias.

Os logs de descoberta de afiliações também incluem documentos empresariais e candidatos consultados em Product.controller#get. Rever necessidade e exposição desses logs na operação.

Validação e manutenção da documentação​

Os prints vêm de componentes e estilos reais, montados em workspace Angular temporário pelo scripts/capture-products.cjs do pepper-docs. Serviços locais fornecem fixtures e bloqueiam gravações; não há backend, provedor de pagamento ou dados reais nessa captura.

A compilação desse preview verifica que os componentes selecionados e seus templates podem ser renderizados no cenário documentado. O build/typecheck do pepper-docs valida a publicação estática e referências internas. Essas verificações não substituem testes de API, autorização, concorrência, armazenamento ou pagamentos.

Ao mudar o produto, atualize o guia operacional afetado, os prints, os achados desta análise e a data da revisão. O README do pepper-docs contém o comando para reproduzir as imagens.