Desenvolvendo O Caso De Uso BuscarVoos Na BuscaVoosTeste App

by Admin 61 views
Desenvolvendo o Caso de Uso BuscarVoos na BuscaVoosTeste App

Introdução: Desvendando a Busca de Voos no Projeto BuscaVoosTeste

E aí, pessoal! Preparem-se para embarcar em uma jornada crucial no coração do nosso projeto BuscaVoosTeste. Hoje, vamos mergulhar de cabeça na implementação do BuscarVoosUseCase na camada de aplicação BuscaVoosTeste.Application, um passo fundamental para o funcionamento da nossa plataforma de busca de voos. Este não é apenas mais um pedaço de código; é o motor que vai permitir que nossos usuários encontrem suas viagens de forma eficiente e confiável. Entender o papel do BuscarVoosUseCase é como decifrar a alma da nossa aplicação, pois é ele quem orquestra todas as ações necessárias para transformar um pedido de busca em resultados concretos, seguindo à risca os princípios da Clean Architecture. Estamos falando de um componente que precisa ser robusto, testável e, acima de tudo, coeso com todo o modelo de domínio que já definimos. A camada BuscaVoosTeste.Application é a intermediária inteligente, a ponte que conecta a interface do usuário com a lógica de negócio e os serviços de infraestrutura, tudo isso sem que um conheça os detalhes internos do outro. Essa separação de responsabilidades não é frescura, galera, é a base para um sistema escalável, fácil de manter e de evoluir. Vamos construir uma busca de voos que não só funcione, mas que seja um exemplo de boa prática de desenvolvimento, onde a clareza, a consistência e a aderência às nossas convenções de código são inegociáveis. O objetivo é criar algo que seja não só funcional, mas também elegante e fácil de entender por qualquer desenvolvedor que chegue no projeto. Bora lá!

O Coração da Operação: Criando o BuscarVoosUseCase na BuscaVoosTeste

Chegamos ao ponto nevrálgico da nossa missão, o objetivo central desta tarefa: criar a implementação concreta do BuscarVoosUseCase no projeto BuscaVoosTeste.Application. Pense nesse BuscarVoosUseCase como o maestro de uma orquestra; ele não toca todos os instrumentos, mas garante que cada um deles toque na hora certa, em harmonia. Sua principal responsabilidade é orquestrar a lógica de negócio da busca de voos, garantindo que os dados de entrada sejam validados, que a chamada ao provedor externo (como a Duffel) seja feita corretamente através de uma interface de infraestrutura – sem acoplamento direto, claro! – e que os resultados sejam mapeados de volta para os nossos DTOs de saída de maneira compreensível. Este BuscarVoosUseCase é a representação viva de um caso de uso na nossa aplicação, um componente que encapsula uma funcionalidade específica e crucial. Ele vai consumir um DTO de entrada (tipo um BuscarVoosInput), utilizar uma interface de provedor de busca (como a IFlightSearchProvider) e, claro, trabalhar com o nosso modelo de domínio de voos (FlightOffer, FlightSegment, etc.), transformando tudo em informações úteis para o usuário. Tudo isso, sem esquecer das nossas regras de negócio de busca de voos e, é claro, mantendo a consistência com as convenções de código, o idioma português do Brasil e a arquitetura que definimos. Estamos construindo um pilar fundamental para a funcionalidade de busca de voos, então a atenção aos detalhes aqui é máxima. A ideia é que este BuscarVoosUseCase seja um exemplo de como orquestrar operações complexas de forma limpa e eficiente, garantindo que o fluxo da busca de voos seja suave e previsível para quem o utiliza e para quem o mantém.

Mergulhando Fundo na Implementação do BuscarVoosUseCase

