Olha como os padrões são coisas que você naturalmente chegaria neles. Qual é a abstração aqui? Connection. Ou Database Connection, se você quiser. Vou trazer Database Connection. O que uma Database Connection me proporciona? Olha só. Vou de novo ao contrato. Permite que eu faça uma query de um statement para alguns parâmetros e volta alguma coisa qualquer permite que eu feche essa conexão também e não volta nada o padrão adapter pessoal e agora aqui vale a pena a gente até olhar tem um site muito conhecido chamado Design Patterns Guru. Deixa eu pegar aqui a link. Tem comendo bastante esse site, tá? Faz um bom trabalho. E aí a gente tem aqui, ó, os design patterns. Vamos entrar na lista aqui, ó. Cadê a lista? Vamos ver se funciona, né? Creational Structure. Está aqui. Ah, é que o zoom está alto. É isso. Por isso. O menu não está aparecendo para o zoom. Cliquei aqui no adapter. O que o adapter diz? É um padrão de estrutura que permite que objetos com interfaces incompatíveis possam colaborar então a ideia você converte olha que interessante até o desenho eu tenho um trilho, eu tenho um carro o carro gira a roda, essa roda por meio de um tradutor gira a roda da locomotiva, do trem interessante né então normalmente do que é composto esse padrão? O adutor gira a roda da locomotiva, do trem. Interessante, né? Então, normalmente, do que é composto esse padrão? Vou ser um pouquinho mais aqui, porque a gente vai usar ele em mais de um lugar aqui, tá? Geralmente, ó, de novo aquela questão do OML, né? Eu tenho uma interface, que nesse caso foi o que a gente criou aqui, Integra Base Connection. que nesse caso foi o que a gente criou aqui database connection e aí eu implemento essa seta aqui é a seta de implementação eu implemento e aí naturalmente eu faço com que os meus o meu sistema dependa dessa interface que eu criei e aí eu faço adaptação para outra coisa que eu criei e aí eu faço adaptação para outra coisa que eu estou utilizando então eu falei o meu sistema só vai conhecer database connection, eu não quero que ele saiba do pgpromise porque o pgpromise pode mudar no futuro eu não quero depender dele converte uma interface em outra, permitindo que você reduza o acoplamento ou faça com que... Deixe-me até olhar a definição que foi dada aqui porque eu achei ela melhor ah, melhor, peraí eu acho que tem uma boa definição, sabe onde? agora está no livro, né deixa eu pegar aqui o adapter está na mão já adapter, vamos lá converte a interface de uma classe em outra interface esperada pelo cliente. Converte a interface de uma classe em outra esperada pelo cliente. O que mais diz aqui? O adaptador permite que classes incompatíveis trabalhem juntas. Permitindo que classes incompatíveis que eu quis dizer aquela hora, trabalhem juntas. Show. O que vai acontecer aqui, então? A gente vai fazer um pgPromiseAdapter.ts Vamos lá. Export default class pg promise adapter implement database o que eu tenho que fazer aqui isso vamos lá, vamos olhar agora pra cá e vamos copiar isso aqui, isso aqui olhar agora pra cá e vamos copiar Sai daqui Vem pra cá Brans, consegue dar uma subidinha De novo no zoom? Opa Isso eu posso saber se você estava ligado Connection está aqui Connection está aqui também Vou fazer aqui vou mover essa dependência para cá um pouco disso e aqui então olha a conversão return connection que eu estou abraçando query estou repassando a query. E o close. Return. Connection. O. End. Por quê? Porque nesse caso eu não fico dependendo disso aqui. E agora vamos juntar com a inversão de dependência, pessoal. Porque não adianta eu vir aqui e dizer assim, database connection é igual a new pgpromise. Não faz diferença nenhuma, porque eu já estou usando a instância de pgpromise. Não é essa a ideia. É isso. Vou fazer a mesma inversão de dependência. Constructor. Read only database connection. Aqui dentro. Database connection. Aqui. Eu copiei coisa demais. Espera aí. Deixa eu dar um control Z aqui. Porque eu acho que eu levei embora aqui o que eu devia. Espera aí. Eu copiei coisa demais. Deixa eu dar um Ctrl Z aqui, porque eu acho que eu levei embora aqui o que eu devia. Pera aí. Então. Read Only. Connection. Database. Connection. Aqui. readonly connection database connection aqui esse ponto esse ponto vou fechar aqui? não acho que não, né por enquanto não, não vou fechar aqui não vai ficar assim porque agora eu tenho controle então, não vou fechar aqui não, vai ficar assim. Por quê? Porque agora eu tenho o controle. Então, olha que bonito isso aqui. O teste agora exige que eu passe a connection. Connection igual a new PG Promise. E eu vou passar ela aqui. Para a coisa ficar legal, vou fazer o seguinte. Eu vou comentar essa parte. Eu vou extrair isso aqui para cá. ContractRepository igual aqui, ContractRepository. E aí essa connection eu vou deixar lá de fora. Olha o controle que a gente vai ter aqui agora que é espetacular. database connection Eu poderia ter um after each lá embaixo depois de tudo. Ou um after all até. Dizendo o seguinte. connection close Esse é o tipo de controle que a gente ganha? Agora a gente no teste tem o controle da criação da conexão, eu poderia passar para o database repository outra conexão que não do pgpromise e ele não saberia disso, por que? Por causa da inversão da dependência. Beleza? Vamos voltar ainda rapidamente no padrão adapter daqui a pouquinho. Legal. Fizemos várias coisas aqui interessantes. Agora, o que mais está estranho aqui? O que mais poderia ficar melhor? Se você reparar, a gente ainda tem uma certa mistura entre regra de negócio, talvez num lugar aqui que deveria ser mais de orquestração do que propriamente de execução dessa regra de negócio. E aqui a gente começa a finalmente falar um pouco do propósito padrão repository. Não pode ser N, Não pode ser qualquer coisa que está voltando. Isso aqui está vindo dados do banco. Dados... Se alguém mudar a coluna, ele é afetado. Concorda? Se o DBA for lá e der um rename numa column, eu afeto a regra de negócio da aplicação. Tudo que a gente não quer é fragilidade no sistema. Imagina que eu tenha 200 lugares no sistema fazendo por exemplo um payment ponto de cheio de beba do país o dente quebrou 200 lugares que vai fazer a gente vai trazer o repositório o agregue em si é formado pelos objetos de domínio. Nesse caso, o que é? É o contract. E esse contract? Ele é composto do quê? Vamos lá. Export the full class contract. Todo contract tem... Ele tem algumas coisas, né? Vamos ver tudo que ele tem ele tem no mínimo description vou quebrar a linha como a gente está com o zoom meio alto ele tem description, como a gente viu lá temos que é number, olha o tipo aí a gente viu lá Temos Alph Que é number Olha o tipo aí A gente tem Bom Os peers Nesse caso aqui é um number também O que mais? Tendente Tendente Aí está tudo certo Para a gente pensar aqui Todo contrato tem um conjunto de pagamentos é um array payments é um array agora, o que eu poderia por hora eu vou fazer assim, vamos ver se só aí já vira payments pass export the full class payments read only consultor read only o que o payments tem? basicamente vai ter page vamos seguir vai ter o Amalfi Method. O método eu nem vou colocar, só vou colocar o Amalfi. Poderia ser Cash, podia ser credit card, debit card, e assim por diante, né? Então, olha o primeiro ponto importante aqui, ó. Tá aí o payments quebrou todo mundo, tá ótimo e aqui eu quero agora eu deveria voltar a contracts agora fica legal porque o que eu vou voltar aqui isso aqui não é contracts isso aqui é contracts data isso aqui não é contracts isso aqui é contracts data são dados de contratos contracts por sua vez é o array de contratos e o que eu vou voltar é esse array de contratos. Agora, toda vez que eu passar por um contrato, eu vou dizer, contract igual new contracts. Olha a descrição. Contract data description. Olha a conversão aqui. O que mais? Contract data amount.amalfi. ContractData.periods.contractDataDate. Detalhe, a Amalfi aqui tem parse float. Olha como eu estou resolvendo, já na implementação da origem do dado, o retorno correto para a aplicação. Não vai voltar string, para que eu, aqui no use case, eu tenha que saber que eu tenho que fazer a conversão, cadê? Para float. Ou aqui ou aqui. Não faz sentido. O que mais? Fizemos isso aqui. Agora, esquece isso aqui. Agora, ó. Esquece isso aqui. Payments data, certo? Aqui, ó. Esse ID a gente não colocou, né? Vamos colocar read-only ID contract string, que é um UUID, né? Vou botar o payment também. Read-only payment string. Aqui, então, ó. Contract data ID contract. Aqui então ContractData E de Aqui ContractData Já está convertido Para cada PaymentData Contract Aí eu poderia adicionar, mas poderia simplesmente fazer e o eu posso estar hidratando esse objeto, recuperando o estado desse objeto só que aqui com o contract que está reclamando porque faltou adicionar para cada um agora, contract push e aqui eu estou voltando a promise de contract array por isso que ele não estava aceitando, aqui é array também agora isso está próximo de um repository entendeu a diferença? agora está perto do repository por que eu digo que está perto? bom, a gente ainda tem que levar lógica para essas entidades para que elas de fato sejam entidades mas está bem perto já aqui, repara eu não tenho que fazer pass float eu já tenho a tipagem garantida. Aqui, mesma coisa, não tem que fazer parse float, temos a tipagem garantida. Vou rolar o Jest de novo. Agora que a gente tem isso, me vem à cabeça algumas coisas que é o seguinte, olha, de repente aqui nesse contract, poderia ter aqui um add payment, de repente para eu reduzir um pouquinho essa visibilidade do que tem lá dentro, aí a gente poderia pensar, olha, posso passar o payment, posso passar os dados do payment, vou passar o payment todo também, vou dizer, payments, push, payments, beleza. Poderia dizer que isso aqui é private, poderia dizer, de repente, aqui um get payments, de repente, aqui um GetPayments. Return Payments. Aqui. Olha como já mudou. Esse Push que a gente faz aqui, na verdade, poderia ser um GetPayments. Esse For aqui poderia ser um GetPayments. esse for aqui pode ser um getPayments toda essa operação que está aqui se a gente parar para pensar será que ela está aí? porque, vamos pensar bem o que todo esse trecho de código faz? ele pega um contrato e toma a decisão de qual é qual é o invoice que eu vou gerar então eu posso dar um CTRL X eu poderia ter aqui um generate invoices deste contrato por que? por type olha surgindo aí essa entidade Por quê? Por type. Olha surgindo aí essa entidade. Tá. Aqui, input, fechou. Agora esse output eu não tenho. Então eu vou ter que me virar numa coisa aqui que é o seguinte. Olha, eu acho que nasceu um tipo chamado invoice. O que é um invoice? export default class invoice invoice é composta de only bom, a gente está lidando com duas coisas com uma date string que estamos lidando também que não precisaria ser string porque a gente está forçando por causa do output dela. Então vamos botar date, date mesmo. E a gente tem a mouth, que é number. Poderia ter aqui então invoices. E o que eu volto aqui agora é invoice. E que contract.getPayment é disso E que é input Month Eu tenho que orientar Esse contrato aqui, qual mês e qual ano eu quero Então tá bom, mês É number, year Number Então, esquece esse input E o outro input Esse output aqui segura, vamos fazer o import moments. Aqui, esse output vai ser invoice, esse push aqui não faz sentido que seja assim, eu não tenho payment date, vou fazer o seguinte new invoice, peguei o payment date, vou pegar o payment amount, aqui, fees, periods, fees date, tiro os dois inputs this.periods this.date tira os dois inputs this.amouth this.periods invoices.push invoices.amouth e faz a mouse vou para mais um e agora, o que sobrou para cá? olha que interessante o output ele é a string, mas é o output não é a entidade. Então, agora sim, o que eu vou fazer? Para cada contrato, eu vou dizer invoices é igual a contract.indireitInvoices. Passando o quê? Input month, input year, input type.í, deixa eu ver, não retornei, aqui, invoice, return invoices, fechou, já inferi o tipo, ok, output push, page é invoice, page, mas aqui como a gente sabe o moment, para fazer o format, já vamos achar um padrão para resolver isso aí e a mouth depois a mouth vamos ver se o teste passa não sei, muita mexida muita mexida ficou um 22 a mais ali provavelmente eu errei aqui vai errar alguma coisa, né? Passou Só que aí, sem a gente se dar conta Agora que eu tenho um repository E agora eu tenho Entidades propriamente ditas Sabe o que eu consigo fazer? Eu consigo fazer um teste de contracts Sem precisar fazer um teste de integração Agora eu posso ter um teste de contracts sem precisar fazer um teste de integração agora eu posso ter um teste de unidade deve gerar faturas de um contrato olha que bonito const contract igual a new contract em id, tanto faz description, tanto faz isso é o que a gente chama de dummy 6 mil reais in use page 2022, 0101, 10, 0000 tá aí agora basta fazer o seguinte invoices igual a config.generateInvoice 1.2022 E eu espero que Agora a mesma coisa de lá A teoria é isso aqui só que aqui eu tenho invoices então aqui não é output aqui de fato eu tenho invoices então quer ver, quando eu for rodar isso aqui ele vai quebrar por causa do formato vai reclamar do formato está vendo deixa eu botar do formato. Está reclamado o formato. Está vendo? Deixa eu botar o formato completo aqui. Aqui ele pegou com... sem o timezone. Deixa eu ver o que ele errou aqui. 22, ah, está. Espera aí. eu boto um getTime e aqui eu tenho um teste de unidade esse é um teste de unidade esse é um teste de integração. Unit test e integration test. Pronto?