[Música] deixa eu te contar algo que você talvez já saiba para as coisas mudarem você precis mudar para as coisas melhorarem você precis melhorar ninguém vai estudar por você ninguém vai cudar por você ninguém vai alcanar o seu sonhos por você só você tem o poder de tornar isso realidade Ready For the next Level Aperte o simpos porque vai começar mais uma edição do Next level we para te levar para o seu próximo nível em programação seja bem-vindo e bem-vinda ao nlw Pocket JavaScript fala Dev seja muito bem-vindo muito bem-vinda ao nlw Pocket de JavaScript
eu sou Diego Fernandes e sou City na Rocket City também programador há 13 anos eu vou te acompanhar na trilha intermediária aqui com react e node juntos a gente vai construir em Apenas três aulas um app para cont controles de metas pessoais para você acelerar pro seu próximo nível em programação nesse evento totalmente gratuito você vai aprender como usar o poder do JavaScript para se destacar no mercado de trabalho Esse é um conteúdo inédito Então aproveita muito essa oportunidade porque as aulas vão ficar disponíveis somente essa semana para você assistir Claro no horário que você
preferir mas para chegar chegar até o Final dessa missão eu preciso que você Se comprometa a assistir todas essas aulas e colocar a mão na massa junto comigo para sair daqui com um projeto pro seu portfólio e Um certificado pro seu currículo beleza Lembrando que sempre que tiver qualquer dificuldade ou qualquer dúvida você pode acessar a comunidade do discord da sua trilha e mandar a dúvida por lá o link dessa comunidade todas as informações do evento estão Reunidas no guia do evento Que você recebeu por e-mail também é importante que você entre no grupo do
WhatsApp exclusivo para particip parantes do nlw para não perder nada e participar dos sorteios e brindes e garantir o seu certificado e muito mais então agora bora pro código bora codar Fala Dev Bora lá pra nossa primeira aula aqui do nlw Pocket JavaScript e o que a gente vai fazer nessa primeira aula é começar construindo o backend na nossa aplicação Lembrando que a gente vai Estar construindo ao longo dessas três aulas uma aplicação full stack tanto com node no backend quanto react no front end a gente vai fazer toda a integração desses dois projetos ou
seja um projetinho completo aí para você colocar no seu portfólio caso você não saiba ainda essa aqui é a aplicação que a gente vai est desenvolvendo Lembrando que esse layout Aqui você encontra também aqui nos materiais do nlw para você baixar acessar e configurar Customizar da maneira que você quiser até utilizar esses assets Quem sabe em outros projetos vai ser um projeto bem completinho aqui que a gente vai est desenvolvendo ao longo desses três dias o inorbit que que ele vai fazer ele é basicamente um projeto de controle de metas pessoais então A ideia é
que você Abra o aplicativo e nesse primeiro momento ele vai mostrar que você não tem nenhuma meta cadastrada Quando você clicar em cadastrar meta você vai e ter Acesso a essa parte aqui onde você vai indicar Qual atividade né qual meta você quer cumprir e quantas vezes na semana você quer cumprir essa atividade e quanto mais vezes você selecionar aqui Claro mais vezes depois você vai ter que cumprir essa meta na semana para atingir o seu objetivo de 100% aqui ah e aqui como você pode ver vai ter uma visualização de semana então ele vai
mostrar olha da semana de 5 a 12 de Agosto ah Você completou tantas metas né E aqui claro eu separei tanto a visualização de quando você não tem nenhuma meta completa veja quando você não tem nenhuma eh isso quando você não completou nenhuma meta aqui em cima vai aparecer quais metas Você Tem que completar então por exemplo meditar praticar exercício acordar cedo e aí clicando aqui já vai eh registrar que Você completou aquela meta e aqui tem o exemplo da tela Ahã com metas né completas e aqui veja Que ele anota certinho qual meta Você
completou Qual o horário e as metas que você já completou o número máximo né que são ah por exemplo se uma meta que você falou que quer completar ela uma vez na semana eh por exemplo acordar cedo né que nesse caso completou Duas né então vamos supor que você selecionou duas vezes na semana aí veja que você já completou ontem e hoje então não precisa completar mais então ela fica apagadinha e assim é esse percentual essa barra de Progresso aqui é totalmente correlacionada com o número de vezes que você tem que completar as metas eh
vezes quantas metas Você completou Então por mais que pareça uma aplicação simples né não se deixe enganar Porque por mais que sejam poucos recursos gerenciados né poucas tabelas do banco de dados vão ser algumas regras de negócio aqui bem interessantes tá porque a gente vai ter que fazer algumas validações e algumas coisas de performance aqui algumas eh Otimizações de performance bem interessantes e eu tenho certeza que a gente vai ah escrever algumas queries no banco de dados aí que você talvez nunca tenha escrito ah dependendo aí do seu conhecimento com SQL tá então esse nlw
aqui eu resolvi trazer um projeto que ele é bem focado é em duas coisas no backend ele vai ser muito focado em SQL muito focado em trabalhar com banco de dados falar sobre joins falar sobre Ah cara sobre CTS né que são as comon Table expressions tem muita coisa que a gente vai fazer aqui que é que é que é legal a gente que eu é legal eu frisar tá e já no front end o nosso foco vai ser menos na estilização menos no CSS por isso até boa parte do CSS eu vou te entregar
pronto pra gente perder menos tempo com isso até porque tem muito conteúdo aqui na Rocket sobre CSS a maioria dos nlw também antigos foram bem focados em CSS nesse aqui a gente vai dar um pouquinho mais de foco na parte De fet de dados e formulários tá então a gente vai dar um pouquinho mais de foco na parte de como que a gente faz eh de uma maneira mais profissional esse consumo do nosso backend né da nossa api dentro do nosso frontend escrito com react veja que ele é um projeto bem completinho né aqui do
lado também eu já deixei todos os estados de foco Fed Hover né então tem todas as variações possíveis né as variantes possíveis aqui de cada um desses Elementos né ah quando o usuário dá um Tab e tudo mais então é um projetinho bem legal para você usar como base aí para criar um projeto no seu portfólio bem interessante tá esse aqui é um projeto bem completo mesmo que tenho certeza que se algum dia claro você dando uma customiz diferenciando ele um pouco dos demais né porque muita gente tá participando aqui do nlw eu tenho certeza
que isso aqui é um projeto incrível para um dia o recrutador olhar No seu no portfólio e falar cara que projetinho bem feito assim porque você vai ver o quanto a gente vai dar atenção a detalhes como eu falei ali no backend mais focado um pouquinho pro skl no Fronte um pouco mais focado pra data pra parte data fetching e pra parte de formulário que é o caso que a gente tem aqui para cadastrar meta tá com validação e tudo mais vamos lá né Já tô aqui no meu terminal e claro para a gente eh
trabalhar nessa aplicação a Gente vai precisar do node instalado tá veja que o node ele tá atualmente na versão LTS 20.16 recomendo que você instale sempre a versão LTS tá se eu for aqui no meu terminal você vai ver que eu tô usando a 22.6 que é a última porque eu tava testando porque agora o node tem um suporte ali parte de typescript e tudo mais mas eu vou junto com você instalar aqui a LTS pra gente usar juntos a versão LTS veja que eu instalei aqui o Node de uma maneira diferente né usando o
n aqui o n ele nada mais é do que um version Management version Manager né que é basicamente uma aplicação que permite você ter várias versões de uma de um como por exemplo do node né De uma biblioteca dentro do seu computador mas eu não recomendo isso se você é iniciante no node tá se você tá chegando agora nesse mundo recomendo que você instale dele ele de uma maneira mais simples e aí lá pelo site do node se Você vier aqui em package managers tá vendo aqui embaixo você vai ter a opção em cada sistema
operacional tem várias opções de package Manager que são ah gerenciadores de pacotes né que são instaladores né ferramentas que você tem no seu sistema operacional que facilitam o processo de instalação de ferramentas terceiras para você não instalar daquela forma como geralmente a gente tem no Windows né next next next E aí a gente não sabe onde que foi instalado depois Para remover não sabe mais para atualizar é muito difícil então recomendo sempre você utilizar um package Manager mas se você tá aqui só para ver no que que vai dar também você pode instalar o node
só baixando aqui dando next next next não é o que eu mais recomendo mas tudo bem se você só tá aqui para eh criar esse projeto e depois nunca mais vai quer ver um node na sua frente Ah mas vamos lá né agora com o node instalado veja já tô aqui na versão 20.16 a gente vai criar o nosso projeto eu já selecionei uma pastinha aqui eu gosto de manter todos os projetos dentro da pasta Rot aqui do meu usuário né E aí www E aí dentro de www eu tenho todos os meus projetos eu
separo por por evento né e tudo mais e aí eu criei uma pastinha aqui ó Pocket JavaScript e aulas veja que é uma pasta vazia e aí vou começar criando aqui o meu backend eu vou chamar ele de server já vou abrir inclusive ele no meu vest code ã E aí Abro o terminal do vest code aqui você pode vir aqui em terminal New terminal aqui ou usar a Hot Key eu não lembro qual que é a Hot Key pro padrão no meu computador aqui é control aspas né ou control acento grave e aí eu
vou executar npm init - Y Isso aqui vai fazer simplesmente a criação do package P json que é o arquivo principal que toda a aplicação JavaScript tem esse arquivo ele guarda basicamente informações cruciais do meu projeto como Versão Qual que é o arquivo principal mas mais importante ele grava Quais são as dependências dependências essas que a gente vai instalar no nosso projeto que são por exemplo frameworks ou ferramentas de terceiros né que a gente vai estar utilizando Com certeza se você veio lá do PHP tem o composer se você veio lá do rails tem o
Jam né as Ruby jams se você veio lá do Python tem o PIP se você veio ah do Java Tem sei lá já não lembro mais mas é muita coisa mas vamos lá eu vou instalar aqui a primeiraa dependência PR a gente visualizar que é por exemplo o typescript que a gente vai estar utilizando aqui eu vou instalar ele como uma dependência de desenvolvimento veja eu boto menos D maiúsculo aqui no final e feito isso ó quando eu instalo ele já aparece aqui ó Dev dependencies que é uma dependência de desenvolvimento typescript e a versão
mais atual Ah e Veja que dev dependen são as dependências que quando eu colocar o meu projeto em produção elas não serão necessárias por o typescript antes de eu colocar o meu projeto em produção como o node ele não entende typescript eu vou converter todo o meu código para jav SC ou seja essa dependência que ela não será útil em produção porque lá o meu código já vai estar em JavaScript com o typescript instalado eu posso executar o npx tsc que que é o npx npx ele vem Instalado quando você instala o node e ele
é basicamente um atalho pra gente executar scripts de bibliotecas instaladas então quando eu escrevo npx é a mesma coisa que eu executar um script que esteja dentro da pasta node modules pbin veja que eu tenho dois scripts que vieram instalados aqui com typescript o tsc e o TS server eu tô executando o tsc E aí eu rodo traço traço init e veja que ele vai criar para mim um arquivo tsconfig.js aqui na raiz do meu projeto E aí que que eu vou mexer nesse projeto não sei o que eu mexer Geralmente eu também não sei
tá é muito nome muita coisa aqui eu cara assim Eu Não Faço menor ideia do que metade dessas dessas configurações fazem que que eu que que eu faço procuro por TS config bases no Google venho nesse repositório da Microsoft que é a mantenedora do typescript certo aqui embaixo procuro pela versão do node que eu tô usando ó node 20 clico nesse carinha aqui ó @ Tsconfig bar node2 venho aqui embaixo copio essa estrutura aqui de test config colo aqui dentro ó Tiro tudo e colo o que ele vem ali e pronto não mexe mais nada
posso até fechar isso aqui e typescript configurado e aí como eu falei o node por padrão ele não entende typescript então a gente instalou o typescript aqui para que o nosso editor né começa a entender que isso aqui é um projeto typescript e tudo mais evite que a gente e Cometa alguns erros ali de Tipagem né né para quem tá vendo de linguagens ah como c e linguagens da família C csharp ah Java já tá muito acostumado com tipagem né até PHP Mais atualmente Ah mas basicamente a tipagem evita né que a gente Cometa erros
durante o desenvolvimento do seu do nosso código que podem ser ah erros muito pesados quando a gente colocar o nosso código em produção né E aí eu vou instalar aqui mais ã uma mais duas bibliotecas primeira delas é o types bar Node que que é esse carinha ele basicamente traz a integração do types scp com o node né senão a gente não vai conseguir utilizar no nosso projeto ah variáveis e bibliotecas globais do node né Então dessa forma a gente tá indicando que isso aqui é um projeto node tá e não um projeto por exemplo
JavaScript qualquer para o front end e eu vou instalar também uma outra biblioteca que é o tsx uma biblioteca incrível vou botar as duas com menos D Tá que são dependências de desenvolvimento o tsx ele vai permitir a gente executar o nosso projeto sem precisar convertê-lo antes para JavaScript Lembra que eu falei que o node não entende código JavaScript então o tsx ele vai fazer o processo de converter o código de typescript para JavaScript e já fazer a execução desse código e isso vai ficar imperceptível pra gente que que tá como deve aqui né E
aí eu vou criar uma pastinha search aqui Dentro vou criar um arquivo chamado ã vou criar uma pastinha http e dentro um arquivo server.ts que é onde vai est o meu código node vou executar aqui simplesmente um console log hello world deixa eu dar um pouquinho de zoom aqui dentro e aí agora aqui dentro de scripts eu vou criar um script chamado Dev e no conteúdo desse script eu vou executar tsx e passo o caminho do meu projeto search bar http bar server.ts se eu executo agora npm Run veja que ele vai Mostrar Hello Word
que é o que eu tenho exatamente aqui dentro só que nós vamos passar uma outra Flag zinha aqui que é o Watch Isso aqui vai fazer o seguinte quando eu executar o meu servidor veja que agora ele não parou de executar ele vai ficar observando qualquer alteração que eu fiz no arquivo e ele reinicia sozinho o servidor assim que eu salvo esse arquivo isso é bem legal E aí se eu quero parar a execução basta eu vir aqui e dar um CRL C tá ó pronto e ele já Parou de executar aqui o meu arquivo
feito isso a gente vai configurar agora a outra ferramenta que a gente vai estar usando aqui que é o ffy eu vou instalar o fast fy e esse eu não vou instalar como dependência de desenvolvimento não vou colocar o menos d o fast F vai ser o Framework que a gente vai estar utilizando aqui mesma coisa se você veio de outra linguagem cada linguagem tem os seus frameworks web né Eu acho que tirando go aí que é uma linguagem que Geralmente o pessoal instala um pouco menos de de frameworks né mas lá no Python tem
o fast api tem o Jungle tem o flask Ah no PHP tem muitos também né a gente tem o cod igniter cake PHP laravel tem o Lumen tem muitos né no Ruby a gente tem basicamente ril Sinatra ah ou seja cada linguagem tem os seus frameworks aqui no node não é diferente a gente tem Express ffy nest hã Happy bom tem vários mas o fast fy hoje para mim é um dos mais incríveis que a gente Tem um dos mais rápidos né aí já tem o próprio nome dele Fast fy né já tem o nome
de um Framework rápido e e realmente é né então o que que eu vou fazer aqui no meu server eu vou começar a importando Fast fy de dentro de fast fy vejo que ele já trouxe aqui a importação para mim eu vou criar a minha aplicação usando app igual a Fast fy E aí eu vou ouvir uma porta né então como eu posso ter várias aplicações rodando na minha máquina ao mesmo tempo cada Aplicação vai estar rodando uma porta diferente Então uso app. Listen passa uma porta por exemplo 33 33 e aí como isso aqui
retorna uma Promise ó veja passo o mouse por cima ele retorna uma Promise que no JavaScript é basicamente a e uma Promise é indica que eu vou ter algo que pode demorar um pouquinho para executar então eu vou esperar isso aqui executar com o ponto then E aí executar uma função e aí veja que a minha fonte aqui ó ela tá unindo aqui porque eu Tenho uma opção de Font ligatures habilitada deixa eu desabilitar essa opção para não te confundir ó é basicamente um igual e uma flechinha e eu vou botar um console log aqui
dentro escrito http server Running E aí salvo aqui agora e veja que quando eu executar o meu servidor aqui ele vai mostrar http server Running e eu já tenho o meu servidor rodando a porta 3333 tanto que se eu vier no meu navegador Abrir local roch 3333 veja que o erro que ele vai Dar é de Rota não encontrada e não um erro dizendo que meu servidor tá offline ou qualquer ou qualquer erro normal do navegador tanto que se eu vier aqui ó e parar a execução do meu servidor dar um F5 esse aqui é
o erro quando eu não tenho o servidor rodando certo agora se o meu servidor tá rodando e eu dou F5 ó veja que é rota não encontrada por quê Porque Claro a gente ainda não criou rotas na nossa aplicação que é o que a gente vai fazer daqui a pouco tá mas a Gente tem várias outras coisas para fazer Ah aqui pra frente tá porque a gente vai utilizar um leque de bibliotecas e ferramentas e ainda tem configuração de banco de dados que a gente precisa fazer antes de sair criando as rotas da nossa aplicação
que vão permitir a gente gerenciar os recursos aqui né Como cadastrar meta listar né o resumo das metas as metas pendentes ah cadastrar aqui que eu completei uma meta Então são várias Funcionalidades que a gente vai ter que trazer pra nossa aplicação Mas eu ainda preciso eh criar uma estrutura um pouquinho melhor antes da gente partir outra coisa que eu vou fazer aqui agora é a configuração de uma ferramenta que eu tô utilizando muito ultimamente que é o biome o biome caso você não conheça ele é basicamente um projetinho que é concorrente do es lint
que ele faz a o voltando aqui fui ver porque que meu cachorro tava latindo ali mas era só Correios o biome ele é uma ferramenta concorrente do S lint que é muito famosa aqui na comunidade JavaScript ele permite que a gente faça formatação né e linting do código isso é basicamente uma forma de padronizar o código quando várias pessoas estão mexendo no projeto Mas ele também ajuda a gente durante o desenvolvimento porque eh eu não preciso me preocupar em escrever o código digamos da maneira mais bonita é só eu salvar o arquivo ele já organiza
o Código para mim isso basicamente é uma ferramenta de formatação eu sei que no Python quando eu programei em Python tinha lá né acho que era o black formater que tinha lá bom tinha várias opções né ah geralmente cada linguagem também tem a sua né que ele dá um exemplo ó de código e como que fica no final Olha só ele formata tudo certinho e ele é muito rápido né uma ferramenta baseada em rest aí e a gente vai instalar ela ah copiando aqui ó npm Install menos d ah vamos rodar Esse comando aqui dentro
do nosso servidor tá E aí a gente precisa criar uma configuração do do biome tá senão ele vai usar uma configuração ah própria dele e aí o que que eu vou fazer Tá eu vou criar um arquivo aqui na raiz chamado biome P Jon veja que ele já ficou com o iconeinstagram furações do vest code você encontra no meu github só entrar em github.com / Diego 3G você vai ter aqui Ó vest code settings todas elas estão aqui tá Ah e aí que que eu vou fazer nesse arquivo b.jon eu vou botar as configurações que
eu uso pessoalmente e eu vou te deixar elas aqui no material que do do nlw caso você queira copiar as mesmas configurações tá então vou dar um cont contrl V aqui ó veja essas aqui são as minhas configurações você pode mexer nelas como você quiser também tá E aí o que que a gente precisa fazer aqui agora eu vou dar um contrl shift P venho em ã Settings n essa opção aqui eu procuro por preferences E aí eu venho nessa opção aqui ó preferences Open workspace settings isso aqui basicamente é uma forma de eu configurar
eh algumas ã ajustes aqui do do vest code apenas para esse projeto e não pros demais então vê ó Open workspace veja que ele vai est vazio porque não é minha S ó ele vai até criar um arquivo novo aqui em pon vscode bar settings tá E aí aqui dentro ah que que eu vou colocar eu vou Basicamente colocar a seguinte opção ó editor pon Format on save vou passar true tá E aí eu vou passar uma Flag Zinha que é o seguinte editor.on default Format e eu passo biome JS biome tá vendo Então agora
eu tô indicando que dentro desse projeto toda ve que eu salvar um arquivo eu quero que ele faça a correção daquele arquivo a formatação e o Format padrão vai ser o biome tá E aí eu preciso por último instalar a extensão do biome caso Você ainda não tenha instalada dentro do seu vest code é só procurar aqui por biome instala ela e aí Claro pra gente garantir que tudo vai funcionar eu vou dar um Reload aqui no vest code ou você pode fechar e abrir ele de novo tá e pronto veja que agora ó salvei
o arquivo ele já arrumou aqui por exemplo trocou aspas duplas por aspas simp que é o que eu tava usando ali dentro já quebrou a linha aqui ó Isso aqui é como tava antes e aqui Claro o arquivo pequeno a gente Não vai perceber ainda muitas mudanças mais mais pra frente isso vai ajudar a gente bastante Principalmente quando a gente tiver escrevendo códigos maiores tá agora com o bium já configurada a última coisa que a gente vai configurar é a parte de banco de dados e aqui a gente vai estar utilizando o postgress dentro da
nossa máquina ah e para usar o post aqui dentro a gente vai precisar rodar esse de alguma forma tá E aí vamos lá existem Muitas formas de você rodar o banco de dados dentro da sua máquina eh aqui deixa eu até o que acontece né a gente poderia aqui utilizar um banco de dados que a gente não não precisasse instalar nada como por exemplo um skite e tudo mais mas no final das contas se a sua aplicação quando ela tiver em produção né quando você for hospedar sua aplicação fazer o Deploy dela o banco não
for eslite não vale a pena Desenvolver a sua aplicação usando eslite já vale a pena desenvolver ela usando post porque os bancos de dados Eles são diferentes tem sintaxes diferentes muitas vezes para o que você for escrever e aí tem várias formas de rodar o poquis tá o que eu mais recomendo é você rodar o poquis usando o docker só que eu sei que algumas pessoas têm dificuldade de instalar o docker Principalmente quando tão no Windows porque Windows tem um sistema de Virtualização lá diferente E aí se você nunca utilizou assim eu recomendo você tentar
pelo menos instalar o docker uma vez aí na sua máquina tá então você pode procurar por docker desktop E aí você vem nessa opção aqui docker desktop E aí você instala ela veja que ele já trouxe aqui pro meu Mac né mas tem para Windows tem para Linux também e depois Teoricamente se você conseguir instalar o docker tudo certinho na sua máquina você vai conseguir vir aqui no seu Terminal e escrever docker PS por exemplo e ele vai mostrar isso aqui ó o docker menos v e vai mostrar a versão do docker tá caso você
você não consiga usar o docker tá assim não deu para instalar assim deu muito problema ou qualquer coisa assim recomendo que você use um banco de dados online mas caso somente se você não conseguir instalar o docker local e vai por mim se você quer trabalhar com programação ou se se você já trabalha com programação envolvendo Backend Você vai precisar o docker Em algum momento A grande maioria matadora de empresas usa docker no seu dia a dia tá então caso você não consiga ter instalar docker na sua máquina você pode vir aqui procurar por neon
ptec acho que ele vai tá logado na minha na minha conta aqui deixa eu deslogar na minha conta o neon ele é uma ferramenta que te permite hospedar um banco de dados postgis online e ele tem um plano de zero por mês aqui que você pode ter um Banco de dados de até 500 MB tá Então nesse caso você não conseguiu instalar o docker crie aqui a sua conta no neon É bem intuitivo E aí você já vai criar um banco de dados ali dentro Eu vou até te mostrar o processo aqui ó deixa eu
logar numa das minhas contas que eu tenho aqui dentro Ó depois que você logar aqui ó você vai vir aqui em new Project você vai dar um nome para ele você cria aqui por exemplo nlw Pocket né E aí você bota aqui o mínimo que tiver pode deixar essa Opção aqui de suspender depois 5 minutos sem uso você dá um Create e pronto ele já vai te dar aqui ó a URL de conexão com o banco é isso aqui basicamente o que a gente vai precisar tá E aí você pode vir aqui ó e dar
um copy snippet Isso aqui vai ter a URL de conexão e pronto aí você já vai ter um banco de dados para utilizar mas eu vou usar o docker aqui local e aí para usar o docker eu vou criar um arquivo aqui na nossa na nossa pasta no nosso projeto Que se chama docker compose pimel que que esse projeto faz tá ele basicamente vai descrever Quais são os serviços né que a gente vai precisar nesta aplicação então é normal que às vezes uma aplicação backend ela tenha postc tenha Rides tenha vários bancos de dados diferentes
tenha sistema de fila tenha muita coisa e cada uma dessas coisas é um serviço que vai virar um contêiner dentro do docker né o docker ele basicamente separa cada pedacinho que a Nossa aplicação precisa como post re ou qualquer outro serviço que ela existe em containers containers são digamos mini sisteminha das vezes e aí eu vou começar fazendo o seguinte vou dar um nome pro meu projeto vou chamar aqui de Pocket JS server que é o meu backend e vou declarar aqui os meus serviços meu primeiro serviço é o post vou chamar ele aqui de
PG por exemplo posso dar o nome que eu quiser tá E aí eu falo primeiramente Qual que é a imagem que eu Vou est utilizando então aqui imagem né se você entrar no docker Hub aqui é basicamente um repositório como github ah de imagens públicas que são digamos serviços comuns né que a gente precisa Então veja que aqui tem muita coisa né tensor Flow ali pra parte de machine learning olama pra parte banco PR parte de ai né ah tem aqui o vitz Né que é um de banco de dados de sharding para mysle tem
serviços de banco de dados como por exemplo post veja que inclusive é a Terceira imagem mais baixada só perdendo para de nex e Python Ah aqui my Nel forj mongo ou seja várias ferramentas que a gente pode rodar na nossa máquina atavés do docker aqui a imagem que eu vou utilizar é a imagem da batname bar postgis Ah postgis SQL né então eu vejo que é postgre SQL tá E aqui eu posso definir a versão se eu procurar aqui no Opa tô no lugar errado docker Hub bitnami post SQL eu posso clicar aqui venho em
tags vejo Qual que é a versão Mais atual Então a gente tem aqui a tag ó versão 13.16 eu vou fixar Nessa versão tá não é legal a gente colocar aqui versão latest por exemplo ou deixar sem versão porque vai que no futuro né alguém instale esse projeto E aí o banco de dados esteja numa versão diferente não funcione né então é legal a gente fixar sempre com a versão atual E aí eu vou aqui fazer um redirecionamento de portas eu vou basicamente falar que eu quero redirecionar a porta 5432 do contêiner ou seja do
posts né né pra porta 5432 da minha máquina isso vai permitir que eu acesse essa porta 5432 que é a porta padrão do banco de dados postgis né E aí eu vou passar também algumas variáveis ambiente aqui que são as credenciais pro meu banco de dados primeiro postgress user que é qual o usuário que eu quero pro meu banco de dados Vou botar aqui docker post password que eu também vou botar docker e por último postgress DB que é Qual o Nome do banco de dados vou chamar ele aqui de ah in ah Orbit tudo
junto tá sem pontos nem nada vou salvar aqui agora venho na minha pasta e rodo docer compose up men D Isso aqui vai fazer o processo de rodar o meu banco de dados veja ele vai baixar a imagem aqui do bitnami postc tá E vai rodar ela aqui localmente a gente só Aguarda um pouquinho pronto veja aqui agora se eu Rod um docker pass meu banco tá rodando caso o seu banco não esteja aqui rodando Uma das coisas que você pode fazer também eh rodar o docker PS - a procurar o seu contêiner aqui dentro
então eu tenho muitos aqui então Ó ele tá aqui esse aqui é o meu é o primeiro aqui é o meu contêiner ó e aí eu posso pegar o ID dele e rodar um docker logs para ver qual que é o log dele vejo que o meu último log aqui é Database system is ready to accept connections Mas pode ser que o seu log seja de algum erro aqui Falando que você fez alguma configuração errada nesse caso não é né E aí com o banco de dados rodando a gente vai instalar aqui a ferramenta que
a gente a gente vai estar utilizando para eh eh fazer as requisições pro meu banco de dados fazer as queries e tudo mais que é o drizzle ORM E aí eu vou instalar aqui drizzle ORM e vou instalar também uma outra biblioteca aqui vamos só aguardar um pouquinho enquanto ele faz a instalação Mas caso você não saiba o que que é o drizzle ele é um ORM né um Object relational mapping Apesar de ele não fazer exatamente isso mas esse nome ficou bem famoso então todo mundo coloca é ORM né Mas que que é um
ORM né se você veio lá do PHP por exemplo você deve conhecer que lá o laravel tem o eloquent Ah no ros tem o Active Record ah cada ferramenta tem uma uma ferramenta mais famosa para trabalhar com banco de dados e que o que que eu quero dizer com Trabalhar com banco de dados é que quando eu tenho um banco de dados tudo que eu for fazer no banco de dados não são só queries né não são só insert select updates ou deletes Ah no banco de dados eu tenho que por exemplo também gerenciar Quais
são as tabelas que eu tenho no meu banco né as colunas índices hã e geralmente isso é um trabalho chato de fazer Principalmente quando eu tenho várias pessoas trabalhando no mesmo projeto então uma estratégia bem comum Que a gente que todos os frameworks na na web né todos os frameworks backend resolvem da mesma forma é utilizar migrations né migrations são basicamente arquivos que da controlam a linha do tempo do nosso banco de dados cada migration ela diz o que que aconteceu com o nosso banco de dados por exemplo uma coluna nova uma tabela nova ou
uma coluna foi removida Ah e assim quando uma pessoa pegar o nosso projeto ela executa um script ali Que faz uma varredura nesses arquivos de migrations né nessa linha do tempo e ajusta o banco de dados dela automaticamente e isso não vai ser diferente aqui no nosso projeto eu vou instalar aqui o drizzle kit também mas nesse caso vou instalar com uma dependência de desenvolvimento Então são duas dependências drizzle ORM que a gente vai usar em produção e drizzle Kit que vai ser usado somente em desenvolvimento e aí com isso eu já vou Inicializar o
meu projeto Se eu vir aqui em drizzle kit vier aqui na opção ah de overview a gente vai ver ah que ele pede pra gente começar criando um arquivo aqui na raiz do nosso projeto chamado drizzle [Música] pc.tem os meus arquivos de migrations que é esses arquivos que definem a linha do tempo do meu banco de dados E aí eu vou basicamente falar que o seguinte aqui na raiz eu quero criar uma pasta tá Chamada ponto migrations por ponto migrations assim ela vai ficar lá em cima no topo de tudo tá aqui no dialect tem
qual que é o qual banco de dados que eu tô usando se é my si ou eslite ou postgis né No meu caso é postgis Ah aqui migrations a gente pode apagar tá e eu vou criar aqui uma opção chamada DB credentials e aqui eu vou passar o RL Qual que é o RL do meu banco lembra que lá quando a gente configurou o banco no neon caso você Tenha utilizado neon né você copiou o URL lá dentro é aqui que vai essa URL agora mas a gente tá usando docker com P então a minha
URL ela vai ser mais ou menos ah postgress ah aqui não é post postgress SQL do P bar Barra docker que é meu usuário ah dois pontos docker que é minha senha @localhost ã que é o meu host né aqui 2.54 32 que é a porta barra inorbit que é o nome do do banco de dados que a gente tinha colocado né isso in Orbit né Então Esso aqui já é a minha url de conexão só que geralmente não é legal a gente colocar URL direto assim no código por quê Porque quando o meu projeto
estiver em produção não vai mais ser essa URL né e sim vai ser outra e por isso a gente usa geralmente variáveis de ambiente neste caso por isso vou criar um arquivo chamado ponto env aqui dentro que é um arquivo para variáveis ambiente declaro aqui a minha variável ambiente vou chamar ela de Database URL colo ali Dentro Cuidado para tirar aqui ó ficou duas aspas repetidas assim ó pronto salvo isso aqui agora e aí que que eu vou fazer é lá no meu à no meu package P json aqui ó ã eu vou passar aqui
no tsx ã uma Flag Zinha chamada traço traço env traço file e eu passo ponto env isso aqui eu tô basicamente falando para ele carregar esse arquivo ponto env aqui ah com as minhas variáveis ambiente Isso aqui é uma Flag do node tá hoje em dia o node Já suporta se a gente procurar aqui node Men H A gente vai ver que ele suporta aqui ó esta opção ah aqui em cima ó env file que tem as minhas o passando Quais são os arquivos Ah o arquivo que tem as variáveis ambiente do meu projeto né
ah perfeito e agora então a gente vai utilizar aqui no lugar da URL ah process que é onde vem e as variáveis ambiente do note pon env pon Database URL veja que ele já Reconhece automaticamente aqui dentro só Que veja que ele tá dando erro né Por quê Porque a minha variável ambiente aqui ela ela pode não existir o arquivo.env pode não existir então o que que eu gosto de fazer em todos os meus projetos JavaScript tá eu gosto de instalar a biblioteca Zod que é uma biblioteca para validação né de dados E aí aqui
no source eu crio um arquivo env.ts tá E aí eu faço o seguinte eu crio uma variável chamada en schema que é igual a z que vende dentro do Zod e Falo o qu as minhas variáveis ambiente né que são as variáveis que tem aqui dentro do ponto env elas precisam ser um objeto dentro eu preciso ter uma Database url que é uma string e é uma url E aí eu exporto uma constante env fazendo o envima ppse no process.env tá E aí deixa eu te explicar o que que tá acontecendo aqui dentro process.env é
onde vem as variáveis ambiente que eu declarei dentro desse ponto env quando eu executo o parse ele basicamente tenta Verificar se este objeto process.env está seguindo esse formato ou seja se dentro do process.env eu tenho uma propriedade Database url que é uma string e que é uma url se não for ele vai dar erro ele vai dar um throw aqui e aí ele já vai falhar aqui a nossa verificação e não permitir que a nossa aplicação Execute lá no drizzle config ao invés de usar agora process.env Database URL eu vou usar envi ou seja veja
ó vou importar lá de search baren Database URL veja que agora ele não dá mais erro por quê Porque esse Arquivo ele vai garantir que essa variável exista se ela não existir ele vai dar erro ele não vai deixar a minha aplicação rodar sem a variável ambiente tá porque eu não tô falando que ela é opcional aqui ó se eu boto que ela é opcional aí eu volto lá no DZ ó tá dando erro porque eu não posso ter uma conexão com o banco de dados né url de conexão com banco de dados opcional isso
aqui é Obrigatório pro meu projeto rodar feito isso agora a gente já tem aqui as configurações necessárias pro nosso projeto rodar ah a última coisa que eu vou fazer é eu vou criar aqui dentro sece uma pastinha chamada DB aqui dentro eu vou criar um esima uma pasta esima e dentro eu vou criar um index.ts aqui nesse index.ts é onde eu vou declarar quais serão as tabelas e colunas que eu vou ter no meu banco de dados por enquanto eu vou agora aqui em Esima falar onde que tá esse meu arquivo então pon bar search
bar DB bar esima ã nem preciso criar uma pasta vou criar direto aqui um dentro do DB criar um esima PTS eu crio aqui esima PTS salvo e pronto meu banco de dados agora tá pronto para receber as minhas tabelas última coisa que eu vou fazer é criar aqui dentro do esquema uma tabela pra gente começar a visualizar como que isso funciona então aqui no drizzle né Cada ORM cada ferramenta ela tem uma forma de A gente declarar Quais são as tabelas que a gente vai ter no banco tá todas as todas essas ferramentas sempre
seguem algum formato diferente por exemplo lá no laravel e no rails a que é o Active Record e o eloquent você utiliza classes né porque eh foram modelos que foram baseados lá no rios e são muito baseados na orientação objeto Então você usa classes Ah no Prisma né que é um RM famoso aqui do node também você vai utilizar uma Sintaxe própria do Prisma aqui no drizzle você vai usar funções que você importa do próprio drizzle Então olha só se eu quero criar uma tabela no banco eu vou importar de dentro de drizzle kit ah
ou melhor drizzle ORM bar eh PG core eu vou importar aqui PG table E aí eu falo o seguinte Olha eu vou ter uma tabela chamada gos veja que eu tô exportando ela daqui de dentro é importante exportar tá ela vai ser uma tabela o nome da tabela vai ser goals e aqui eu Declaro quais Campos quais colunas eu vou ter na tabela por exemplo vou ter uma coluna ID que é um texto e aí eu importo text aqui ó de dentro de PG Core veja que eu tô usando post Então eu preciso importar tudo
dentro de PG core aqui ele fez duas importações separadas Então deixa eu importar aqui ó Text e eu vou ter também um campo do tipo integer e um campo do tipo time stamp Beleza então id e falar que ele é uma chave primária Ó vou ter um campo também título que é a o título da Meta né atividade veja que eu usei o ponto not null para falar que o título ele nunca vai poder ser nulo tá e a gente vai ter também aqui um outro Campo que vai ser o desired weekly Frequency né que
é o número de vezes que eu desejo praticar essa meta na semana veja que o nome da coluna eu deixei ele bem descrito só que quando eu levo essa coluna lá para dentro do banco de dados no banco de Dados eu não gosto de deixar em Camel Case igual tá esse formato tá então eu gosto de usar com Underline o und né que se não me engano é o Kebab Case sei lá já não sei mais mas por isso Ó eu aqui no caso do lado do JavaScript eu gosto de manter C Case mas quando
eu levo pro banco aqui ó aqui dentro é o nome da coluna em si né eu boto desired underline weekly Frequency e falo que aqui também não pode ser nulo né e o tipo é integer por Último vou criar aqui um created at que ele vai guardar a data que essa meta foi criada E aí no banco novamente created e aí eu passo aqui também vírgula opção com with time Zone como sendo true isso aqui quer dizer que quando uma pessoa eh que eu vou guardar essa data no banco de dados com os detalhes de
time Zone né então a o fuso horário assim a gente consegue criar mais facilmente né uma aplicação que ela Pode ser acessada e consumida em qualquer lugar do mundo tá mas vou falar também que esse campo aqui ele não pode ser nulo e vou passar para ele o default não o que que isso aqui vai fazer vai fazer com que quando alguém cadastrar uma nova meta o campo create at seja preenchido automaticamente com a data atual Tá feito isso olha que interessante volto no meu terminal agora vou rodar npx drizzle kit generate e dou um
enter e olha só o que que ele fez ele Criou pra gente automaticamente com dado isso aqui que a gente forneceu para ele um arquivo SQL que tem a instrução paraa criação dessa tabela no banco de dados e ele ainda não criou a tabela Ele criou só a migration tá então se você quiser vir aqui ajustar alguma coisa tudo bem mas se agora eu executar o comando migrate ele vai rodar a migration E aí ele deu erro falando que para se conectar com a banco de dados postgis eu preciso instalar alguma dessas Bibliotecas PG postgis
ou neon Database serverless e tudo mais né a gente ainda não instalou o driver do postgis né e por isso a gente vai instalar postgis aqui no nosso projeto feito isso agora eu vou rodar o migrate e veja que ele já executou Diego Quer dizer então que o meu banco de dados já tem essa tabela sim como é que eu posso visualizar se você executar npx drizzle kit Studio ele vai abrir no seu navegador aqui ó só clicar nesse Link uma Interface para você navegar no seu banco de dados olha só já tenho aqui ele
mostra as tabelas que eu tenho no meu banco aqui na esquerda ó então só tem a tabela de metas e aqui os campos ó ID título a frequência e o created at você pode criar registros aqui de dentro filtrar e tudo mais por isso que é muito legal o drizzle né e dá para configurar o tema né como você bem pode ver o meu tema aqui tá diferente ó então tem vários temas e por aí vai Ah feito isso banco de dados criado tabela de metas criada a gente já pode continuar pra gente continuar aqui
agora então vou parar de executar o drizzle Studio aqui no meu terminal né Você pode executar ele quantas vezes você quiser depois a gente vai executar várias inclusive para ver se tá funcionando né O que a gente for colocar aqui no banco Ah E aí eu vou criar a minha próxima tabela que eu vou ter no banco de dados que ela vai armazenar as conclusões de Meta então tem uma tabela aqui quando usuário cadastrar a meta né e tudo mais né a gente vai listar aqui mas por exemplo essa lista aqui ó de quando usuário
e completou cada meta a gente vai precisar guardar numa outra tabela e e eu vou criar aqui então ela criar uma variável lembrar de exportar aqui tá senão o drizzle não consegue entender que isso aqui é uma tabela ah go completions né acho que é o nome mais fácil de entender ah vai ser uma tabela Também então PG table go underline completions Lembra no banco de dados né tudo o que que tá Entra aqui na função né que tá em stream ó é como que vai ficar no banco de dados aqui é como eu vou
chamar no JavaScript por isso aqui eu faço com Camel Case geralmente aqui dentro ah com ess case com und E aí essa tabela aqui ela vai ter o ID que é um texto que é uma chave primária vai ter o ID da Meta né então toda vez que o Usuário completar uma meta eu preciso saber qual é essa meta que ele completou então aqui eu vou criar aqui um um campo chamado go underline ID que vai referenciar e aí aqui eu passo uma função dessa forma go.id então tô referenciando uma coluna dessa tabela aqui isso
aqui ele vai fazer já a criação pra gente de uma forma né uma chave estrangeira aí do skl E e esse campo ele não pode ser nulo né Não Faz Sentido ter uma completar uma uma meta e A meta não não existir Ah E aí por último vou botar o created at aqui da mesma forma salvo se eu rodar aqui o drizzle kit generate criou uma migration ó e aí veja ó ele cria a tabela e depois ele cria a constraint né que é a for referenciando lá o ID da tabela legal né se eu
rodo aqui o migrate já vai dar tudo certo perfeito última coisa aqui agora né esses ids aqui ó veja que eu criei eles como texto Eu não criei eles como numéricos Geralmente eu acabo não trabalhando com ids numéricos na minha aplicação E aí a gente vai precisar usar esse ID você pode usar ah vários formatos de ID né pode usar o oid Ah seid o Lead tem vários algoritmos tem vídeo no YouTube da Rocket explicando ã as diferenças de formatos de ID para você usar no banco de dados tá mas se você tá começando agora
não se preocupa não é importante ah saber isso Agora Você pode usar até um alto increment ali um ID sequencial mesmo né mas eu gosto também de usar essa biblioteca aqui ó que ela se chama Opa NP instal tô usando Import é paralel e deixa eu ver se tenho aqui ó paralel @ paralel com dois l no começo drive Barra cuid 2 Então vou usar o algoritmo cuid 2 Ele é bem famoso aí em todas as linguagens de programação então ele é um algoritmo de geração de ID únicos Existem muitos tá muitos mesmo E eu
só importo ele aqui ó E aí importo aqui Create ID tá E aí eu vou aqui nos dois Campos de ID aqui eu posso selecionar os dois com contrl D venho no final e passo para eles um default function ó com o dólar na frente tá vendo e aí eu passo uma função e aí eu passo Create ID que é a função que eu importei aqui de dentro e executo então o que que eu tô falando basicamente para quando eu inseri um registro na tabela de goals ou na de GO completions ele vai Preencher o
ID automaticamente executando Esta função são aqui Create ID que cria um ID único aqui usando o algoritmo seu id2 tem vários algoritmos como eu já falei né se eu executar um generate veja que ele não vai criar nenhum arquivo de migration por quê Porque essa geração de ID aqui ela vai acontecer pelo lado do JavaScript e não no banco de dados então a gente não precisa se preocupar eh porque não tem migration Nova nenhuma Aqui nesse caso perfeito agora sim a gente já configurou tudo que a gente precisa para começar a criar aqui as funcionalidades
da nossa aplicação aí quase 40 minutinhos aí explicando E aí uma dúvida pode ter surgido caso você já seja né do ecosistema JavaScript Por que que a gente vai usar o drizzle e não vai usar um outro ORM Como por exemplo o prisma né nesse caso Ah tem dois motivos primeiro porque já tem muito conteúdo de prisma e em todos os vídeos da Rocket City né Tem masterclass completa de prisma lá no nosso YouTube mas também porque você vai perceber que nessa aplicação a gente vai escrever queries no banco de dados que são mais complexas
né que não são tão simples como simplesmente Ah fazer um select wear alguma coisa e coisas simples do SQL não a gente vai escrever umas queries mais complexas e quando a gente começa a escrever queries mais complexas com o prisma não fica tão legal assim tá ele Não tem um suporte tão grande a gente acaba tendo que escrever Ah a query comcell puro né E você vai ver que com drizzle não né mesmo queries mais complexas a gente consegue ah traduzir para uma sintaxe ã do drizzle ali que fique bem fácil de ser entendido e
que a gente não perca as funcionalidades de um RM né coisa que lá com o prisma a gente acaba perdendo um pouco tá ã então agora a gente vai eh com o nosso esquema do banco de dados já criado a Gente vai começar a criar as nossas funcionalidades tem uma última coisa que eu vou fazer aqui que eu gosto de fazer em todo o projeto e eu altamente recomendo você fazer isso também que é criar um seed que que é o seed o seed ele é um arquivo que a gente vai executar quando ah por
exemplo imagina o seguinte né você criou ali um projeto backend E aí você manda para um amigo seu testar esse projeto E aí quando ele vai rodar o projeto não tem nada Cadastrado no banco de dados não tem uma meta ou seja ele abre o projeto tá tudo em branco sabe ele vai ter que cadastrar tudo do zero isso eu não acho tão legal eu acho legal sempre no projeto a gente deixar um seed que ele é um arquivo que ele vai Popular o banco de dados com dados fictícios isso deixa a nossa aplicação mais
mais bonita mais legal de ser utilizada Então vou criar basicamente uma função aqui ó chamada seed função assíncrona e vou Executar ela aqui no final e aí aqui dentro eu vou fazer algumas inserções do banco de dados tá só pra gente ter um banco de dados mais com algumas informações Mas como eu posso executar esse seed várias vezes é legal sempre eu também limpar o meu banco de dados no começo Então veja que eu venho aqui ó vou dar um a wait ã vou usar aqui ah eu não fiz conexão com o banco de dados
Então vou criar aqui aqui ó dentro de DB eu vou criar um Arquivo index onde eu vou criar a conexão ah com banco de dados e aí como é que vai ficar essa conexão com banco de dados eu vou importar de dentro de drizzle ORM bar postgress JS eu vou importar aqui trezel e eu vou importar postgress de dentro de postgress que eu já instalei Ah e eu vou também fazer um Import asterisco skima from P barima que que esse asterisco S skima Faz como esse meu arquivo skima ele tem várias exportações e não uma
só veja tem um Export aqui um Export aqui mais pra frente a gente pode ter vários ele vai pegar todas as exportações e jogar dentro uma única variável esima que vai ter todas elas e aqui embaixo eu vou dar um Export const o client é igual a post passando a minha RL de conexão então vou pegar lá meu env que tá aqui ó pon P barv Cuidado para importar do local certo que é o meu arquivo que eu criei Aqui ó ponto Database URL e por último eu vou exportar uma constante DB que é igual
a drizzle passando meu client e passando aqui um objeto de configuração e dentro eu passo skima e aí outra coisa que é legal que você pode fazer aqui também é passar loger dois pontos Deixa eu lembrar como é que passo aqui logger acho que é só true mesmo e aí que que isso aqui vai fazer ele vai dar Log Em todas as queries que a gente fizer no banco de dados a gente vai conseguir ver elas no no terminal aqui bem legal então volto aqui no seed e agora vou fazer o seguinte ó DB importo
aqui ó ponto delete e eu passo o nome da tabela go completions por exemplo o quero apagar todas as metas completas e também quero apagar todas as metas né então vou apagar as duas tem que ser nessa ordem Porque como a go completions Ela depende do go ID se eu apagar primeiro as metas Vai dar erro de chave estrangeira né porque eu não coloquei Cascade aqui e tudo mais mas e é isso não vou entrar muito no mérito porque também se você não sabe muito sobre SQL não vale a pena muito a gente falar sobre
isso agora e aí eu vou fazer algumas inserções aqui no banco de dados tá então Olha só eu vou pegar o meu banco de dados vou fazer um insert na tabela goals E aí values passo um Array com alguns valores que eu vou inserir Por exemplo vou inserir uma meta veja que é tudo integrado ao typescript né então dou um control espaço ele traz aqui ó todas as colunas que eu tenho no banco de dados as colunas que não são opcionais elas não têm o ponto de interrogação então eu sei que eu preciso informar elas
então por exemplo vou criar uma meta ã de acordar cedo e aí eu vou passar aqui o desired weekly Frequency que é quantas vezes eu quero completar isso aqui na semana vou passar Lá cinco vou criar uma outra meta aqui ah de me exercitar né e eu vou botar aqui três vezes por semana e vou criar uma última aqui de meditar vou criar pelo menos botar uma vez na semana aí e aí se eu salvo isso aqui agora e eu executo esse arquivo como é que eu vou como é que eu posso executar esse arquivo
aqui da mesma forma que eu executei o meu server Então posso criar aqui uma outra instrução aqui ó vou chamar ela de seed E eu vou executar tsx passo aqui o env file.env igual não vou passar o Watch porque agora não quero ficar observando quero executar ele uma apenas uma única vez src bar Ah DB bar seed PTS salvo npm Run seed dou enter veja que ele mostrou aqui ó o insert acontecendo ó os deletes e depois o insert aqui ele não parou de executar por quê Porque como eu não fechei a conexão com o
banco de dados ele fica digamos aguardando novas coisas acontecerem então aqui no eu vou fazer o Seguinte ó ponto finally que é basicamente depois do seed executar Independente se deu certo ou deu erro se eu boto then é só caso tenha dado certo né eu vou executar o que tá aqui dentro no finally é tanto se deu certo Ou se deu errado nesse caso eu vou fechar a conexão como é que eu fecho a conexão eu importo o meu client aqui ó junto com a importação do DB e dou um end salvo vej que agora
quando eu executo ó ele executa e já fecha e aí se eu executar Aqui npx drizzle kit Studio ó abri aqui o meu banco de dados veja que aqui dentro eu já tenho na tabela goals ó as minhas três metas que eu criei isso aqui é legal porque Vai facilitar bastante a gente criar as funcionalidades da nossa aplicação já tendo alguns dados do banco de dados para melhorar Ainda mais eu vou também criar algumas eh completions né dizer que eu completei algumas metas para não também ficar com banco de dados vazio nessa tabela então Vou
fazer um inserto na tabela go completions e posso passar alguns valores aqui da mesma forma que eu passei e aí nesse caso aqui do goals completion eu preciso passar só o ID da meta e posso passar quando que essa meta foi completa para eu pegar o ID da Meta sendo que o ID ele foi gerado aqui na hora que eu fiz o insert eu posso vir aqui no final ó do insert e passar o returning pon returning E aí eu passo dessa forma Isso aqui vai fazer com que O meu insert ele retorne os dados
inseridos E aí eu posso buscar esses dados daqui de dentro Então aqui no result veja que agora eu vou ter um Array né vão ser eu result ele Guarda um arrei com três posições porque eu tô inserindo três registros cada uma dessas posições tem os dados que foram inseridos todos os dados o id o título E por aí vai então por exemplo se eu quero pegar a primeira meta aqui posso botar result 0 ponto ID assim eu vou ter o ID Dessa primeira meta aqui acordar cedo e aí eu vou preencher que ela foi completa
ã hoje por exemplo posso botar New date Ah E aí se eu quero falar que a segunda meta ela foi completa aqui eu botar o id1 agora né para pegar essa segunda meta aqui ela foi completa amanhã eu teria que é é um pouquinho chato aqui controlar datas com o JavaScript por isso quando trabalho com datas Eu sempre gosto de instalar uma Lib de datas tá E nesse caso aqui eu vou instalar o dayjs É uma das libs mais legais de data que a gente tem como é que funciona importo aqui o dayjs e olha
só vou criar aqui uma variável chamada start of Week que eu vou pegar a data atual e vou executar o método start off passando Week que que isso aqui vai fazer ele vai retornar agora esse start of Week vai ser a referência do dia eh do primeiro dia dessa semana então do Domingo digamos o primeiro domingo que antecede o dia de hoje né E aí eu vou para quando eu rodar O seed eu cadastrar de que eu completei meta já nessa semana na semana que eu tô rodando Sid para não ficar tipo uma data muito
antiga e a gente não conseguir visualizar isso então vou falar por exemplo que essa primeira meta aqui eu completei nessa primeira semana mesmo só que esse start of Week ele é do tipo dayjs Então eu preciso converter ele no objeto date do JavaScript aqui ó to date E aí essa segunda meta eu vou falar que eu completei e no começo da semana porém Eu vou adicionar um dia nela Então a add um Day E aí eu converto para uma data então né basicamente eu tô falando que essa meta aqui de cima eu completei no domingo
e essa aqui eu completei na segunda tá dependendo de quando você esteja assistindo essa aula e construindo essa aplicação eh para você talvez eh por exemplo se você tiver assistindo essa aula aqui no domingo né ã vai ficar aqui essa meta que Você completou hoje Mesmo né No domingo e essa aqui amanhã como se você já tivesse completado no futuro né porque eu tô adicionando um dia nela mas não tem problema não vai ser algo muito ruim pr pra aplicação salve isso vou rodar o seed de novo pronto veja que agora ele fez a inserção
aqui no go completions também caso você queira rodar aqui o estúdio você vai visualizar isso também já aqui na tabela de GO completions ó então dia 11 né que é o domingo aqui antes do dia que eu tô Gravando essa aula tô no dia 13 então dia 11 e dia 12 que é a segunda-feira tá perfeito agora sim com tudo pronto a gente vai começar a criar as funcionalidades da nossa aplicação as rotas da nossa aplicação E como eu falei a gente vai trabalhar bastante com skl são quatro principais rotas aqui na nossa aplicação que
a gente vai precisar tá já anota aí a gente vai precisar uma para cadastrar a meta certo vamos precisar uma para Marcar uma meta como concluída vamos precisar uma meta uma meta uma rota que retorne Os dados aqui da minha semana como se fosse um resumo da semana né ou seja quais rotas quais metas eu completei certo e eu vou criar uma outra rota que me retorna quais metas eu ainda não completei né ou melhor que me retorna todas as metas que eu tenho da semana tanto aquelas que eu já completei que aí vão ficar
pagadin aqui né e as metas que eu ainda não completei que vão Ficar um pouquinho mais eh chamativas ali né então são quatro rotas na nossa aplicação E como eu falei não se deixe enganar e por serem apenas quatro rotas porque você vai ver a complexidade e a profundidade que a gente vai nessas rotas vamos lá vamos lá para feature mais simples Ah pra gente começar pelo mais simples antes né aqui em sece eu vou criar uma pastinha chamada functions poderia ser use cases Services ã cada pessoa nomeia de alguma Forma mas são basicamente as
funcionalidades da aplicação Poderia chamar de features também bom você pode dar o nome que você quiser não é isso que vai ser o problema né e eu vou começar criando a minha primeira feature aqui que é Create go tá E aí a gente vai tentar manter aqui a estrutura da nossa aplicação a arquitetura o mais simples possível mas você pode levar isso aqui muito pro próximo nível Inclusive tem vários conteúdos no YouTube da Rocket City Ah e claro nos materiais pagos também mas no YouTube também tem ah falando mais sobre ah Solid arquitetura limpa essas
coisas assim mas assim na grande maioria das vezes Ah você não vai precisar disso tudo tá E aí eu vou começar criando simplesmente uma função chamada Create go aqui dentro e eu vou criar uma interface do typescript aqui falando Quais que são os dados né E aí eu gosto de chamar isso de request poderia ser data ou parms Ah que eu vou precisar receber aqui dentro para criar uma nova meta né e eu vou precisar do título e eu vou prisar a desired weekly Frequency só cuidado para digitar bem certinho né copiar lá talvez do
de dentro aqui do esquema caso você queira né para não se perder depois e a aqui eu vou receber então a minha request que tem esse formato aqui ó Create go request E aí aqui de dentro eu posso buscar né o título e a desired weekly Frequency Posso também fazer uma desestruturação aqui ó pego o título e a desired weekly Frequency dessa forma e assim eu tenho essas duas variáveis separadas E aí o que que eu vou fazer aqui dentro é basicamente criar essa go dentro do meu banco de dados então a parte de criação
de uma nova meta ela é a parte mais simples né então vou pegar o meu banco de dados faço aqui um insert pego o qual que é a tabela então gos importo lá do meu esquema ponto Insert ah ou melhor ponto values e passo aqui um objeto Agora não vou passar um Array porque eu quero inserir um único registro né E aí passa os dados aqui ó title e desired weekly Frequency bem simples né E aí como eu quero retornar essa meta que foi recém criada eu vou botar um ponto returning aqui no final e
olha só que interessante né o insert ele sempre se eu pegar aqui o resultado né ó result certo o resultado dessa inserção a gente passa o mouse em res primeira Coisa que a gente pode perceber ele sempre vai ser um arrei tá vendo que tem esses dois cochet aqui por quê Porque por mais que no insert Eu inseri apenas um registro né Ele sempre vai me retornar uma ar rei porque ele me permite inserir mais de um registro então se eu quero apenas a go inserida que a meta inserida eu tenho que sempre pegar o
result na posição zero tá porém Olha só se eu passo o mouse em cima de GO tá vendo que ele tá do tipo never por Quê Porque por padrão É nos bancos de dados né a inserção ela não retorna os dados inseridos ela retorna ela ela retorna no máximo acho que é o número de registros afetados né assim como o update faz então eu preciso passar o ponto returning aqui no final que ele vai adicionar no final da query returning asterisco né Isso significa que eu quero retornar os dados inseridos se eu passo o mouse
em go Olha só agora já tem todos os dados da meta e aí eu Retorno daqui de dentro eu gosto sempre retornar um objeto ó mesmo que eu esteja retornando uma única informação que é a meta né ao invés de retornar dessa forma aqui ó eu gosto de retornar o objeto com a meta dentro por quê mais pra frente se eu precisar retornar outras coisas além da Meta né eu não preciso mudar a estrutura de dados eu só venho aqui e adiciono a outra coisa certo salvo aqui agora veja o biome já deu uma organizada
aqui no código e agora a gente vai criar Nossa rota então eu vou vir aqui em http vou criar aqui Ah vamos criar dentro server aqui mesmo depois a gente separa em mais arquivos tá vou criar a primeira rota da minha aplicação ela vai ser do tipo post né porque seguindo aí As convenções ah http quando eu quero fazer a criação de um novo recurso Eu uso o método post passo aqui o endereço então aqui eu Qual que é o recurso né Então estou querendo inserir uma nova meta e aí aqui do Lado passo uma
função que vai ser executada quando o usuário acessar esta rota com o método post aqui eu recebo a minha requisição de dentro da requisição eu consigo acessar o corpo da requisição que está dentro de request PB que são os dados enviados né para esta requisição quando é uma requisição do tipo post op Geralmente os dados né que vem de um formulário por exemplo eles são enviados através do corpo da requisição do bar Certo e aí com esse bar aqui em mãos eu quero fazer a chamada da minha função Create go aqui então vou dar um
await ah transformar aqui função uma função assíncrona vou chamar aqui o Create go veja que eu já importo lá de functions e aqui eu tenho o título que eu espero que que dentro do meu bar tenha né então bar p title e o desired weekly Frequency que eu espero que também esteja dentro do meu bari e aí que que acontece aqui ó tá vendo que ele começa a dar alguns erros Aqui porque ele começa a falar que o body ele não sabe de que tipo é esse Body né então quer dizer esse Body ele pode
não não não ter essas informações dentro porque eu não tô fazendo qualquer tipo de validação aqui correto e aí lembra que eu já usei lá no no no no na parte de variáveis ambiente eu já usei o Zod para fazer a validação eu poderia fazer a mesma coisa aqui né eu poderia importar o z aqui do Zod e fazer algo da seguinte forma ah criar aqui um Create Go schema falar que o meu bar ele tem que ser um objeto e dentro eu tenho que ter o título que é uma string e tenho que ter
o desired weekly Frequency que é um número ele é um inteiro ele tem ele vai ser no mínimo um e no máximo sete né que é o máximo de repetições que aquela meta pode ter dentro ah de uma semana correto e aí eu poderia vir aqui e fazer a validação então eu espero que o meu bar aqui ó vou fazer um parse no meu bar e aí veja que agora ó parou de dar todos Os erros porque se eu passo o mouse em cima de bar agora ele sabe exatamente que dentro vai ter esses campos
aqui e como eu tô fazendo parse caso não tenha essas informações ele vai dar erro ele não vai deixar essa linha aqui eh prosseguir tá então se eu salvo aqui agora a gente já pode testar essa nossa rota para ver se ela tá funcionando Existem várias formas da gente testar a nossa api tá existem ah extensões do próprio vest code como por exemplo rest Client Ah o thunder client existem aplicações externas ah como por exemplo insônia Postman hop Scott E por aí vai existem tem também interfaces de linha de comando Como por exemplo o Curl
né que já vem instalado na maioria dos sistemas operacionais ou melhor acho que só os baseados em Unix Ah o http também que é uma opção muito legal mas aqui a gente vai est utilizando o Postman que caso você nunca tenha utilizado ele funciona em todos os sistemas Operacionais você abre ele vai ter uma tela parecida com essa aqui eu vou clicar aqui em cima em workspaces vou criar um novo workspace em branco mesmo e a gente vai dar um nome para ele aqui de nlw Pocket JavaScript vou dar Create aguarda um pouquinho e essa
aqui é a tela inicial começar criando uma Collection que é uma pastinha dou um nome aqui para essa Collection vou chamar ela de goals né de metas e crio a minha primeira requisição Troco o método aqui para post troco o título dela para Create go e a gente vai trocar aqui o endereço local rost 3333 bargs veja que já tá com post venho aqui em Body agora troco aqui para Raw seleciono a opção Jason que é como eu vou enviar o os dados certo envio aqui um objeto vou enviar um título aqui uma nova meta
por exemplo hum nadar né eu poderia ter uma meta de nadar aí uns dois dias pela semana coloco aqui o meu desired weekly Frequency cuida para Escrever bem certinho e agora vou botar aqui um número um uma informação errada Vou botar aqui por exemplo um texto test que não é o que eu espero para esse campo aqui e aí venho no meu servidor rodo aqui o meu servidor com npm Run Dev opa errinho Vamos tentar entender o que que tá acontecendo cannot find modules H server watch acho que eu errei alguma coisa aqui ah esse
watch aqui ó tem que tá aqui tsc watch e depois vem o mvf acho que é isso Aí perfeito legal já tá rodando o servidor volto no Postman dou send veja que ele vai dar erro né Ele fala aqui ó invalid Type né eu esperava um número e Recebi uma string dentro do desired weekly Frequency Claro que ele tá retornando de uma maneira Ainda bem feia né a gente vai arrumar isso no futuro mas veja se eu boto aqui de volta um dois por exemplo que é o correto envio ele já dá certo né dá
um status 200 aqui ã E se eu acessar meu banco de dados eu Vou ver lá tanto que aqui na minha curry ó ele já passou que deu certo ele fez o insert na tabela goals ó Campo id title e desired weekly Frequency com os valores aqui que são esses valores aqui embaixo Então esse aqui foi o id o meu title e o desired weekly Frequency que foram inseridos ali na tabela né Lembrando que esse log aqui aparece porque a gente configurou lá no banco de dados aqui o logger como sendo true né geralmente em
produção a gente tira essa Opção legal finalizamos a primeira rota aqui da nossa aplicação E aí uma coisa que a gente pode ah já padronizar né combinar é que quase toda a rota da nossa aplicação a gente vai precisar de validação como a gente tá fazendo aqui pensando nisso né existe um Plugin do Fast fy que é o fast fy type provider Z tá que ele faz isso de uma maneira mais automatizada pra gente tá vamos fazer o seguinte eu vou vir aqui ah ele não tem o scrip de instalação eu vou copiar aqui O
nome do pacote volto aqui na minha aplicação vou parar de executar o meu projeto instala o FF Type provider Zod e a gente vai fazer a configuração como que ele pede ó a gente vai adicionar esta linha aqui que tem a importação lá no topo do arquivo perfeito copiar essas duas linhas aqui ó e vamos jogar logo abaixo da definição do nosso app tá esse Z Type provider aqui eu nem vou precisar na verdade e agora na minha Rota ao invés de eu passar o esquim do Zod aqui dentro dessa forma eu vou copiar o
esquema veja ó pegar essa parte do Z Object vou remover daqui né cortar digamos assim ah o meu bar aqui agora nem preciso mais fazer isso vou tirar ele daqui também vai continuar dando erro e agora aqui ó antes do a request vou botar mais uma vírgula aqui e aqui ó entre essas duas vírgulas vou botar um objeto dá enter cont control espaço procuro por esima aqui dentro procuro Por Body que é o que eu quero validar dois pontos e dou um Crol V naquilo que a gente tinha copiado ali de dentro ou seja agora
eu consigo enviar o esquema do meu do Zod diretamente aqui dentro dessa opção esima Onde eu consigo validar várias informações ó não só o bar né E aí aqui agora de dentro de request eu posso buscar direta ente ó de dentro do meu bar Olha só se eu pego o request bar dou um cont control espaço aqui ó ah ele na verdade ele não trouxe As informações isso aqui é porque hã request Body deixa eu tentar lembrar Ah claro claro claro porque a gente tem que ah passar aqui ó eu falei que eu não precisava
Mas eu precisava que Z ty provider aqui ó então ponto with Type provider e passo aqui no sinal de menor e maior o Z Type provider se eu não me engano é só isso aqui o Import eu posso mover para Import Type né porque isso aqui é só uma tipagem e agora Teoricamente dentro do meu request Body Eu tenho ali ó o title e o desired weekly Frequency já validados né então eu posso remover isso aqui posso usar short syntax aqui e Pronto né a gente Teoricamente vamos trocar aqui criar uma nova meta por exemplo
não usar o celular ã de noite e aí vamos botar aqui a meta de três dias vamos dar um send aqui e deu erro Claro meu servidor não tá rodando dá um send e pronto veja que agora já deu tudo certo aqui a gente já criou a nossa a nossa meta e agora claro A gente vai criar algumas coisas que são um pouquinho mais difíceis né a gente já fez todas as features mais simples que a gente poderia para esse backend não tem como fugir agora a gente vai criar uma das features mais complexas tá
que é a rota que vai retornar Quais são as metas pendentes da semana tá então ela vai retornar na verdade todas as metas da semana mas o foco são nas metas pendentes porque as metas pendentes são aquelas que o Usuário ainda pode e indicar que ele completou aquela Meta Em determinado dia então vou criar uma nova function aqui que eu vou chamar ela de get Week pending gos tá isso aqui bem simples de entender né eu quero retornar as metas pendentes da semana essa função não vai retornar não vai receber nenhum parâmetro assim como na
Create go né na verdade é diferente da Create go porque ela vai retornar sempre da semana atual perfeito Então eu não preciso receber Qual que é a semana né do um digamos de fora eu sei qual que é a semana atual simplesmente usando um New date aqui pegando a data atual e essa aqui essa rota ela vai exigir bastante da gente ah em algumas coisas do SQL Ah mais aprofundadas mas a gente vai construindo juntos ela devagarzinho e você vai ver como vai ficar pra gente conseguir calcular aqui né E retornar de dentro do nosso
backend essa lista aqui ó que tem Todas as metas certo porém eu preciso retornar também Quais das metas já foram completas né para botar essa opacidade mais baixa Então veja que essa quy de metas pendentes ela tem alguns detalhes que são difíceis Porque pensa assim né primeiro eu tenho que contar primeira coisa né imagina o seguinte imagina que mais PR frente na nossa AP Eu coloco um botão aqui para poder navegar entre as semanas para eu ver se o usuário completou 100% das metas na semana anterior tá Então imagina isso comigo e aí eu vou
lá vejo na semana anterior que ele completou que eu completei 100% das metas tá aí eu volto pra semana atual cadastro uma nova meta por exemplo como eu fiz ali né nadar alguma coisa assim e aí eu volto na semana anterior de novo na semana anterior deveria est 100% ou deveria ter Menos percentual agora que eu criei uma nova meta na minha concepção deveria continuar 100% por quê Porque eu criei uma nova meta a partir da semana atual isso não deveria influenciar as semanas anteriores Então esse aqui é o primeiro detalhe complicado dessa query eu
tenho que levar em conta para retornar essa lista aqui somente as metas criadas a partir da semana atual A partir da semana que eu estou mostrando né Essa essas metas pendentes certo Então veja Esse é o primeiro detalhe segundo como eu preciso retornar aqui né deixar apagadinho com menos opacidade as metas que já foram completas eu preciso também fazer uma contagem de todos os GO completion que a gente criou lá no banco de dados né da tabela go completions para cada uma das metas para ver se elas já foram completadas o número eh total de
vezes que eu esperava que elas fossem na semana para daí eu deixar opacidade Baixa Então veja que não é só retornar as metas e pronto sabe seria muito simples mas aqui a gente não quer que seja simples para resolver isso tem várias formas de fazer o SQL assim como uma linguagem de programação porque o SQL ele é uma linguagem né Já tá no próprio nome ele deixa a gente resolver esses problemas de várias formas eu posso resolver isso usando subqueries eu posso resolver isso usando views materializadas eu posso fazer isso Usando e colunas virtuais né
colunas calculadas eu posso resolver isso ah usando joins apenas ou eu posso resolver isso com uma das coisas que eu mais gosto no SQL mas que tem que ser usadas com cuidado para não gerar problemas de performance que são as common table expressions ou trazendo pra sintasse os comandos with que que que que é isso aqui né with e ou common table expressions permitem a gente escrever E queries auxiliares para serem usadas numa query maior e a ideia é que quando eu utilize comon table expressions eu consiga repartir uma query que ela é muito complexa
porque ela tem vários pedaços várias fases em uma query mais simples dividindo ela em queries menores só que todas elas vão ser executadas ao mesmo tempo numa única instrução ao banco de dados e aqui tem um exemplo certo aqui por exemplo olha só ele quer ã bom aqui eu não vou entrar nesse Exemplo e tal Porque a acho que vai ficar muito fora do nosso contexto a gente não vai conseguir fazer muita correlação acho que fica difícil para entender tá mas eu vou usar essas common table expressions aqui e a gente vai ver como que
isso fica legal tá primeiro como eu falei né Por enquanto a gente não tem aquela navegação entre semanas Então vou pegar a semana atual como é que a gente faz isso vou pegar aqui o ano Atual usando o dayjs Vou importar o DJs aqui ó e vou dar um get ah ou melhor ponto ear só ele já retorna o ano atual tá e eu vou pegar a semana atual veja que se eu der um DJs aqui p Wick ele não tem tá porque isso aí é um Plugin do DJs não sei por que isso é
um plugin Mas tudo bem eu importo aqui ó de plugin Week of ear e importo aqui é Week of ear E aí dou um DJs extend Week of Year Pronto agora aparece aqui ó Week então esse método aqui me retorna O ano Atual 2024 e esse aqui é a semana só que esse aqui a semana é claro a primeira semana lá do dia 1 de janeiro até o dia 8 é a semana 1 certo não do dia 1 até o dia 7 né é a semana 1 E aí vai a semana atual agora eu nem
sei qual que é né mas é a gente vai ter aqui logo mais e aí que que eu vou fazer lembra que eu falei que a gente quer separar a nossa query em vários pedacinhos então eu vou começar com um desses pedacinhos como é que a gente vai criar esse pedacinho eu Vou começar pegando quais são todas as metas criadas até a semana atual Então se a gente for traduzir né goals created up to Week né então metas criadas até a semana e aí eu vou usar o DB que é o meu banco de dados
lá do drizzle certo ponto e aqui eu tenho esse with veja que ele já tá aqui logo no comecinho né esse with veja que ele é assim como a gente vê na documentação lá do postgis é esse carinho aqui ó with eu tô criando uma query né auxiliar que vai Ser usada depois dentro de uma outra query E aí eu dou um nome para ela aqui eu vou chamar ela de gos created up to Week veja que é o mesmo nome aqui só usando outro casing tá E aí aqui eu dou um ponto as e
aqui dentro eu vou escrever essa query que eu tenho aqui dentro ó aqui as da mesma forma que eu botei o as aqui ó e agora eu vou escrever ay aqui dentro certo que que eu quero fazer eu vou no meu banco de dados e eu vou Selecionar todas as metas então from gos né fazer um select na tabela gos onde E aí aqui eu vou fazer duas verificações por isso eu vou botar um and por volta porque eu quero fazer duas condicionais e eu preciso que as duas condicionais estejam presentes por isso and e
não or certo são operadores lógicos e aqui eu quero fazer uma comparação E aí o que acontece o drizzle ele tem algumas comparações tradicionais como por exemplo eu posso Comparar se dois valores são iguais usando o eq né equal posso comparar se um valor é maior que o outro usando o GT que é o greater than ou greater than equal posso verificar se tá dentro de um Array usando in Array se é nulo como por exemplo is null not in Array is not null que são é comparações simples né que a gente tem ah dentro
do SQL nesse caso eu quero fazer uma comparação um pouquinho mais complexa por quê eu quero selecionar todas as metas que a data de Criação que é o campo created at é for menor ou igual a semana atual concorda comigo porque eu quero que conte nas metas da minha semana somente as metas que foram criadas até a semana atual concorda comigo porque mais paraa frente se eu tiver visualizando aqui dados de uma semana anterior as metas que foram criadas depois não devem ser exibidas Beleza por isso eu quero selecionar E aí eu vou usar aqui
o SQL que vende de dentro do drizzle que ele me permite fazer e condicionais mais digamos Raw né mais ah customizadas E aí ele segue aqui uma uma ideia de de Tagged Tagged literals template bom já não lembro mais a qual que é o nome disso aqui mas ele é uma função e veja que eu não preciso passar parênteses tá isso aqui é uma Funcionalidade do JavaScript e bom se der tempo depois eu explico mas a gente só passa SQL e passa aqui as duas os dois acentos grave ou aspas e escreve aqui dentro e
aí eu vou escrever aqui SQL SQL normal né do post claro então o que que eu quero fazer eu quero extrair ã eh bom Aqui tem Deixa eu pensar tem várias formas de resolver isso aqui né hum é pensando bem aqui eu posso fazer isso Aqui de uma maneira mais simples tá eu posso usar o próprio DJs aqui ó para eu pegar qual que é o dia o último dia da semana Então olha só e aí eu vou pegar aqui ó o last day of Week tá usando o método End of Week ele vai retornar
e aí eu posso usar aqui até o to date ele vai me retornar o último dia da semana e aí eu posso usar aqui ao invés de fazer o end como eu tava explicando antes eu quero selecionar todas as metas onde a data de criação delas Seja menor ou igual ao último dia da semana então lower than or equal né então LTE que eu importo do drizzle ORM E aí eu passo Qual campo eu quero comparar que é o Ghost created at e aqui o valor last day of Week então quero selecionar todas as metas
onde a data de criação seja menor ou igual ao último dia dessa semana e aqui no select eu posso passar exatamente quais Campos eu quero retornar para não trazer todos os campos né É legal no skl sempre a gente Filtrar bem quais Campos a gente tá retornando então por exemplo eu quero o ID go.id eu quero título go. Tile eu quero a frequência então desired weekly Frequency e eu quero por exemplo Ah Diego mas esses são todos os campos do banco de dados sim por enquanto né a tabela de metas no futuro pode crescer e
talvez a gente não vá utilizar esses novos Campos aqui dentro Perfeito a gente já tem aqui a nossa primeira instrução né Ah Diego posso executar essa query Hum o que a gente pode fazer aqui ó é usar esse get SQL né para visualizar aqui o o SQL que essa query geraria mas não né a ideia quando a gente usa como um table Expression é que essas queries que estão aqui dentro do with elas não são executáveis digamos n sozinhas né Elas sozinha elas não fazem sentido elas vão fazer sentido quando a gente executar elas aqui
dentro De uma query maior tá perfeito a gente tem todas as metas criadas até essa semana e agora eu vou fazer uma outra common table Expression que vai me retornar a contagem de metas concluídas dentro dessa dentro dessa semana Então olha só vou lá no meu banco de dados vou fazer um go go completions tá veja que o mesmo nome aqui só coloco troco cas E aí vou fazer o novo select aqui Dentro DB select e agora eu quero na GO fazer lá no meu na minha tabela de GO completions E aí que que eu
vou fazer aqui dentro e eu vou fazer um ah deixa eu pensar aqui vou fazer um group buy go completions P goid certo porque eu quero e fazer uma contagem então aqui no select eu vou criar aqui uma Completion count E aí Vou colocar aqui vou fazer um count E aí o drizzle tambm exporta isso então posso fazer aqui importa de dentro drizzle vend e aí eu quero fazer uma contagem no campo go completion pode ser no ID mesmo e vou pegar aqui também o go ID que é o go completions goid então o que
que isso aqui vai fazer né Se a gente for ler o Eu acho que esse aqui até consigo executar fora porque como ele não tem uma variável a gente pode vir aqui ó executar o npx Dri kit Studio abre aqui nosso banco de dados aqui a gente vem nessa opção aqui em cima em driz Runner tá vendo a gente joga a aqui dentro e roda ela aqui dentro not porque eu acho que eu não posso usar o count que vem de dentro do drizzle então aqui eu acho que eu teria que [Música] escrever teria que
escrever o skl na mão ou será que eu posso importar aqui Import count from drizzle ORM será não né não posso tá Não tudo bem Vamos ler a juntos aqui né que que basicamente eu tô fazendo né selecionando aqui todos os registros da tabela go completions certo para mim só Faz sentido vou até fazer o we aqui ó os registros também filtrados aqui apenas os que foram eh criados eh ã só faz sentido os que foram criados na semana específico né não faz muito sentido os registros que foram criados em outras semanas então eu vou
pegar aqui o first Day of Week E aí vou pegar aqui start of Week pon to dates aqui vai retornar o Primeiro dia da semana e a vou falar que eu quero apenas os registros onde e vou usar um and aqui e vou onde a data de criação seja menor ou igual ao last day of Week e maior ou igual ao primeiro dia da semana então só as goal completions que foram criados nessa semana especificamente E aí eu tô basicamente agrupando elas pelo id da da da meta e fazendo um cálculo de quantas vezes aquela
meta foi concluída certo então isso aqui é um sk um SQL bem bem Básico digamos assim né ah perfeito agora que a gente já tem essas duas queries aqui a gente vai fazer agora a nossa query principal que vai usar dessas duas common table expressions aqui para unir esses dados e gerar pra gente ah os dados necessários pra gente mostrar aqui ó Nessa listinha aqui tá Então vamos lá eu vou criar aqui um pending gos E aí eu vou começar escrevendo a waight DB E aí no db aqui ó eu vou usar a opção with
veja que esse With aqui ó ele não é com o sinal de dólar na frente porque agora eu não tô criando uma table uma common table Expression eu estou criando uma query que vai usar destas duas outras comon table expressions e então vou passar o nome delas aqui ó variável dentro desse with para essa query saber que essas outras duas queries aqui em cima existem tá se você quiser pode fechar assim ó por enquanto para não incomodar E aí vamos lá vou escrever aqui ó select vou Deixar ele selecionar tudo por enquanto ponto from E
aí eu vou passar aqui da onde que eu quero buscar os dados deixa eu transformar aqui numa função assíncrona tá da onde que eu quero buscar os dados Então veja eu vou pegar os dados de dentro ao invés de eu passar o nome de uma tabela aqui agora eu posso passar o nome de uma comon table Expression Então olha só aqui no from ó eu vou passar toda a minha lista de goals created up to Week que é a a lista De metas criadas até essa semana e aí pra gente já começar a ver os
dados sendo retornados ó eu vou dar um return aqui nesse pending gos tá vou salvar aqui agora e só pra gente eh ir visualizando eu vou criar uma rota aqui na nossa aplicação app.get aqui ó pending gos tá bem simples vou botar aqui uma função assíncrona vou vou fazer um await get weak pending goals não preciso passar parâmetro ela vai me retornar aqui ó Pending goals e eu vou retornar isso aqui de dentro tá se eu salvar isso aqui agora vamos rodar aqui o meu backend né npm Run Opa npm Run venho aqui no Postman
Ah vou clicar aqui em duplicar vou dar um aqui ó ah get Week pending gos troco aqui para pending gos e troco aqui para get e aqui no bu daí não vai mais nada né non don't send Olha só ah Missing from clause entry for table gos tá fechou a gente ah Missing from clause entry for table Goost deixa eu só entender ah [Música] não tá dando para entender muito Qual que é o erro né então o que que a gente pode fazer ó aqui no final eu posso dar um ponl tá vendo salva isso
aqui agora e agora quando eu executo a invés Dee me retornar ele me retorna a query que foi executado ó Então eu tenho aqui e ao invés de eu vou botar aqui Ó eu vou mandar ele retornar pending gos psql tá para eu ver só o SQL mesmo não quero ver o resto Ah não é assim não vou dar um return Vou retornar o SQL direto aqui o SQL SQL e lá no server aqui ó pegar SQL SQL Ox sql.sql é que eu não quero ver os parâmetros eu quero ver só a query aqui ó
assim fica mais fácil porque agora eu posso pegar ela aqui ó e entender o que que tá acontecendo Então tô dando with As from goals vírgula e gos from go completions perfeito group by select ID title from gos created up to Week Hum tá Deixa eu entender aqui o que que eu fiz de errado Hum Ah eu deixei goals created at aqui ó e aqui tem que ser gos completions Sacanagem né não tem problema vamos lá vamos voltar aqui como tava antes vou tirar Oql tá posso deixar ele retornando aqui da forma que tá vindo
mesmo e aí dou send aqui agora e veja que não foi retornado nada Vamos tentar entender o porquê vou voltar com oql aqui ó eh aqui ele retorna sem os parâmetros Tá talvez seja um pouco disso ã vamos entender o que que tá o que que tá acontecendo aqui porque ele deveria retornar todas as Metas onde a data de criação seja lower than or equal last day of Week tá vamos tentar aqui ver qual que é last day of Week pon to ISO string D send ã dia 18 certo Se eu olhar no meu banco
de dados as metas que eu tenho foram criadas antes do dia 18 certo então se eu pegar este essa instrução aqui botar aqui no skl Runner Ahã acho que o PR Fi não arrumou nada na verdade né ã quebrar isso aqui bom eu quebrei aqui a query e dou uma dica para você ah a meu Deus do céu abri um monte de coisa nada a ver mas você consegue mandar a query aqui pro GPT e pedi para ele eh formatar ela foi o que eu fiz né mas eu executei ela e olha só retornou Os
dados aqui aqui e aí foi eu basicamente percebi que aqui no server ó eu deixei esse ponto SQL aqui Eu vou tirar ele daqui ó e agora tiro esse SQL volto lá no Postman don't send e pronto olha só ele trouxe aqui tá Isso aqui é legal vamos lá porque agora a gente começa a ver por partes né Então olha só eu comecei retornando todos os dados que essa query retornou que são todas as metas criadas até o dia 18 ou seja Olha só todas elas dia 13 a gente pode até fazer um teste caso
você queira vai lá no banco de dados manualmente né ali pelo estúdio cadastra uma m al no Dia 20 você vai ver que não vai ser retornado aqui dentro tá mas agora eu preciso cruzar isso com esses dados aqui e aí a gente sabe que para cruzar dados no SQL a melhor forma é usando um join certo então a gente vai fazer aqui um left join Por que left join e não um Inner join né É legal entender as diferenças right left Inner né ah quando a gente faz um left join a gente entende que
os registros dessa tabela aqui pode não existir tu concorda comigo que pode Ser que o usuário não ou nenhuma meta então pode ser que esses registros aqui não existam mas se esses registros não existem para determinada meta aqui eu quero continuar retornando ela e aí eu retorno sei lá zero para dizer que não teve nenhum Ah nenhuma meta nenhuma ã completude como é que você fala isso mas o usuário não completou aquela meta nenhuma vez tá se eu fizesse um Inner join caso eu não tivesse nenhuma Ah o usuário não tivesse completado Aquela meta uma
única vez pelo menos ele não retornaria nem a meta em si Então seria Ok Seria uma ótima opção caso eu quisesse retornar por exemplo todas as metas que tiveram no mínimo um complete ali dentro da semana tá E aí aqui eu fazer um left join então com essa nossa outra common table Expression E aí aqui eu quero fazer um join onde o GO desta query aqui seja igual ao ID desta Query aqui em cima né então Pego aqui ó go ah Opa gos created up to Week ponto ID certo se eu salvar aqui agora voltar
lá no Postman Down send Ah deu erro Ah e por quê deu erro tá quando a gente trabalha com common table expressions né e a gente faz essas agregações como count Sum essas coisas assim a gente precisa Obrigatoriamente dar um dar um nome é de um alas né que é digamos um nome para essa agregação aqui então sempre que eu fizer um count um Sum né Dentro de uma agregação dentro de uma common table Expression eu preciso passar o ponto as e dar um nome eu posso dar o mesmo nome que eu tenho aqui ó
completion count tá vendo mesmo que tá aqui aqui dentro dou send e veja que agora olha o que que tá sendo retornado aqui de dentro pra gente tá eu tenho para cada meta ó cada um desses objetos que tá sendo retornados daqui de dentro é uma meta Então a primeira meta aqui que é a meta acordar cedo eu tenho Uma vez esta meta completa é completa dentro da semana para essa outra meta me exercitar Eu também tenho uma vez paraa outra meta meditar nenhuma veja tá nul certo para outra meta nadar também nulo porque lembra
a gente criou elas depois não usar o celular de noite também nulo porque a gente criou ela depois essas duas primeiras metas que tem aqui completion count foram aquelas metas que a gente criou lá no seed aqui ó as duas metas que a gente completou Essa semana certo por isso elas estão mostrando ali mas agora eu preciso organizar esses dados então aqui no select ao invés de retornar dessa forma que tá toda bagunçada aqui eu vou fazer o seguinte eu quero o ID da meta e aí eu posso usar aqui o gos created up to
Week ID eu quero o título da Meta que eu também posso pegar desta mesma como um table Expression veja ela retorna o título aqui eu quero o número de vezes que eu deveria ter completado ou que eu Devo ter completado essa meta na semana que eu também vou buscar dali por último eu quero saber quantas vezes eu completei essa meta e aí essa parte de completei vem da outra tabela que é a go completion E aí eu vou pegar aqui o completion count Então veja que eu estou buscando três dados que vem desta primeira query
aqui da primeira comon table Expression e este outro dado vem dessa segunda common table Expression Vou salvar aqui Agora venho aqui no Postman don't send e olha como vem mais bonito os dados agora né eu tenho cada uma das metas e o completion count mas tá vendo que o completion count ele vem como nulo aqui Ó nesses casos né então a gente tem algumas opções para resolver isso acho que a mais simples é vir aqui ó depois do count ó e fazer um ponto map with e eu passo Number do JavaScript pon map with Number
se eu salvo aqui agora e volto e dou um send continua como nulo Então isso ah não resolveu Deixa eu ver se eu tenho Ah eu posso fazer um wif aqui dentro e tudo mais mas aqui não realmente não não vai resolver tá que que eu vou fazer aqui ó aqui no completion count ao invés de simplesmente só pegar esse dado eu vou fazer o seguinte vou usar o SQL lembra que a gente falou do SQL antes que ele me permite fazer uma é uma tratativa né tratar esse sk Ah daí aqui não dá para
ficar dessa forma aqui ó que vai ter que Ser pending goals de volta e aqui pending goals né para não ficar o mesmo nome SQL aqui aqui no skl vou escrever código skl mesmo e aí que que eu vou fazer aqui ó eu vou vou usar aqui um coales caso você nunca tenha usado quals dentro do SQL ele me permite fazer um if né Eh caso aquela variável não exista seja nulo eu vou retornar um valor default né então aqui eu passo dentro do calls Passo uma variável dessa forma e passo qual que é a
minha coluna então go completion counts P completion count dou uma vírgula aqui e boto o valor default zero se eu salvar isso aqui agora e der um send olha só ele retornou mas tá vendo que ele retornou tudo como string porque por padrão né O O quals ele vai retornar como string E aí sim aqui no final do skl Ó eu posso vir aqui e fazer um ponto map with Number salvo dou send e agora Sim veja que tá tudo como número né então que que eu tô fazendo no campo completion count né nessa nesse
retorno eu estou pegando a coluna completion count que vem de dentro desta comon table Express caso ela não exista seja nulo retorno zero e aí no final eu faço um map que é basicamente eu pego o resultado desse SQL e passo ele para dentro do da classe Number do JavaScript que basicamente converte né um texto para Número poderia ser um parse int também resolveria da mesma forma mas o Number aqui vai ser vai ser melhor tá Ah e outra dica que eu te dou aqui que eu acho bem legal também é algo mais para bonito
mesmo tá aqui no vest code tem uma extensão que é essa aqui ó comment Tagged templates se você instalar ela uma coisa que é legal é aqui ó no SQL quando a gente cria esse Tagged template aqui esse com com com Cras tá vendo que fica tudo como texto aqui dentro não Consegue saber ter uma sintasse né de esql então tu vem aqui ó joga um comentario Zinho dessa forma aqui ó só dessa forma aqui ó escreve ES e agora veja que o colest já ficou roxinho tá vendo qualquer esel que a gente escrever aqui
dentro agora olha só ó select asterisco tá vendo ele deixa sintasse de SQL acho muito legal isso aqui no para usar no no vest code tá perfeito ah finalizamos aqui a nossa cre só vou retornar ela de uma maneira um Pouquinho melhor aqui ficou em dobro aqui o skl aqui eu vou retornar como objeto mesmo Da mesma forma que eu falei lá no outro né pending goals Tá vendo vou aqui no meu server Ah vou pegar aqui ó pending goals e aqui também dessa forma pending a goals tá e perfeito agora sim a gente finalizou
com chave de ouro aqui o que a gente queria fazer e para esta rota em si né a gente já pode continuar e agora eu sei 1:40 de código você já deve estar cansado de me ouvir Ou cansada de me ouvir Mas pense que eu estou aqui 1:40 na verdade muito mais preparando a aplicação gravando para você esse conteúdo gratuito que eu espero que você eh absorva o máximo de conteúdo possível assim e eu tenho certeza que a gente vai chegar lá no final muito felizes juntos com essa aplicação construída Tá mas eu vou criar
mais uma função a última função de hoje eu prometo que é a Create go completion tá que ela vai fazer mais Ou menos parecido com o Create go aqui a gente vai criar uma nova não sei como é que é o nome disso né mas marcar que eu completei o uma meta e aí ela vai receber apenas o ID da Meta que eu quero marcar como completa tá então Create go completion e vou trocar o nome dessa interface aqui também PR Create go completion request vou pegar aqui o go ID E aí se a gente
for pensar Bom Para eu marcar que uma meta foi completa basta eu inserir dentro da tabela go Completions o go ID certo e pronto ele vai usar a data atual lá no campo created at certo aqui eu posso chamar sei lá de GO completion retornar aqui e pronto certo certo mas e o que que deveria acontecer se o usuário já completou essa meta o número máximo de vezes que ela poderia ser completa naquela semana né que ele configurou que ela poderia ser completa bom pensando na nossa aplicação hoje isso não deveria ser possível Porque como
eu ten essa barra de progresso aqui em cima né Eu quero que quando ela chega em 100% é 100% não é 110 % né A minha aplicação Ela não é uma aplicação que eu quero motivar o usuário ir além do que ele se propôs não então até para ela ficar um pouco mais difícil né pra gente não deixar as coisas tão simples quando uma meta foi completada ali o número máximo de vezes que o usuário se propôs eu não quero permitir que ele possa novamente marcar essa meta Como completa tá então o que que eu
vou fazer aqui dentro aqui no get Week pending goals a gente tem esse goal completion counts aqui que pode servir pra gente saber se uma meta foi completa o número de vezes é ideal né o número de vezes máximo dela certo então que que eu vou fazer aqui eu vou copiar esse go completion CS aqui vou jogar aqui no meu Create go completion tá falta algumas coisas aqui vou importar o count que vem do d RM Cuidado para importar certinho aqui também tem que vir do driz perfeito greater than equal lower than equal e esse
first Day e last day of Week que eu vou importar aqui acabo nem usando esse extend aqui ó Então posso até remover ele aqui de cima O plugin né venho aqui jogo aqui dentro importo DJs e pronto certo e agora a gente vai fazer o seguinte aqui embaixo eu vou escrever uma query usando esse common table ah Expression aqui então vou fazer o seguinte const result igual e eu vou fazer o seguinte a DB with passo aqui a minha com Expression né porque eu quero usar ela nessa e eu vou dar um select vamos quebrar
aqui a linha ficar um pouquinho mais organizado P from vou passar aqui minha tabela de gos tá vou fazer um left join nessa minha common table Expression onde o go Completion count goid seja igual a ao ID que eu tô botando aqui no from na tabela goals tá ã E aí eu quero selecionar basicamente eh o número de completion então pegar aqui o completion count Posso até fazer da mesma forma que eu fiz lá no get Week pending goals aqui ó usando um cols ah e o desir weak Frequency também ó Posso copiar os dois
já e venho e jogo aqui dentro só que o desir Frequency Agora ele vai vir da tabela gos que eu já tô fazendo o select direto Vou importar o SQL aqui ó e pronto tá aqui deixa eu eh comentar o resto do código aqui porque eu quero ver só O resultado deste carinha aqui tá então vou dar um return aqui nesse resultado vou lá no meu server vou criar aqui uma nova rota do tipo post por enquanto tudo no mesmo arquivo logo a gente vai mudar aqui o nome dela vai Ser go completion pode ser
assim ou só completions pode completion fho mais bonito e aqui botar go ID é única informação que preciso receber noego aqui go ID aqui vai serate go completion e pass goid ven aqui duplicar essa rota aqui ó vamos renomear ela né PR Create go completion perfeito aqui a Gente troca para completions E aí no bar eu preciso enviar o ID vamos pegar aqui no get Week paining goals vamos pegar o ID de uma meta aqui ó que ainda falta a gente completar vamos pegar essa meditar aqui ó que a gente só precisa completar ela uma
única vez e vamos botar aqui no go ID Vamos botar ela aqui dentro e aí que que eu vou fazer aqui ó eu vou dar um const result aqui ó e vou dar um return nesse result pra gente ver o que que tá Sendo retornado ali de dentro Então se eu dou um send aqui agora olha só ele retornou aqui ó todas as metas só que olha só aqui ó eu esci de fazer esqueci ou não tinha feito ainda né mas eu esqueci de fazer o we então vou fazer aqui um we onde o gos
pid seja igual ao go ID que eu tenho lá em cima e inclusive posso fazer esse mesmo we aqui dentro da minha common table Expression porque assim eu Não incluo dados de uma meta que não é a meta que eu tô querendo completar agora então bota aqui ó eq go completions goid é o mesmo go ID que eu tô recebendo aqui como parâmetro se eu salvar isso aqui agora e dar um send Olha só o resultado ele já vem bem mais filtrado então ele me falou que essa meta que eu mandei aqui ó eu espero
né completar ela uma vez na semana e eu completei zero até agora né então isso Aqui já me traz as informações que eu quero e aí aqui de dentro Então desse result né eu vou pegar do result na posição zero porque veja ele retornou um arrei porque todo select retorna um Array só que aqui eu sei que sempre vai vir apenas um único registro né porque eu tô fazendo a pelo id posso até jogar um limit um aqui ó para garantir que só vai vir um registro sempre E aí desse Primeiro Registro eu quero buscar
os dados completion count e o desired Weekly Frequency E aí se o completion count for maior ou igual ao desired weekly Frequency né se eu já completei essa meta ah pelo menos o mesmo número de vezes deveria ser é difícil ser maior né Poderia verificar só igual Mas pode acontecer né mas se eu já completei essa meta número de máximo de vezes vou dar um erro então throw New error ah go already completed this Week tá se eu salvar aqui agora não vai dar erro porque eu não completei essa meta ainda E aí eu vou
fazer o quê Vou fazer a inserção então pego aqui não vou chamar isso aqui de result n vou chamar de insert result só pra gente não ficar com o mesmo resultado E aí torno aqui agora o meu go completion dessa forma e aí lá no meu servidor no meu na minha rota vou fazer a ah eu não preciso retornar o result aqui nesse caso aqui ó só fazer a inserção sem retornar nada salvo aqui agora vou Fazer o send e veja aqui deu Ok se eu for lá na rota que lista as metas pendentes veja
que agora ela já tem o completion um aqui ó e se eu tento completar ela de novo ó erro go already completed this we cara legal né a gente aprendeu bastante como usar as comon table expressions e aqui eu quero deixar uma dica para você fazer até a aula de amanhã que é o seguinte vem por exemplo nessa get Week pending goals que é uma query um pouquinho mais complexa tá E aí Você vem aqui no final dela ó aqui depois do Left Joint tá vendo você vem aqui e faz o seguinte ó dá um
to e ou melhor vem aqui ó dá um conso log pending gos P2 ah ah eu acho que eu não vou fazer conseguir fazer dessa forma aqui porque eu usei o aight aqui em cima H Deixa eu pensar Deixa eu pensar Deixa eu pensar tá tudo bem vem aqui ó dá um ponto to SQL aqui no final tá ã E aí lá no no seu servidor tu vem aqui Ó na rota get pending goals aqui ó ah e tu dá um return pending gos psql perfeito aí tu salva ou melhor pode retornar os dois não
tem problema dessa forma aqui ó e tu vem aqui na pending gos dá um send tá E aí veja que ele vai retornar o SQL E vai retornar os parâmetros que foi o que ele inseriu em cada um desses carinhas aqui ó dólar 1 é esse primeiro parâmetro dólar 2 é esse segundo par D esse terceiro parâmetro aqui que que Eu vou fazer vem aqui ó pega esse sk aqui copia vai no chat GPT e bota assim ó Format Dá um enter e manda o skq aqui tá olha só ele vai te retornar oql todo
formadinho bonito demais e aí tu pode falar por exemplo até para ele assim ó add these palms inside the SQL eu acho que ele vai entender que é para adicionar no 1 2 e 3 ali Né Beleza cara é muito bom já inseriu ali ó bem certinho os parâmetros E aí olha só agora tu consegue vir aqui e dar um cy tá E aí tu CONSEG vir aqui no Studio não lembro se ele tá rodando ainda eu acredito que sim tá aqui ó pode vir aqui no skl cola o skl aqui dentro tu vai executar
e veja que ele retorna ó exatamente os dados da nossa C Tá única diferença que o col aqui T vendo que retornou como coal tu pode botar aqui um as completion count tá Dá um uma Executada de novo ó já trocou o nome certinho olha só que legal né agora qual que é meu exercício para você tenta entender né olhar para essa query e entender né E você vai ver que as coisas elas vão se conectando né E essa parte comon table Expression como isso aqui é legal né a gente repartir a nossa query em
pequenos pedacinhos né então primeiro eu busquei todas as metas que foram criadas até essa semana depois eu busquei uma lista de metas e quantas Vezes essas metas foram completas e depois eu agreguei todos esses resultados aqui numa última cy que usou dessas duas cies aqui de cima para retornar esses resultados aqui né Isso aqui é muito legal e uma das coisas que você pode fazer também caso e você pode pedir pro GPT né então explain this Line by Line né E aí se você quiser claro pedir para ele fazer em português e ele vai explicar
detalhadamente caso você queira né entender um pouquinho mais a Fundo o que que está sendo feita dentro de cada comon table Expression E como que isso é utilizado aqui dentro né Isso é bem legal também acho que ajuda bastante eh usar Eu gosto muito de usar o GPT para esses casos né quando a gente quer Eh resolver problemas mais específicos mas sem usar ele para fazer toda a construção pra gente né porque senão a gente eh nem sabe o que que ele tá escrevendo e muitas vezes acaba escrevendo coisas que não são Performáticas o suficiente
Ahã ou que tem problemas de segurança né E por aí vai então vou tirar o tsql aqui de volta ã e Pronto né nossa aplicação volta a funcionar como ela já táa funcionando e a gente pode dar essa aula como concluída Ah agora sim hein parabéns por ter finalizada essa aula agora que você terminou essa etapa acessa a comunidade do discord exclusiva da sua trilha e posta lá que você concluiu essa aula inclusive pode me marcar lá que eu mando Um coraçãozinho lá você também pode tirar dúvidas sobre o conteúdo e ajudar outros devs a
finalizar a aula também isso vai te ajudar a evoluir muito além do código Lembrando que todas as informações sobre o evento estão Reunidas no no guia que você recebeu por e-mail e lá você vai também encontrar Como concorrer a prêmios exclusivos e também como você entra no grupo do WhatsApp que você precisa tá para concorrer esses prêmios Então não Esquece de entrar lá até amanhã na próxima aula