Ao mergulharmos na implementação do BuscarVoosUseCase, nosso foco será a criação de uma classe robusta e aderente às nossas diretrizes arquiteturais. Primeiro, precisamos garantir que a interface IBuscarVoosUseCase já exista no projeto BuscaVoosTeste.Application, no namespace/pasta que especificamos. Não podemos alterar a assinatura pública dela, pessoal, isso é um contrato! A classe BuscarVoosUseCase será criada no mesmo projeto, em uma pasta lógica como UseCases/BuscarVoos, seguindo a padronização para casos de uso. Ela vai implementar a interface IBuscarVoosUseCase, e sua visibilidade, modificadores e o padrão de injeção de dependência via construtor devem espelhar as convenções definidas. A injeção de dependências é fundamental aqui: vamos injetar a interface do provedor de busca de voos (IFlightSearchProvider) e quaisquer outros serviços auxiliares (logging, mapeamento, validadores), sempre através de interfaces ou abstrações, nunca diretamente a implementações concretas de infraestrutura. Isso garante que nosso BuscarVoosUseCase seja agnóstico sobre como a busca é feita ou como outros serviços são implementados. O método principal, digamos ExecutarAsync ou BuscarAsync, será onde a mágica acontece. Ele receberá o DTO de entrada (BuscarVoosInput), validará as informações essenciais (origem, destino, datas, passageiros, conforme nossas regras de negócio), mapeará esse DTO para o formato esperado pelo provedor de voos, chamará o IFlightSearchProvider e, finalmente, mapeará o resultado de volta para os nossos DTOs de saída. E, claro, a gente precisa ser gente boa e tratar os cenários chatos: nenhuma oferta encontrada (retornando algo coerente) ou erros do provedor (retornando uma mensagem amigável, em português, sem expor detalhes internos). A coesão com o nosso Domain Model é vital; usaremos entidades como FlightOffer, FlightSegment e value objects para garantir que a lógica de negócio seja bem representada. E por último, mas não menos importante, vamos registrar a interface IBuscarVoosUseCase com a nossa implementação BuscarVoosUseCase no container de DI, garantindo que a aplicação saiba como criar e fornecer uma instância desse caso de uso quando necessário. Isso tudo é a essência do que estamos construindo: um BuscarVoosUseCase que é eficiente, desacoplado e fácil de gerenciar.

Onde Não Pisar: Entendendo o Que Está Fora do Escopo

É super importante, galera, a gente ter uma clareza cristalina sobre o que não faz parte desta tarefa. Manter o escopo bem delimitado nos ajuda a focar, evitar desvios e garantir que a entrega seja precisa e de alta qualidade para o nosso BuscarVoosUseCase. Primeiro, esqueçam a criação ou alteração de endpoints HTTP na camada BuscaVoosTeste.Api. Isso não é trabalho para agora; a exposição do caso de uso via API será tratada em outras issues, então nada de mexer em controllers por enquanto. Em segundo lugar, não vamos implementar nem mexer no cliente de infraestrutura (o tal do cliente Duffel ou qualquer outra API externa) na camada BuscaVoosTeste.Infrastructure. Se o DuffelFlightSearchProvider já existe, ele fica como está. Nosso foco é usar a interface dele, não implementar os detalhes. Terceiro ponto crucial: mudanças no modelo de domínio estão fora de cogitação. Não criamos, excluímos ou alteramos entidades de domínio como FlightOffer, FlightSegment ou value objects. Eles já foram definidos e são a base que usamos, não o que estamos construindo agora. As regras de negócio em 20-regras-negocio-busca-voos.md também são sagradas; não as alteramos. Quarto, nada de integração com MCP ou ferramentas do MCP Server; não é o momento de criar tools no BuscaVoosTeste.McpServer ou ajustar scripts. Quinto, e isso é importante para a gente se manter focado: não vamos criar testes automatizados nesta issue. Testes unitários, de integração ou end-to-end terão suas próprias issues específicas. E por fim, e talvez o mais importante, não há espaço para alterações de arquitetura ou convenções. A estrutura de pastas, nomes de projetos, namespaces e convenções de idioma/estilo que estão lá desde 10-arquitetura-clean.md e 15-convencoes-de-codigo.md são os nossos mandamentos. O objetivo aqui é seguir o mapa, não redesenhá-lo. A gente está construindo o BuscarVoosUseCase dentro de um sistema já estabelecido, e respeitar essas fronteiras é essencial para o sucesso do projeto como um todo e para a clareza da nossa tarefa de implementar o BuscarVoosUseCase na BuscaVoosTeste.Application.

