Arquivo analisado: python-api/app/api/routes.py
Tipo da mudança
- Nova funcionalidade: inclusão de um novo endpoint POST
/discounts/calculatepara cálculo de desconto. - Extensão da API: adição de serviço e schemas relacionados a descontos.
Evidências observadas
- No diff, foi adicionado o import de
DiscountServicee dos schemasDiscountRequesteDiscountResponse. - Instanciação de
discount_service = DiscountService()no escopo do router. - Novo endpoint FastAPI definido com decorator
@router.post("/discounts/calculate", response_model=DiscountResponse, tags=["discounts"]). - O endpoint recebe um payload do tipo
DiscountRequeste retornaDiscountResponse. - A lógica do endpoint chama
discount_service.calculate_final_pricecom os parâmetros do payload. - Tratamento de exceção para
ValueErrorque retorna HTTP 400 com a mensagem da exceção. - No contexto do repositório, o arquivo
routes.pyé responsável por definir endpoints e delegar lógica para serviços. - Não há evidência no diff ou no contexto sobre a implementação interna de
DiscountServiceou validação dos schemas, mas pelo padrão do projeto, espera-se que estejam emapp/services/discount_service.pyeapp/schemas.py. - O endpoint segue o padrão de tratamento de erros e resposta já utilizado em outros endpoints.
Impacto provável
- Introdução de um novo recurso para cálculo de descontos, que pode ser consumido por clientes da API.
- Possível impacto na camada de serviços, dependendo da implementação de
DiscountService.calculate_final_price. - Nenhuma alteração nos endpoints existentes, portanto impacto isolado.
- A API agora expõe um novo grupo de rotas com tag
"discounts", o que pode afetar documentação e clientes que consomem a API. - Possível aumento na superfície de ataque ou falhas se o serviço de desconto não tratar corretamente entradas inválidas.
Riscos identificados
- Validação insuficiente do payload: não há validação explícita no endpoint além do Pydantic via
DiscountRequest. Se o schema não validar corretamente, pode haver erros ou comportamentos inesperados. - Tratamento de exceções limitado: apenas
ValueErroré capturado. Outros erros (ex: erros internos, falhas inesperadas) não são tratados e podem resultar em 500. - Dependência do serviço de desconto: se
DiscountServicenão estiver bem testado ou tiver bugs, o endpoint pode retornar valores incorretos. - Possível falta de testes: não há evidência de testes para este novo endpoint no contexto atual.
- Segurança e autorização: não há controle de acesso ou autenticação visível; se o desconto for sensível, pode ser um risco.
- Consistência do contrato: se
DiscountResponseouDiscountRequestmudarem, pode quebrar clientes.
Cenários de testes manuais
- Cálculo básico de desconto válido
- Enviar payload combase_price,discount_percentage,coupon_code(opcional),is_vip(booleano).
- Verificar se ofinal_priceretornado está correto conforme regras de negócio (se conhecidas). - Payload com valores limite
-base_pricezero ou negativo (se permitido).
-discount_percentagezero, 100, ou valores inválidos (ex: >100, negativos).
-coupon_codeinválido ou vazio.
-is_vipverdadeiro e falso. - Payload inválido
- Campos faltando.
- Tipos errados (ex: string embase_price).
- Verificar se retorna HTTP 422 (validação Pydantic). - Erro de negócio
- ForçarDiscountServicea lançarValueError(ex: desconto maior que preço).
- Verificar se retorna HTTP 400 com mensagem adequada. - Testar ausência de campos opcionais
- Enviar payload semcoupon_codee verificar comportamento. - Testar comportamento com valores extremos
- Preço muito alto.
- Desconto muito alto. - Testar resposta do endpoint
- Verificar se o JSON retornado corresponde ao schemaDiscountResponse. - Testar documentação
- Verificar se o endpoint aparece corretamente em/docscom os schemas.
Sugestões de testes unitários
- Testar
calculate_discountisoladamente, mockandodiscount_service.calculate_final_pricepara: - Retornar valor esperado e verificar resposta correta.
- Lançar
ValueErrore verificar se HTTPException 400 é levantada com mensagem correta. - Testar validação do schema
DiscountRequestpara garantir que campos obrigatórios e tipos são validados. - Testar
DiscountService.calculate_final_price(fora do escopo do diff, mas essencial) para: - Casos normais de cálculo.
- Casos de erro que geram
ValueError. - Testar que o endpoint rejeita payloads inválidos (ex: tipos errados, campos faltando) com erro 422.
Sugestões de testes de integração
- Testar fluxo completo do endpoint
/discounts/calculatecom payloads válidos e inválidos, verificando status HTTP e conteúdo da resposta. - Testar integração com
DiscountServicereal para validar cálculo correto. - Testar comportamento em caso de exceções não previstas (ex: simular erro interno no serviço).
- Testar documentação Swagger gerada para o endpoint.
- Testar concorrência mínima para garantir que múltiplas chamadas simultâneas não causam problemas (se aplicável).
Sugestões de testes de carga ou desempenho
- Não há evidência no diff ou contexto que justifique testes de carga específicos para este endpoint.
- Caso o serviço de desconto envolva chamadas externas ou cálculos pesados, considerar testes de carga futuros.
Pontos que precisam de esclarecimento
- Regras de negócio do cálculo de desconto: quais são as regras exatas para cálculo? Como
coupon_codeeis_vipinfluenciam o resultado? - Validação dos campos do payload: quais valores são válidos para
base_price,discount_percentage? Há limites ou formatos específicos paracoupon_code? - Comportamento esperado para erros: além de
ValueError, que outros erros podem ocorrer? Como devem ser tratados? - Segurança e autorização: o endpoint deve ser público? Há necessidade de autenticação ou autorização para uso?
- Cobertura de testes existente: há testes automatizados para
DiscountServicee para este endpoint? Se não, é recomendável criar. - Persistência ou registro: o cálculo de desconto gera algum registro ou log? Isso pode impactar testes e riscos.
- Dependências externas: o serviço de desconto depende de APIs externas ou recursos que podem falhar?
Resumo: A mudança adiciona um novo endpoint para cálculo de desconto, integrando um novo serviço e schemas. O impacto é isolado, mas requer atenção à validação, tratamento de erros e testes específicos para garantir que o cálculo e a API funcionem corretamente. Riscos reais incluem falhas no serviço de desconto e tratamento insuficiente de erros. Recomenda-se testes manuais focados em entradas válidas e inválidas, além de testes unitários e de integração para o endpoint e serviço. Pontos de negócio e segurança precisam ser esclarecidos para garantir cobertura adequada.
Arquivo analisado: python-api/app/schemas.py
Tipo da mudança
- Adição de novos schemas Pydantic para requisição e resposta relacionados a desconto (DiscountRequest e DiscountResponse).
Evidências observadas
- O diff mostra a inclusão de duas novas classes no arquivo
python-api/app/schemas.py: DiscountRequestcom os campos:base_price: floatobrigatório, com validaçãoge=0(maior ou igual a zero).discount_percentage: floatopcional, default 0.0, com validaçãoge=0ele=100.coupon_code: str | Noneopcional, default None.is_vip: boolopcional, default False.
DiscountResponsecom o campo:final_price: floatobrigatório.
- O arquivo
schemas.pyé o local central de definição dos modelos Pydantic usados para validação e serialização dos dados de entrada e saída da API. - No contexto do repositório, há um serviço chamado
DiscountServiceimportado empython-api/app/api/routes.py(não mostrado no diff, mas presente no contexto), sugerindo que esses schemas provavelmente serão usados para endpoints relacionados a cálculo de desconto. - Não há alterações em rotas ou serviços diretamente no diff, apenas a definição dos modelos.
- O uso de validações Pydantic (
Field(..., ge=0),Field(0.0, ge=0, le=100)) indica preocupação com a integridade dos dados recebidos.
Impacto provável
- Introdução de um novo contrato de API para operações relacionadas a descontos, provavelmente para um endpoint que recebe um preço base, percentual de desconto, código de cupom e status VIP, e retorna o preço final após aplicação do desconto.
- A validação embutida nos campos do
DiscountRequestgarante que valores inválidos (ex: preço negativo, percentual fora do intervalo 0-100) sejam rejeitados já na camada de entrada. - Como são apenas definições de schemas, o impacto direto no comportamento da API depende da implementação dos endpoints e serviços que consumirão esses modelos.
- Caso os novos schemas sejam usados em endpoints públicos, clientes da API precisarão adaptar-se para enviar e receber os novos formatos.
Riscos identificados
- Ausência de validação explícita para o campo
coupon_code: não há restrição de formato, tamanho ou validade, o que pode permitir dados inválidos ou malformados. - Possível falta de testes para esses novos modelos: não há evidência no contexto de testes existentes que cubram esses schemas.
- Se os serviços ou endpoints que usam esses schemas não implementarem corretamente a lógica de desconto, pode haver inconsistência entre o valor enviado e o valor final retornado.
- Se o campo
discount_percentagefor omitido, o default é 0.0, o que pode ser esperado, mas deve ser confirmado se isso está alinhado com a regra de negócio. - Não há validação para garantir que
final_priceemDiscountResponseseja coerente com os dados de entrada (ex: não negativo, menor ou igual aobase_price). - Se o campo
is_vipfor usado para aplicar descontos adicionais, a ausência de lógica visível pode levar a dúvidas sobre seu uso correto.
Cenários de testes manuais
-
Validação de entrada:
- Enviar requisição combase_pricenegativo → deve ser rejeitada com erro de validação.
- Enviardiscount_percentagemenor que 0 ou maior que 100 → rejeição por validação.
- Enviarcoupon_codecom valores variados (string vazia, caracteres especiais, muito longo) para verificar aceitação.
- Enviaris_vipcomotrueefalsepara verificar aceitação. -
Fluxo funcional (assumindo endpoint implementado):
- Enviar requisição combase_pricepositivo ediscount_percentageválido, sem cupom eis_vipfalso → verificar sefinal_priceé calculado corretamente.
- Enviar com cupom válido (se houver regra) e verificar desconto aplicado.
- Enviar comis_vipverdadeiro e verificar se desconto adicional é aplicado.
- Enviar comdiscount_percentagezero e verificar sefinal_priceé igual abase_price. -
Testar comportamento com campos opcionais omitidos:
- Omitirdiscount_percentageecoupon_codee verificar comportamento padrão. -
Testar limites:
-discount_percentageexatamente 0 e 100.
-base_pricezero.
Sugestões de testes unitários
- Testar validação do modelo
DiscountRequest: - Criar instância com valores válidos e verificar sucesso.
- Tentar criar com
base_pricenegativo e esperar erro de validação. - Tentar criar com
discount_percentagefora do intervalo e esperar erro. - Testar aceitação de
coupon_codecomoNonee string válida. -
Testar aceitação de
is_vipcomoTrueeFalse. -
Testar serialização e desserialização dos modelos.
-
Se existir lógica associada ao cálculo do desconto (provavelmente no
DiscountService), criar testes unitários para: - Calcular preço final com diferentes combinações de
discount_percentage,coupon_codeeis_vip. - Garantir que o preço final nunca seja negativo.
- Validar comportamento com cupom inválido ou ausente.
Sugestões de testes de integração
- Testar o endpoint que utiliza
DiscountRequesteDiscountResponse(se já implementado): - Enviar requisições válidas e verificar resposta correta.
- Enviar requisições inválidas e verificar erros de validação HTTP 422.
- Testar integração com o serviço de desconto para garantir cálculo correto do preço final.
-
Testar comportamento com diferentes combinações de campos (cupom, VIP, percentual).
-
Testar integração com outras partes da API que possam consumir ou produzir esses modelos.
Sugestões de testes de carga ou desempenho
- Não aplicável, pois a mudança é apenas na definição de schemas, sem alteração de lógica ou endpoints visíveis.
Pontos que precisam de esclarecimento
- Qual é a regra de negócio exata para o cálculo do
final_price? Comodiscount_percentage,coupon_codeeis_vipinteragem? - Existe validação ou restrição para o formato ou validade do
coupon_code? - O campo
discount_percentagepode ser omitido? O default 0.0 está correto para o negócio? - O campo
final_priceemDiscountResponsedeve ser validado para garantir coerência com os dados de entrada? - Os novos schemas já estão sendo usados em algum endpoint? Se sim, qual é o comportamento esperado?
- Há planos para adicionar validação customizada (ex: método
@validator) para regras mais complexas no modelo?
Resumo: A mudança adiciona dois novos modelos Pydantic para requisição e resposta de desconto, com validações básicas de campo. O impacto funcional depende da implementação dos serviços e endpoints que os utilizam. Riscos principais envolvem ausência de validações mais específicas e falta de testes para esses novos modelos. Recomenda-se testes focados em validação de dados, integração com serviços de desconto e verificação do cálculo do preço final.
Arquivo analisado: python-api/app/services/discount_service.py
Tipo da mudança
- Nova funcionalidade: Inclusão de um novo serviço (
DiscountService) para cálculo de descontos no e-commerce, com regras específicas para descontos percentuais, clientes VIP, cupons e descontos progressivos por quantidade.
Evidências observadas
- O arquivo
discount_service.pyfoi criado do zero, contendo a classeDiscountServicecom dois métodos principais: calculate_final_price: calcula o preço final aplicando descontos percentuais limitados a 70%, desconto adicional para clientes VIP (5% sobre o valor já descontado), descontos fixos por cupons (QUERO10eQUERO20), e garante que o preço final não seja negativo.apply_bulk_discount: aplica desconto progressivo baseado na quantidade de itens (5% para 5+, 10% para 10+, 15% para 20+ itens).- O docstring do método
calculate_final_priceexplicita as regras de negócio implementadas. - O contexto do repositório mostra que o serviço foi importado em
python-api/app/api/routes.py(linhadiscount_service = DiscountService()), indicando que pode ser utilizado em rotas da API. - Não há evidência de testes unitários ou de integração específicos para este serviço no repositório atual, nem menção direta a ele nos arquivos de teste listados.
- O uso de tipos
floatpara preços e descontos pode implicar em pequenas imprecisões numéricas, apesar do arredondamento final para 2 casas decimais.
Impacto provável
- Introdução de um novo componente para cálculo de descontos que pode afetar:
- Cálculo do preço final de produtos ou pedidos no e-commerce.
- Aplicação de regras de desconto específicas para clientes VIP e cupons promocionais.
- Descontos progressivos baseados na quantidade de itens comprados.
- Possível impacto em fluxos de compra, checkout e precificação, caso o serviço seja integrado a esses processos.
- Como o serviço é novo, pode ser que ainda não esteja amplamente utilizado, mas sua incorporação pode alterar o comportamento de cálculo de preços se substituir ou complementar lógica existente.
Riscos identificados
- Validação insuficiente de entradas:
base_pricenegativo gera exceção, masdiscount_percentagenegativo é simplesmente ajustado para zero, o que pode mascarar erros de entrada.coupon_codeaceita qualquer string, mas só reconhece dois valores específicos; cupons inválidos são ignorados silenciosamente.- Ordem de aplicação dos descontos:
- O desconto percentual é aplicado primeiro, depois o desconto VIP (5% sobre o valor já descontado), e por fim o desconto fixo do cupom.
- Essa ordem pode não estar clara para o negócio e pode gerar dúvidas ou inconsistências se não estiver documentada ou validada.
- Uso de
floatpara valores monetários: - Pode causar problemas de precisão em cálculos financeiros, apesar do arredondamento final.
- Limite de desconto percentual fixo em 70%:
- Pode não contemplar futuras promoções ou regras especiais.
- Desconto do cupom
QUERO20depende do preço base, não do preço já descontado: - Pode gerar confusão se o preço base for alterado antes da aplicação do cupom.
- Método
apply_bulk_discountnão valida entradas: items_countetotal_valuenegativos ou zero não são tratados explicitamente.- Ausência de testes automatizados:
- Não há evidência de testes unitários ou de integração para este serviço, aumentando o risco de regressões ou erros não detectados.
- Possível falta de integração com o restante do sistema:
- O serviço foi criado, mas não há evidência clara de uso em endpoints ou fluxos de negócio existentes, o que pode indicar risco de inconsistência ou falta de cobertura.
Cenários de testes manuais
-
Cálculo básico de desconto percentual
- Entrada:base_price=200.0,discount_percentage=20.0, sem cupom, não VIP.
- Esperado: preço final = 200 - 20% = 160.00. -
Desconto percentual maior que 70%
- Entrada:base_price=100.0,discount_percentage=80.0.
- Esperado: desconto limitado a 70%, preço final = 30.00. -
Desconto percentual negativo
- Entrada:base_price=100.0,discount_percentage=-10.0.
- Esperado: desconto tratado como 0%, preço final = 100.00. -
Cliente VIP com desconto adicional
- Entrada:base_price=100.0,discount_percentage=10.0,is_vip=True.
- Cálculo: 100 - 10% = 90.0; VIP 5% sobre 90.0 = 85.5.
- Esperado: preço final = 85.50. -
Aplicação do cupom
QUERO10
- Entrada:base_price=50.0,discount_percentage=0,coupon_code="QUERO10".
- Esperado: preço final = 50 - 10 = 40.00. -
Aplicação do cupom
QUERO20com preço base abaixo de 100
- Entrada:base_price=90.0,discount_percentage=0,coupon_code="QUERO20".
- Esperado: cupom não aplicado, preço final = 90.00. -
Aplicação do cupom
QUERO20com preço base acima de 100
- Entrada:base_price=150.0,discount_percentage=0,coupon_code="QUERO20".
- Esperado: preço final = 150 - 20 = 130.00. -
Preço base negativo
- Entrada:base_price=-10.0.
- Esperado: exceçãoValueError. -
Preço final não pode ser negativo
- Entrada:base_price=10.0,discount_percentage=70.0,coupon_code="QUERO10",is_vip=True.
- Cálculo: 10 - 7 = 3; VIP 5% sobre 3 = 2.85; cupom -10 = -7.15 → preço final ajustado para 0.00.
- Esperado: preço final = 0.00. -
Desconto progressivo por quantidade de itens
- Testar para 0, 4, 5, 9, 10, 19, 20 itens com valores variados.
- Verificar se o fator aplicado está correto (1.0, 0.95, 0.90, 0.85).
-
Valores negativos ou zero em
apply_bulk_discount- Entrada:
items_count=0etotal_value=100.0. - Esperado: sem desconto, preço final = 100.00.
- Entrada:
items_count=-5etotal_value=100.0. - Esperado: comportamento definido (atualmente aplica fator 1.0).
- Entrada:
Sugestões de testes unitários
calculate_final_price:- Testar limite superior do desconto percentual (70%).
- Testar desconto percentual negativo (deve ser tratado como 0).
- Testar aplicação correta do desconto VIP (5% sobre preço já descontado).
- Testar aplicação correta dos cupons
QUERO10eQUERO20com condições de preço base. - Testar que preço final nunca é negativo.
- Testar exceção para preço base negativo.
- Testar combinação de descontos (percentual + VIP + cupom).
- Testar comportamento com cupom inválido (deve ignorar).
apply_bulk_discount:- Testar faixas de quantidade (0, 4, 5, 9, 10, 19, 20).
- Testar valores negativos e zero para
items_countetotal_value. - Testar arredondamento correto para 2 casas decimais.
Sugestões de testes de integração
- Criar um endpoint de API (se ainda não existir) que utilize
DiscountServicepara calcular preço final e descontos progressivos, e testar fluxo completo via requisição HTTP. - Testar integração do serviço com o fluxo de checkout, garantindo que o preço final calculado pelo serviço seja refletido corretamente na resposta da API.
- Testar cenários com diferentes tipos de clientes (VIP e não VIP) e cupons aplicados.
- Validar que erros de entrada (ex: preço base negativo) retornam respostas HTTP apropriadas (ex: 400 Bad Request).
- Testar integração com base de dados ou sistema de cupons, se aplicável, para validar que cupons são reconhecidos corretamente.
Sugestões de testes de carga ou desempenho
- Não há evidência na mudança que justifique testes de carga ou desempenho específicos para este serviço, pois trata-se de lógica de negócio computacional simples e local.
Pontos que precisam de esclarecimento
- Qual a origem e formato esperado dos cupons? Apenas
QUERO10eQUERO20são válidos? Como cupons inválidos devem ser tratados? - A ordem de aplicação dos descontos está correta e alinhada com a política de negócio? (percentual → VIP → cupom)
- Por que o cupom
QUERO20é aplicado somente se o preço base for maior que 100, e não o preço já descontado? - Há planos para suportar outros tipos de desconto ou regras mais complexas no futuro?
- O uso de
floatpara valores monetários é intencional? Há risco de imprecisão que justifique uso deDecimal? - O método
apply_bulk_discountdeve validar entradas negativas ou zero paraitems_countetotal_value? - O serviço já está integrado a algum endpoint da API? Se sim, quais? Caso contrário, qual o plano para integração?
- Existe alguma política para tratamento de erros ou logs para casos de entrada inválida?
Resumo: A mudança introduz um novo serviço de cálculo de descontos com regras claras e específicas, mas ainda sem cobertura de testes automatizados e com algumas decisões de implementação que podem gerar dúvidas ou riscos. Recomenda-se foco em testes unitários detalhados para as regras de desconto, testes manuais para validar cenários críticos e esclarecimentos sobre regras de negócio e integração para garantir segurança e consistência na aplicação.