Seu Mapa do Tesouro: As Instruções Essenciais para o Sucesso

Para garantir que a implementação do BuscarVoosUseCase na BuscaVoosTeste.Application seja um sucesso retumbante, a gente não pode sair atirando para todo lado, certo? Temos um conjunto de instruções que são o nosso mapa do tesouro, um guia essencial para nos orientar em cada linha de código. Ignorá-los é como tentar navegar sem bússola. Por isso, é mandatório consultar e seguir rigorosamente estas referências. O 00-visao-geral-e-objetivos.md nos dá a visão macro, o porquê de tudo, o objetivo final do sistema de busca de voos. É o nosso propósito, galera! O 10-arquitetura-clean.md é a nossa bíblia arquitetural, garantindo que o BuscarVoosUseCase respeite a separação de responsabilidades da Clean Architecture, assegurando que a camada de aplicação orquestre o domínio e a infraestrutura através de abstrações, sem acoplamento direto. Já o 15-convencoes-de-codigo.md é onde a gente aprende a falar a mesma língua: português do Brasil no código e nos comentários, padrões de nomenclatura para classes, interfaces, métodos e arquivos, e como organizar pastas e namespaces. Sem isso, nosso código vira uma torre de Babel! O 20-regras-negocio-busca-voos.md é onde estão as leis do nosso negócio: validações, filtros obrigatórios, limites de datas, regras para passageiros. Essas são as balizas que o nosso BuscarVoosUseCase tem que respeitar religiosamente. O 40-domain-model.md nos apresenta as estrelas do nosso domínio: FlightOffer, FlightSegment, value objects como Duration e Money. Nosso caso de uso tem que interagir com esses caras de forma inteligente e correta. O 50-application-usecases.md é o playbook do BuscarVoosUseCase: define a interface IBuscarVoosUseCase, as responsabilidades da nossa classe, os DTOs de entrada/saída e os padrões de orquestração. É aqui que a gente pega a receita! E por último, o 60-infrastructure-duffel-client.md nos mostra como o provedor de busca de voos (nossa IFlightSearchProvider) expõe seus métodos e contratos de dados, para que o BuscarVoosUseCase chame a infraestrutura corretamente, sempre via abstrações. Seguir esses documentos não é opcional, pessoal, é a garantia de que o nosso BuscarVoosUseCase será uma peça de engenharia de software de alta qualidade, perfeitamente integrada e compreensível, essencial para o sucesso da nossa aplicação de busca de voos. Confiem no mapa!

Mão na Massa: Implementando o BuscarVoosUseCase Passo a Passo

Agora que já entendemos o contexto e temos nossos mapas em mãos, é hora de colocar a mão na massa e realmente construir o BuscarVoosUseCase dentro do nosso projeto BuscaVoosTeste.Application. Cada passo aqui é fundamental para garantir que a implementação do BuscarVoosUseCase na BuscaVoosTeste.Application seja feita com precisão e seguindo todas as nossas diretrizes. Lembrem-se, a qualidade do nosso código depende da atenção a cada um desses detalhes, desde a fase de preparação até o registro final no nosso container de Injeção de Dependência (DI). Não pulem etapas, galera! Cada uma delas tem um propósito e contribui para a robustez e manutenibilidade do nosso sistema de busca de voos. Este é o momento de transformar as especificações em realidade, linha por linha de código, sempre com o objetivo de criar um caso de uso que seja claro, eficiente e que se encaixe perfeitamente na nossa arquitetura limpa. Vamos construir um componente que não só funcione, mas que seja um verdadeiro modelo de excelência em desenvolvimento de software, digno da nossa equipe e dos nossos padrões de convenções de código e português do Brasil.

Preparação é Chave: Revisando as Instruções Cruciais

Antes de digitar uma única linha de código para o nosso BuscarVoosUseCase, a primeira tarefa e, sem dúvida, a mais crucial, é revisar as instructions relevantes. Pensem nisso como o briefing pré-voo de um piloto: ele não decola sem checar tudo. Vocês precisam ler atentamente os documentos que mencionei anteriormente: 00-visao-geral-e-objetivos.md, 10-arquitetura-clean.md, 15-convencoes-de-codigo.md, 20-regras-negocio-busca-voos.md, 40-domain-model.md, 50-application-usecases.md e 60-infrastructure-duffel-client.md. A intenção aqui não é apenas ler, mas compreender profundamente cada um deles. Confirmem o nome exato da interface do caso de uso (será IBuscarVoosUseCase, certo?), o nome da implementação esperada (provavelmente BuscarVoosUseCase), e, o mais importante, o(s) DTO(s) de entrada e saída que foram definidos para este caso de uso específico. Prestar atenção aos DTOs é vital, pois eles são o contrato de comunicação. Além disso, precisam identificar a interface do provedor de busca de voos que será utilizada – como a IFlightSearchProvider. Qualquer desvio aqui pode gerar retrabalho gigantesco mais tarde. Esta etapa de revisão é a base para todo o trabalho que se seguirá; ela evita suposições erradas e alinha todos os envolvidos com as expectativas exatas do projeto. Ao entender os contratos e as regras de negócio, vocês garantem que o BuscarVoosUseCase que será desenvolvido será perfeitamente integrado e alinhado com a visão global do sistema de busca de voos. É o momento de tirar dúvidas e garantir que a base do conhecimento está sólida antes de avançarmos para a implementação em si.

Construindo o Pilar: Criando a Classe BuscarVoosUseCase

Com as instruções devidamente assimiladas, o próximo passo é erguer o pilar central da nossa funcionalidade: a criação da classe BuscarVoosUseCase. Essa etapa envolve mais do que apenas criar um arquivo; significa integrá-lo corretamente na arquitetura do projeto BuscaVoosTeste.Application. No projeto BuscaVoosTeste.Application, vocês vão criar um novo arquivo de classe, nomeado, por exemplo, BuscarVoosUseCase.cs, e posicioná-lo na pasta apropriada para casos de uso de busca de voos. As instruções geralmente sugerem algo como UseCases/BuscarVoos, o que mantém a organização limpa e modular. Dentro desse arquivo, vocês deverão declarar a classe BuscarVoosUseCase implementando a interface IBuscarVoosUseCase. É crucial que o namespace da classe siga estritamente o padrão adotado na camada de Application e documentado nas convenções de código. Por exemplo, algo como BuscaVoosTeste.Application.UseCases.BuscarVoos. Garantir que o nome do arquivo, da classe e o namespace estejam em perfeita conformidade com as nossas convenções de código e o idioma português do Brasil é fundamental para a clareza e manutenibilidade do projeto. Um nome bem escolhido e um posicionamento lógico facilitam muito a vida de qualquer desenvolvedor que venha a trabalhar nesse código no futuro. A estrutura bem definida do nosso BuscaVoosTeste.Application não é apenas um capricho, é uma estratégia para garantir que cada componente, incluindo o BuscarVoosUseCase, tenha seu lugar certo e suas responsabilidades bem delimitadas. Isso reforça a Clean Architecture e torna a navegação pelo código muito mais intuitiva. Ao seguir essas diretrizes de nomenclatura e estrutura, estamos construindo não apenas uma classe, mas um componente que se integra de forma harmoniosa ao ecossistema existente, contribuindo para a organização e a escalabilidade da nossa aplicação de busca de voos. Este é o alicerce onde o restante da lógica será construído, então, capricho total!

O Cérebro da Operação: Implementando o Método Principal do Caso de Uso

Agora chegamos ao ponto onde a mágica realmente acontece: implementar o método principal da interface IBuscarVoosUseCase. Este é o cérebro do nosso BuscarVoosUseCase, onde toda a lógica de orquestração para a busca de voos reside. Vocês precisam seguir exatamente a assinatura especificada em 50-application-usecases.md, incluindo o uso de async, o tipo de retorno (Task/Task<T>) e, se houver, a CancellationToken, que é vital para operações assíncronas canceláveis. O fluxo interno desse método será uma sequência lógica de passos bem definidos. Primeiro, a validação básica do input. Aqui, antes de qualquer coisa, o BuscarVoosUseCase deve checar se os campos obrigatórios do DTO de entrada (origem, destino, datas de ida/volta, quantidade de passageiros, etc.) estão preenchidos e válidos, conforme as regras de negócio de 20-regras-negocio-busca-voos.md. Por que fazer isso tão cedo? Para evitar processamento desnecessário e fornecer feedback rápido ao usuário. Em caso de violação, sigam o padrão definido para erros (lançar exceções de domínio ou retornar um objeto de resultado com erro, sempre com mensagens em português do Brasil). Segundo, o mapeamento para o provedor. O DTO de entrada do caso de uso (ex: BuscarVoosInput) precisa ser transformado no contrato de entrada que o IFlightSearchProvider (ou a interface correspondente) espera. Isso garante que a camada de aplicação não exponha detalhes internos do nosso domínio para o provedor externo e vice-versa. Terceiro, a chamada ao provedor de busca de voos. É aqui que o BuscarVoosUseCase faz a chamada assíncrona para o método definido em IFlightSearchProvider para obter as ofertas de voo. É crucial tratar eventuais exceções oriundas da camada de infraestrutura, convertendo-as para respostas compreensíveis na camada de aplicação, sem expor detalhes técnicos que não interessam ao usuário. Quarto, o mapeamento do resultado para DTOs de saída. As entidades de domínio retornadas pelo provedor (como FlightOffer e FlightSegment, que vimos em 40-domain-model.md) devem ser mapeadas para os DTOs de saída definidos para o nosso caso de uso em 50-application-usecases.md. Garanta que todos os campos relevantes (horários, duração, valor, moeda, escalas, companhia aérea) sejam preenchidos corretamente, respeitando as regras de 20-regras-negocio-busca-voos.md. E por fim, o retorno do resultado padronizado. O BuscarVoosUseCase deve retornar o DTO de saída contendo a lista de ofertas e metadados da busca. Cuidado especial aqui para os cenários onde nenhuma oferta foi encontrada (retornar uma coleção vazia e, opcionalmente, uma mensagem informativa em português do Brasil) ou onde houve um erro de comunicação com o provedor (retorno padronizado, sem expor detalhes internos ou stack traces). O objetivo é que o consumidor do BuscarVoosUseCase sempre receba uma resposta consistente e fácil de interpretar. Essa implementação detalhada do fluxo do caso de uso é o coração da busca de voos, e fazê-la bem significa uma aplicação mais confiável e amigável. Além disso, precisamos garantir que não haja acoplamento indevido à infraestrutura. Isso significa que o BuscarVoosUseCase deve depender apenas de interfaces/abstrações de provedores de voos (ex: IFlightSearchProvider), entidades/value objects de domínio e serviços utilitários de aplicação (ex: logger, mappers), nunca diretamente de classes concretas de infraestrutura como clientes HTTP específicos. Essa é a chave para um design limpo e flexível!

Conectando as Peças: Injeção de Dependências e Coesão

Para que o nosso BuscarVoosUseCase funcione como uma engrenagem bem azeitada, ele precisa de algumas ferramentas e parceiros, e é aí que a injeção de dependências (DI) entra em cena, galera! Pensar em BuscarVoosUseCase sem DI é como querer montar um carro sem chaves de fenda. A injeção de dependências é o mecanismo pelo qual as dependências (outros serviços que o caso de uso precisa) são fornecidas a ele, geralmente através do seu construtor, em vez de o BuscarVoosUseCase criá-las por conta própria. Isso nos traz uma flexibilidade enorme, tornando nosso código mais testável, mais fácil de manter e mais desacoplado. A gente vai injetar, via construtor da classe BuscarVoosUseCase, no mínimo: a interface do provedor de busca de voos (aquela IFlightSearchProvider que conversamos), e qualquer outro serviço auxiliar que as instructions mencionem explicitamente (pensem em loggers, mapeadores, validadores, etc.). A palavra-chave aqui é interface. Armazenem essas dependências em campos readonly, e o mais importante: nomeados em português do Brasil, alinhados com as nossas convenções de código. Por exemplo, um _provedorDeVoos ou _logger. Nunca, em hipótese alguma, injetem implementações concretas de infraestrutura! Isso quebraria o princípio de inversão de dependência e nos amarraria a detalhes de implementação que deveriam ser transparentes para a camada de aplicação. Ao final, precisamos garantir que a IBuscarVoosUseCase esteja devidamente registrada no container de DI com a implementação BuscarVoosUseCase. Geralmente, há um ponto central de registro (tipo um método de extensão AddApplication ou similar) no projeto responsável pelas configurações de DI, conforme 30-dependencias-e-configuracoes.md e 50-application-usecases.md. Esse registro deve respeitar o padrão de vida útil (scoped/transient/singleton) especificado. Fazer isso direito garante que, quando alguém pedir uma instância de IBuscarVoosUseCase, nosso sistema saberá entregar um BuscarVoosUseCase novinho em folha, com todas as suas dependências já resolvidas e prontas para trabalhar. É a implementação do BuscarVoosUseCase na BuscaVoosTeste.Application sendo configurada para o sucesso!

O Toque Final: Garantindo Qualidade e Compilação

Depois de todo esse trabalho árduo na implementação do BuscarVoosUseCase na BuscaVoosTeste.Application, chegamos à etapa de revisão e compilação, que é o nosso controle de qualidade final. Não pensem que o trabalho termina quando a última linha de código é digitada! Uma boa revisão garante que tudo o que construímos está em conformidade com os altos padrões que estabelecemos. Primeiro, vamos revisar o idioma, nomes e convenções. Isso significa passar um pente fino na classe BuscarVoosUseCase e em todos os seus membros públicos e privados. Todos os nomes de métodos, parâmetros, propriedades e comentários devem estar em português do Brasil, sem exceção, e alinhados com 15-convencoes-de-codigo.md. Chequem se não há aquela mistura chata de inglês e português em nomes internos, a não ser que seja estritamente exigido por contratos externos já documentados. Verifiquem se o estilo de código (organização, espaçamento, documentações) está impecável. Essa consistência facilita a leitura e manutenção para todo mundo. Segundo, e não menos importante, vamos verificar a compilação da solução completa. Compilem a solução BuscaVoosTeste.sln após todas as alterações. Qualquer erro de compilação ou warning crítico diretamente relacionado ao BuscarVoosUseCase ou à sua injeção de dependências deve ser tratado imediatamente. Uma solução que compila sem problemas é o nosso sinal verde, indicando que as peças se encaixam. Lembrem-se, nosso objetivo é entregar não apenas um BuscarVoosUseCase funcional, mas um pedaço de software clean, robusto e que serve de exemplo para o resto do projeto de busca de voos. Este é o momento de polir o diamante, garantindo que o BuscarVoosUseCase esteja pronto para brilhar na nossa aplicação, cumprindo todas as expectativas de qualidade e design que definimos desde o início. É o seu último check-list antes do lançamento!

A Prova do Pudim: Critérios de Aceitação para o Nosso BuscarVoosUseCase

Para que esta issue seja considerada um sucesso absoluto e possamos bater o martelo na implementação do BuscarVoosUseCase na BuscaVoosTeste.Application, a gente precisa ter certeza de que todos os critérios de aceite foram devidamente atendidos. Pensem neles como os requisitos mínimos para que nosso BuscarVoosUseCase seja considerado pronto para decolar! Primeiro, a Classe de caso de uso criada e implementada: A classe BuscarVoosUseCase tem que existir no BuscaVoosTeste.Application, no namespace/pasta corretos para casos de uso de busca de voos, e ela deve implementar a interface IBuscarVoosUseCase sem nenhuma alteração na sua assinatura pública. Segundo, o fluxo do caso de uso implementado conforme regras de negócio: O método da interface na classe BuscarVoosUseCase precisa conter a validação básica do DTO de entrada (origem, destino, datas, passageiros, etc.) de acordo com as regras de negócio de 20-regras-negocio-busca-voos.md. Além disso, deve haver o mapeamento correto do input para o contrato do provedor de voos, a chamada à interface de provedor (IFlightSearchProvider), o mapeamento do retorno do provedor (entidades de domínio) para os DTOs de saída, e, por fim, o tratamento adequado de cenários como “nenhuma oferta encontrada” e erros, sempre com mensagens em português do Brasil e sem expor detalhes internos. Terceiro, o uso correto do modelo de domínio: A implementação tem que usar as entidades e value objects de 40-domain-model.md (FlightOffer, FlightSegment, Duration, Money) quando aplicável, e esse uso precisa respeitar as regras de 20-regras-negocio-busca-voos.md. Quarto, dependências injetadas por abstrações: Nosso BuscarVoosUseCase não pode depender diretamente de implementações concretas de infraestrutura. Todas as dependências externas têm que ser interfaces/abstrações, conforme definido nas instruções. Quinto, o registro de DI configurado: A interface IBuscarVoosUseCase deve estar devidamente registrada no container de DI com a implementação BuscarVoosUseCase, no ponto especificado pelas instruções de 30-dependencias-e-configuracoes.md. A solução precisa compilar sem erros relacionados à resolução de dependências. Sexto, idioma e convenções de código: Tudo (nomes de classes, métodos, parâmetros, propriedades e comentários) em português do Brasil, em total conformidade com 15-convencoes-de-codigo.md. Nenhuma mistura desnecessária de inglês! Sétimo, compilação da solução: A BuscaVoosTeste.sln tem que compilar sem erros, e não podem ter sido incluídos arquivos ou modificações fora de escopo (nada de API, MCP, domínio ou infra que não seja o necessário para usar interfaces já existentes). E por último, mas não menos importante, respeito às instructions e ao escopo: Nenhuma entidade de domínio nova foi criada ou alterada fora do especificado, nenhum endpoint, controller, tool de MCP ou cliente de infraestrutura novo foi criado. As instructions referenciadas foram seguidas e não houve alteração de arquitetura ou convenções globais. Se a gente checar todos esses pontos, é hora de comemorar! A busca de voos está no caminho certo!

Um Recado Especial para Nossos Parceiros de IA

E aí, Copilot/agente, um recado especial para você, nosso parceiro inteligente! Para que a implementação do BuscarVoosUseCase na BuscaVoosTeste.Application saia perfeita, preciso que você preste atenção a alguns pontos cruciais. Primeiro, não omita código! Geração completa é a regra; nada de // código omitido ou .... A classe BuscarVoosUseCase tem que estar inteirinha, com todos os membros implementados, sem faltar nada, para que qualquer pessoa possa copiar e usar diretamente. Segundo, respeite fielmente as instructions. Antes de gerar qualquer coisa, por favor, releia com atenção redobrada 15-convencoes-de-codigo.md, 20-regras-negocio-busca-voos.md, 40-domain-model.md, 50-application-usecases.md e 60-infrastructure-duffel-client.md. Se por acaso houver alguma discrepância entre o que você