<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Lady{de}bug – Lady{de}bug</title><link>https://deploy-preview-18--ladydebug.netlify.app/</link><description>Recent content on Lady{de}bug</description><generator>Hugo -- gohugo.io</generator><language>pt-BR</language><lastBuildDate>Thu, 27 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://deploy-preview-18--ladydebug.netlify.app/index.xml" rel="self" type="application/rss+xml"/><item><title>Linux Básico</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/dezembro/linux-basico/</link><pubDate>Mon, 01 Dec 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/dezembro/linux-basico/</guid><description>
&lt;h2>Minhas anotações sobre o básicos do Linux&lt;span class="hx:absolute hx:-mt-20" id="minhas-anotações-sobre-o-básicos-do-linux">&lt;/span>
&lt;a href="#minhas-anota%c3%a7%c3%b5es-sobre-o-b%c3%a1sicos-do-linux" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2></description></item><item><title>Configurando o SonarQube Localmente</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/</link><pubDate>Sat, 20 Sep 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/</guid><description>
&lt;p>&lt;strong>Isso não é um tutorial,&lt;/strong> é mais para o entendimento e estudo sobre a ferramenta e como aplicar ela em projetos pequenos, até médio porte, em repositórios fechados (código privado). Bom, como eu já tinha o SonarQube instalado na minha máquina, abaixo segue como configurar o Docker.&lt;/p>
&lt;hr>
&lt;h2>&lt;strong>Opção 1: Remover o container existente&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="opção-1-remover-o-container-existente">&lt;/span>
&lt;a href="#op%c3%a7%c3%a3o-1-remover-o-container-existente" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Para um trabalho de Pós-graduação eu tinha configurado para um projeto de estudo de análise de código, neste caso foi reconfigurar para outro projeto (depois eu configuro novamente correto para o projeto de estudo de análise de código).&lt;/p>
&lt;p>&lt;code>docker rm sonarqube&lt;/code>&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/image1.png" alt="image1.png" loading="lazy" />&lt;/p>
&lt;p>Agora posso executar o comando para subir um novo container:&lt;/p>
&lt;p>&lt;code>docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community&lt;/code>&lt;/p>
&lt;blockquote>
&lt;p>Sim, a versão é gratuíta, para aprendizado antes de sair pagando algo que não sabe usar.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/image2.png" alt="image2.png" loading="lazy" />&lt;/p>
&lt;h3>&lt;strong>Opção 2: Substituir o container automaticamente&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="opção-2-substituir-o-container-automaticamente">&lt;/span>
&lt;a href="#op%c3%a7%c3%a3o-2-substituir-o-container-automaticamente" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Se quiser forçar a substituição, use o parâmetro &amp;ndash;rm (remove ao parar) ou &amp;ndash;replace (caso use Podman). No Docker, geralmente removemos manualmente como acima.&lt;/p>
&lt;h3>&lt;strong>Opção 3: Verificar o status do container&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="opção-3-verificar-o-status-do-container">&lt;/span>
&lt;a href="#op%c3%a7%c3%a3o-3-verificar-o-status-do-container" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;code>docker start sonarqube&lt;/code>&lt;/p>
&lt;p>Para encerrar use o comando:&lt;/p>
&lt;p>&lt;code>docker stop sonarqube&lt;/code>&lt;/p>
&lt;h2>&lt;strong>Executar o SonarQube localmente&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="executar-o-sonarqube-localmente">&lt;/span>
&lt;a href="#executar-o-sonarqube-localmente" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Agora a parte que interessa é configurar localmente o SonarQube, e fazer um escaneamento básico.&lt;/p>
&lt;p>Primeiro um setup de configuração (acho que vale adicionar isso no script de desenvolvimento).&lt;/p>
&lt;h3>&lt;strong>1. Pré-requisitos&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="1-pré-requisitos">&lt;/span>
&lt;a href="#1-pr%c3%a9-requisitos" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Java 11 ou superior&lt;/strong> instalado na máquina (SonarQube precisa do Java para rodar).&lt;/li>
&lt;li>&lt;strong>Docker&lt;/strong> (opcional, mas facilita a execução do SonarQube — realmente).&lt;/li>
&lt;/ul>
&lt;h3>&lt;strong>2. Baixando e rodando o SonarQube&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="2-baixando-e-rodando-o-sonarqube">&lt;/span>
&lt;a href="#2-baixando-e-rodando-o-sonarqube" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Link de download: &lt;a href="https://www.sonarsource.com/open-source-editions/sonarqube-community-edition/"target="_blank" rel="noopener">https://www.sonarsource.com/open-source-editions/sonarqube-community-edition/&lt;/a>&lt;/p>
&lt;p>Aqui a primeira parte de ajustar o docker então precisa se atentar a deixar ele executando, corretamente, sem problemas.&lt;/p>
&lt;p>&lt;code>docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community&lt;/code>&lt;/p>
&lt;p>Pronto! SonarQube rodando localmente.&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/image3.png" alt="image3.png" loading="lazy" />&lt;/p>
&lt;p>Ajuste as configurações de senha e segue para a página:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/image4.png" alt="image4.png" loading="lazy" />&lt;/p>
&lt;h3>&lt;strong>Configuração do SonarQube&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="configuração-do-sonarqube">&lt;/span>
&lt;a href="#configura%c3%a7%c3%a3o-do-sonarqube" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>Acesse &lt;a href="http://localhost:9000/"target="_blank" rel="noopener">http://localhost:9000&lt;/a>&lt;/li>
&lt;li>Login padrão:
&lt;ul>
&lt;li>Usuário: admin&lt;/li>
&lt;li>Senha: admin&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>Agora vamos configurar para fazer um escaneamento do projeto&lt;/p>
&lt;h3>&lt;strong>Gerando um Token de autenticação&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="gerando-um-token-de-autenticação">&lt;/span>
&lt;a href="#gerando-um-token-de-autentica%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>No menu superior direito, clique no seu usuário &amp;gt; My Account &amp;gt; Security.&lt;/li>
&lt;li>Em &amp;ldquo;Generate Tokens&amp;rdquo;, crie um novo token (ex: nome-projeto-token).&lt;/li>
&lt;li>Guarde esse token (será usado no scanner).&lt;/li>
&lt;/ol>
&lt;h3>&lt;strong>Instalando o SonarScanner&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="instalando-o-sonarscanner">&lt;/span>
&lt;a href="#instalando-o-sonarscanner" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>O &lt;strong>SonarScanner&lt;/strong> é o CLI para enviar seu código ao SonarQube. Ou seja, localmente via terminal vamos falar para ele ler o projeto e então temos a análise.&lt;/p>
&lt;h3>&lt;strong>Instalação via NPM (para projetos Node):&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="instalação-via-npm-para-projetos-node">&lt;/span>
&lt;a href="#instala%c3%a7%c3%a3o-via-npm-para-projetos-node" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;code>npm install -g sonarqube-scanner&lt;/code>&lt;/p>
&lt;p>Para referências de cada projeto segue: &lt;a href="https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/scanners/sonarscanner"target="_blank" rel="noopener">https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/scanners/sonarscanner&lt;/a>&lt;/p>
&lt;h3>&lt;strong>Configurando o SonarScanner no Projeto&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="configurando-o-sonarscanner-no-projeto">&lt;/span>
&lt;a href="#configurando-o-sonarscanner-no-projeto" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Na raiz do projeto, crie um arquivo chamado &lt;code>sonar-project.properties&lt;/code>:&lt;/p>
&lt;p>Exemplo:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-jsx" data-lang="jsx">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">projectKey&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nx">nome&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="nx">projeto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">projectName&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nx">Nome&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="nx">projeto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">projectVersion&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">1.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">sources&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">language&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nx">js&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nx">php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">sourceEncoding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nx">UTF&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">host&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">url&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nx">http&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="c1">//localhost:9000
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">sonar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">login&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nx">SEU_TOKEN_AQUI&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;h2>&lt;strong>Problemas encontrados&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="problemas-encontrados">&lt;/span>
&lt;a href="#problemas-encontrados" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/problema-encontrado-ao-rodar-o-escaneamento-2025-09-20-09-24.png" alt="problema encontrado ao rodar o escaneamento" loading="lazy" />&lt;/p>
&lt;p>ERROR: You&amp;rsquo;re not authorized to run analysis. Please contact the project administrator.&lt;/p>
&lt;h3>&lt;strong>O que significa esse erro?&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="o-que-significa-esse-erro">&lt;/span>
&lt;a href="#o-que-significa-esse-erro" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>O SonarScanner está tentando enviar os resultados da análise para o SonarQube, mas o usuário (ou token) configurado &lt;strong>não tem permissão&lt;/strong> para realizar essa operação no projeto configurado no SonarQube.&lt;/p>
&lt;p>&lt;strong>Perfeito! Vamos ver o que fiz de errado&lt;/strong>: o nome do projeto no arquivo &lt;code>sonar-project.properties&lt;/code> não estava igual ao que eu configurei no SonarQube local.&lt;/p>
&lt;p>Agora pronto: quando executar o comando &lt;code>sonar-scanner&lt;/code> vai executar o escaneamento no projeto e seguida mostrar em tela os resultados.&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/terminal-sucesso-2025-09-20-09-33.png" alt="terminal com sucesso" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/configurando-o-sonar-qube-localmente/executado-2025-09-20-09-32.png" alt="executado" loading="lazy" />&lt;/p></description></item><item><title>Refactor: Blog</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/refactor-blog/</link><pubDate>Fri, 10 Jul 2026 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/refactor-blog/</guid><description>
&lt;h2>Análise do repositório &lt;code>notion-blog&lt;/code>&lt;span class="hx:absolute hx:-mt-20" id="análise-do-repositório-notion-blog">&lt;/span>
&lt;a href="#an%c3%a1lise-do-reposit%c3%b3rio-notion-blog" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Meu blog pessoal estava cheio de bugs pois eu só não fiz a devida manutenção que precisava ao longo do período desde que criei — talvez 2 anos. Agora a ideia é corrigir bugs e funcionalidades que eu gostaria de adicionar.&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/refactor-blog/repo-atual-notion-blog.png" alt="Blog antigo em Next.js &amp;#43; Notion" loading="lazy" />&lt;/p>
&lt;p>Paginação com erros, demora no carregamento, conteúdo centralizado em ferramenta.&lt;/p>
&lt;p>&lt;strong>O que gostaria de melhorar&lt;/strong>: descentralizar o conteúdo, organizar o backup rotineiro (por versão), fazer o deploy em dev (não somente em main).&lt;/p>
&lt;hr>
&lt;h2>1. Visão geral&lt;span class="hx:absolute hx:-mt-20" id="1-visão-geral">&lt;/span>
&lt;a href="#1-vis%c3%a3o-geral" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>É um &lt;strong>blog estático em Next.js que usa o Notion como CMS/backend&lt;/strong>. É um &lt;em>fork&lt;/em> do template original de &lt;a href="https://github.com/ijjk/notion-blog"target="_blank" rel="noopener">&lt;code>ijjk/notion-blog&lt;/code>&lt;/a>, personalizado por mim. O conteúdo dos posts vive em uma tabela do Notion e o site é gerado via &lt;strong>SSG (Static Site Generation)&lt;/strong> com revalidação incremental, hospedado na Vercel.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Deploy atual:&lt;/strong> &lt;code>https://notion-blog-lake-two.vercel.app/&lt;/code>&lt;/li>
&lt;li>&lt;strong>Branch atual:&lt;/strong> &lt;code>claude/repository-analysis-ieglo6&lt;/code> (idêntica a &lt;code>develop&lt;/code> — sem diferenças)&lt;/li>
&lt;li>&lt;strong>Licença:&lt;/strong> presente (&lt;code>license&lt;/code>)&lt;/li>
&lt;/ul>
&lt;h2>2. Stack e dependências&lt;span class="hx:absolute hx:-mt-20" id="2-stack-e-dependências">&lt;/span>
&lt;a href="#2-stack-e-depend%c3%aancias" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Camada&lt;/th>
&lt;th>Tecnologia&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Framework&lt;/td>
&lt;td>Next.js &lt;code>^11.1.2&lt;/code> (Pages Router)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>UI&lt;/td>
&lt;td>React &lt;code>17&lt;/code>, CSS Modules&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Linguagem&lt;/td>
&lt;td>TypeScript &lt;code>5.8&lt;/code> (com &lt;code>strict: false&lt;/code>)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Conteúdo&lt;/td>
&lt;td>&lt;strong>API privada não-oficial do Notion&lt;/strong> (&lt;code>www.notion.so/api/v3&lt;/code>)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Extras&lt;/td>
&lt;td>&lt;code>katex&lt;/code> (equações), &lt;code>prismjs&lt;/code> (syntax highlight), &lt;code>@zeit/react-jsx-parser&lt;/code>, &lt;code>async-sema&lt;/code> (rate limit), &lt;code>github-slugger&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Qualidade&lt;/td>
&lt;td>Prettier + lint-staged + pre-commit&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Deploy&lt;/td>
&lt;td>Vercel&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2>3. Estrutura&lt;span class="hx:absolute hx:-mt-20" id="3-estrutura">&lt;/span>
&lt;a href="#3-estrutura" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">src/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── pages/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── index.tsx # Home
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── contact.tsx # Contato (GitHub/LinkedIn)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── blog/index.tsx # Lista de posts (getStaticProps)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── blog/[slug].tsx # Renderiza 1 post (getStaticProps/Paths + fallback)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ └── api/ # asset.ts, preview.ts, preview-post.ts, clear-preview.ts
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── lib/notion/ # Integração com o Notion (rpc, getBlogIndex, getPageData…)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── lib/build-rss.ts # Gera feed Atom em /public/atom no build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── components/ # Header, Footer, Code, Equation, Counter, SVGs, SpotifyPlayer…
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── styles/ # CSS Modules + global.css
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">scripts/create-table.js # Cria a tabela-modelo no Notion via API privada&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;h2>4. Como funciona (fluxo de dados)&lt;span class="hx:absolute hx:-mt-20" id="4-como-funciona-fluxo-de-dados">&lt;/span>
&lt;a href="#4-como-funciona-fluxo-de-dados" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>&lt;strong>&lt;code>rpc.ts&lt;/code>&lt;/strong> faz POST autenticado no endpoint privado do Notion usando o cookie &lt;code>token_v2=$NOTION_TOKEN&lt;/code>.&lt;/li>
&lt;li>&lt;strong>&lt;code>getBlogIndex&lt;/code>&lt;/strong> carrega a tabela (&lt;code>BLOG_INDEX_ID&lt;/code>), monta o mapa de posts via &lt;code>getTableData&lt;/code> (que interpreta o &lt;em>schema&lt;/em> da collection do Notion) e busca &lt;em>previews&lt;/em> dos 10 posts mais recentes com concorrência limitada a 3 (&lt;code>async-sema&lt;/code>). Usa cache em disco (&lt;code>.blog_index_data*&lt;/code>) durante o build (&lt;code>USE_CACHE&lt;/code>).&lt;/li>
&lt;li>&lt;strong>&lt;code>blog/index.tsx&lt;/code>&lt;/strong> filtra rascunhos em produção (&lt;code>Published === 'Yes'&lt;/code>) e lista os posts.&lt;/li>
&lt;li>&lt;strong>&lt;code>blog/[slug].tsx&lt;/code>&lt;/strong> busca o conteúdo do post (&lt;code>getPageData&lt;/code> → &lt;code>loadPageChunk&lt;/code> paginado), resolve embeds de tweets, e faz um &lt;em>switch&lt;/em> gigante convertendo cada tipo de bloco do Notion (text, header, image, code, quote, callout, equation, bookmark, tweet…) em JSX.&lt;/li>
&lt;li>&lt;strong>&lt;code>api/asset.ts&lt;/code>&lt;/strong> funciona como proxy: pega a URL assinada do arquivo no Notion (&lt;code>getSignedFileUrls&lt;/code>) e redireciona (307) para servir imagens/vídeos.&lt;/li>
&lt;li>&lt;strong>&lt;code>build-rss.ts&lt;/code>&lt;/strong> roda no build e gera o feed Atom em &lt;code>public/atom&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Preview mode&lt;/strong>: &lt;code>api/preview.ts&lt;/code> e &lt;code>preview-post.ts&lt;/code> habilitam o modo rascunho do Next.&lt;/li>
&lt;/ol>
&lt;h2>5. Pontos fortes&lt;span class="hx:absolute hx:-mt-20" id="5-pontos-fortes">&lt;/span>
&lt;a href="#5-pontos-fortes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>Arquitetura enxuta e bem separada (lib/pages/components).&lt;/li>
&lt;li>Uso correto de SSG + &lt;code>revalidate&lt;/code> (ISR) e &lt;code>fallback: true&lt;/code>.&lt;/li>
&lt;li>Rate-limiting no fetch de previews e cache de build.&lt;/li>
&lt;li>Suporte rico a blocos do Notion (equações KaTeX, código com Prism, callouts, bookmarks, vídeo, tweets).&lt;/li>
&lt;li>Ferramentas de formatação já configuradas (Prettier/lint-staged).&lt;/li>
&lt;/ul>
&lt;h2>6. Problemas e riscos que encontrei&lt;span class="hx:absolute hx:-mt-20" id="6-problemas-e-riscos-que-encontrei">&lt;/span>
&lt;a href="#6-problemas-e-riscos-que-encontrei" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;h3>Segurança / prático&lt;span class="hx:absolute hx:-mt-20" id="segurança--prático">&lt;/span>
&lt;a href="#seguran%c3%a7a--pr%c3%a1tico" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;strong>&lt;code>NOTION_TOKEN&lt;/code> usado como senha de preview&lt;/strong>: &lt;code>preview.ts&lt;/code> e &lt;code>preview-post.ts&lt;/code> comparam &lt;code>req.query.token === process.env.NOTION_TOKEN&lt;/code>. Isso coloca o &lt;strong>token secreto do Notion na URL&lt;/strong> (fica em logs, histórico, referrers). Deveria ser um segredo separado (&lt;code>NEXT_PREVIEW_SECRET&lt;/code>).&lt;/li>
&lt;li>&lt;strong>API privada do Notion&lt;/strong> (&lt;code>token_v2&lt;/code> + &lt;code>/api/v3&lt;/code>): não é oficial, pode quebrar a qualquer momento e o token é a sua sessão pessoal. O ideal moderno é migrar para a &lt;strong>API oficial do Notion&lt;/strong> (&lt;code>@notionhq/client&lt;/code>).&lt;/li>
&lt;li>&lt;strong>&lt;code>api/asset.ts&lt;/code> é um proxy aberto&lt;/strong> (&lt;code>Access-Control-Allow-Origin: *&lt;/code>) que assina URLs para qualquer &lt;code>assetUrl&lt;/code>/&lt;code>blockId&lt;/code> recebido — vale restringir.&lt;/li>
&lt;/ul>
&lt;h3>Dependências não declaradas&lt;span class="hx:absolute hx:-mt-20" id="dependências-não-declaradas">&lt;/span>
&lt;a href="#depend%c3%aancias-n%c3%a3o-declaradas" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;code>node-fetch&lt;/code>, &lt;code>@next/env&lt;/code> e &lt;code>shell-quote&lt;/code> são &lt;strong>importados mas não constam no &lt;code>package.json&lt;/code>&lt;/strong> (funcionam só por dependência transitiva/hoisting). Isso é frágil e pode quebrar o build com um lockfile limpo. Devem ser adicionados como dependências explícitas.&lt;/li>
&lt;/ul>
&lt;h3>Restos do template original (branding inconsistente)&lt;span class="hx:absolute hx:-mt-20" id="restos-do-template-original-branding-inconsistente">&lt;/span>
&lt;a href="#restos-do-template-original-branding-inconsistente" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;code>header.tsx&lt;/code>: link &amp;ldquo;Source Code&amp;rdquo; e OG image apontam para &lt;code>ijjk/notion-blog&lt;/code> e &lt;code>notion-blog.now.sh&lt;/code> (domínio &lt;code>now.sh&lt;/code> desativado), twitter &lt;code>@_ijjk&lt;/code>.&lt;/li>
&lt;li>&lt;code>footer.tsx&lt;/code>: link para o repo do &lt;code>ijjk&lt;/code>.&lt;/li>
&lt;li>&lt;code>index.tsx&lt;/code>: ainda usa a imagem/branding &amp;ldquo;Vercel + Notion&amp;rdquo;.&lt;/li>
&lt;li>Metadados/&lt;code>&amp;lt;title&amp;gt;&lt;/code> genéricos (&amp;ldquo;My Notion Blog&amp;rdquo;, &amp;ldquo;An example Next.js site…&amp;rdquo;).&lt;/li>
&lt;li>&lt;strong>Idiomas misturados&lt;/strong> (PT + EN) na interface.&lt;/li>
&lt;/ul>
&lt;h3>Código potencialmente quebrado/frágil&lt;span class="hx:absolute hx:-mt-20" id="código-potencialmente-quebradofrágil">&lt;/span>
&lt;a href="#c%c3%b3digo-potencialmente-quebradofr%c3%a1gil" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Embed de tweets&lt;/strong> usa &lt;code>api.twitter.com/1/statuses/oembed.json&lt;/code> (API v1, &lt;strong>descontinuada&lt;/strong>) — provavelmente já não funciona.&lt;/li>
&lt;li>&lt;code>[slug].tsx&lt;/code> usa &lt;code>unstable_revalidate&lt;/code> (API antiga, &lt;strong>ignorada&lt;/strong> no Next 11) junto com &lt;code>revalidate&lt;/code>.&lt;/li>
&lt;li>&lt;code>equation.tsx&lt;/code>: &lt;code>render()&lt;/code> pode retornar &lt;code>undefined&lt;/code> se o erro &lt;strong>não&lt;/strong> for &lt;code>ParseError&lt;/code> (a variável &lt;code>result&lt;/code> nunca é atribuída).&lt;/li>
&lt;li>&lt;code>getPageData&lt;/code> remove blocos de tabela com &lt;code>splice(0, 3)&lt;/code> fixo — quebradiço.&lt;/li>
&lt;li>&lt;strong>Incoerência de versão de Node&lt;/strong>: o &lt;code>readme&lt;/code> pede Node &lt;code>&amp;gt;=18&lt;/code>, mas &lt;code>getBlogIndex.ts&lt;/code> usa &lt;code>Array.prototype.toSorted()&lt;/code> que exige &lt;strong>Node 20+&lt;/strong>. Já &lt;code>vercel.json&lt;/code> força &lt;code>-openssl-legacy-provider&lt;/code> (workaround de build antigo). Recomendo fixar Node 20 explicitamente.&lt;/li>
&lt;/ul>
&lt;h3>Qualidade / manutenção&lt;span class="hx:absolute hx:-mt-20" id="qualidade--manutenção">&lt;/span>
&lt;a href="#qualidade--manuten%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;code>tsconfig&lt;/code> com &lt;code>strict: false&lt;/code> (perde segurança de tipos; muito &lt;code>any&lt;/code>).&lt;/li>
&lt;li>&lt;strong>Sem testes&lt;/strong> e &lt;strong>sem CI&lt;/strong> (&lt;code>.github/&lt;/code> ausente).&lt;/li>
&lt;li>README com pequenos erros (crases &lt;code>´´´&lt;/code> em vez de &lt;code>```&lt;/code>).&lt;/li>
&lt;/ul>
&lt;h2>7. Recomendações priorizadas&lt;span class="hx:absolute hx:-mt-20" id="7-recomendações-priorizadas">&lt;/span>
&lt;a href="#7-recomenda%c3%a7%c3%b5es-priorizadas" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Trocar o segredo de preview&lt;/strong> por uma variável dedicada (não reusar &lt;code>NOTION_TOKEN&lt;/code> na URL).&lt;/li>
&lt;li>&lt;strong>Declarar &lt;code>node-fetch&lt;/code>, &lt;code>@next/env&lt;/code>, &lt;code>shell-quote&lt;/code>&lt;/strong> no &lt;code>package.json&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Atualizar o branding&lt;/strong>: links, OG image, título e twitter para os meus (remover resíduos do &lt;code>ijjk&lt;/code>/&lt;code>now.sh&lt;/code>).&lt;/li>
&lt;li>&lt;strong>Corrigir/remover o embed de tweets&lt;/strong> (API v1 morta) e o &lt;code>unstable_revalidate&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Alinhar a versão do Node&lt;/strong> (fixar &lt;code>engines: node &amp;gt;=20&lt;/code>) por causa do &lt;code>toSorted()&lt;/code>.&lt;/li>
&lt;li>(Médio prazo) &lt;strong>Migrar para a API oficial do Notion&lt;/strong> e considerar atualizar o Next.js (11 → recente) para segurança e performance.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2>Correções no Blog&lt;span class="hx:absolute hx:-mt-20" id="correções-no-blog">&lt;/span>
&lt;a href="#corre%c3%a7%c3%b5es-no-blog" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/refactor-blog/correcoes-blog.png" alt="Correções aplicadas no blog" loading="lazy" />&lt;/p>
&lt;p>Primeiro foi solicitado para realizar uma análise utilizando o claude.ai, seguindo foi escrito o seguinte script.&lt;/p>
&lt;blockquote>
&lt;p>📚 claude/repository-analysis-ieglo6? Posso começar pelas de baixo risco e alto impacto (dependências no package.json, branding, segredo de preview e os bugs pequenos). Como esta foi uma tarefa de análise, não fiz nenhuma alteração ainda.&lt;/p>
&lt;p>Faça as implementações da seguinte forma.&lt;/p>
&lt;ul>
&lt;li>Corrija os pontos, sempre realizando os testes necessários, não deve implementar sem testar.&lt;/li>
&lt;li>Após testes de validação, abra PRs&lt;/li>
&lt;li>Quando tiver uma atualização delicada, deve ter atenção aos pontos para não quebrar em produção.&lt;/li>
&lt;li>Deve documentar as alterações somente no meu repositório kellen-xavier&lt;/li>
&lt;li>Deve criar a pasta /docs para uso de documentação&lt;/li>
&lt;li>Não deve compartilhar chaves e dados sensíveis - isso inclui documentações, README.md&lt;/li>
&lt;li>Criar um setup .agents no repositório, para adicionar informações persistentes&lt;/li>
&lt;li>Deve incluir no setup o arquivo .AGENTS.md&lt;/li>
&lt;/ul>
&lt;p>Para cada step dado aqui, tenha atenção e testes.&lt;/p>
&lt;/blockquote>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Etapa&lt;/th>
&lt;th>Mudança&lt;/th>
&lt;th>Validação&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Dependências&lt;/strong>&lt;/td>
&lt;td>Declarei &lt;code>node-fetch@2.6.1&lt;/code>, &lt;code>@next/env@11.1.2&lt;/code>, &lt;code>shell-quote@1.7.2&lt;/code> (dev) e &lt;code>@types/node-fetch&lt;/code>; adicionei &lt;code>engines.node &amp;gt;=20&lt;/code> e scripts &lt;code>typecheck&lt;/code>/&lt;code>test&lt;/code>&lt;/td>
&lt;td>&lt;code>tsc&lt;/code> verde&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Segurança (delicado)&lt;/strong>&lt;/td>
&lt;td>&lt;code>PREVIEW_TOKEN&lt;/code> dedicado em &lt;a href="https://github.com/kellen-xavier/notion-blog/blob/claude/repository-analysis-ieglo6/src/lib/preview-auth.ts"target="_blank" rel="noopener">&lt;code>src/lib/preview-auth.ts&lt;/code>&lt;/a>, &lt;strong>com fallback&lt;/strong> para &lt;code>NOTION_TOKEN&lt;/code> para não quebrar produção&lt;/td>
&lt;td>4 testes (401/404/ok/fallback)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Branding&lt;/strong>&lt;/td>
&lt;td>Removidos resíduos &lt;code>ijjk&lt;/code>/&lt;code>now.sh&lt;/code> de header/footer/server-constants&lt;/td>
&lt;td>teste de regressão&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Bugs&lt;/strong>&lt;/td>
&lt;td>&lt;code>equation.render&lt;/code> nunca retorna &lt;code>undefined&lt;/code>; &lt;code>unstable_revalidate&lt;/code> → &lt;code>revalidate&lt;/code>; oembed de tweet v1 morto → &lt;code>publish.twitter.com&lt;/code>&lt;/td>
&lt;td>teste do render + build&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Docs&lt;/strong>&lt;/td>
&lt;td>&lt;code>/docs&lt;/code> (SETUP, ARCHITECTURE, SECURITY, CHANGELOG) — só no meu repo&lt;/td>
&lt;td>—&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Agentes&lt;/strong>&lt;/td>
&lt;td>&lt;code>AGENTS.md&lt;/code> na raiz + &lt;code>.agents/&lt;/code> (contexto + convenções persistentes)&lt;/td>
&lt;td>—&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;ul>
&lt;li>&lt;code>.AGENTS.md&lt;/code> (com ponto): usei a convenção padrão &lt;code>AGENTS.md&lt;/code> na raiz (é o nome que as ferramentas de agente reconhecem) + a pasta &lt;code>.agents/&lt;/code> para o setup persistente.&lt;/li>
&lt;li>O PR foi aberto contra &lt;strong>&lt;code>develop&lt;/code>&lt;/strong> (branch padrão do repo), em 4 commits temáticos.&lt;/li>
&lt;/ul></description></item><item><title>Bot Planner - Projeto para acompanhamento do desenvolvimento pessoal</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/</guid><description>
&lt;p>Recentemente estive a desenvolver alguns projetos de estudos com IA, e estava precisando me organizar, de, quanto tempo estive a desenvolver — tempo corrido —&lt;/p>
&lt;p>também ao esta desenvolvendo algo geralmente eu costumo ler a documentação da lingagem para leitura de algumas práticas, links de documentos, docs que eu estou escrevendo para determinada característica do projeto. Criar tarefas que me lembrei no ato que estava a desenvolver, e verifiquei que pode ser terminada logo após a tarefa que estou a fazer. Além de comentários do que foi realizado, esse acompanhamento de forma geral.&lt;/p>
&lt;p>Com base nesse problema, pensei em algo prático que eu possa fazer enquanto estou desenvolvendo. Ou seja comando &lt;code>/inicio&lt;/code> quando inicio a atividade, &lt;code>/link&lt;/code> para adicionar documentações entre outros importantes. &lt;code>/nota&lt;/code> quando eu quiser adicionar notas comentários, &lt;code>task&lt;/code> para quando quiser criar uma tarefas, &lt;code>fim&lt;/code> quando finalizar tudo. Após isso gere um &lt;code>Release notes&lt;/code> com o que foi feito e quais as tarefas ficaram pendentes.&lt;/p>
&lt;p>Então lendo uma &lt;a href="https://akitaonrails.com/2026/02/16/vibe-code-do-zero-a-producao-em-6-dias-the-m-akita-chronicles/#spoiler-do-processo"target="_blank" rel="noopener">postagem em um blog&lt;/a> e pensei em criar o bot com gestão pessoal para auxiliar no ciclo de desenvolvimento pessoal sem fricção e que gere um report notes no fim do trabalho.&lt;/p>
&lt;p>Podendo também aplicar para compartilhar caso queira com alguém do time (desenvolvimento orientado com metodologia XP).&lt;/p>
&lt;hr>
&lt;p>Criei o repositório no github &lt;a href="https://github.com/kellen-xavier/ladydebug-bot-planner"target="_blank" rel="noopener">https://github.com/kellen-xavier/ladydebug-bot-planner&lt;/a> &lt;del>inicialmente privado mas irei liberar em seguida&lt;/del>, open-source — estou a corrigir algumas questões de segurança — e primeiro criar o bot, inicialmente interação é via Discord, mas vai abranger multicanal de comunicação (pensei em slack e dicord principal) as demais particularmente não me interessei muito.&lt;/p>
&lt;h2>Primeira Fase do desenvolvimento&lt;span class="hx:absolute hx:-mt-20" id="primeira-fase-do-desenvolvimento">&lt;/span>
&lt;a href="#primeira-fase-do-desenvolvimento" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image.png" alt="image.png" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-1.png" alt="image.png" loading="lazy" />&lt;/p>
&lt;p>Nos testes iniciais, ficou bem poluído os comandos no chat unificado, então pensei em criar um segundo “canal de texto”, para que o release-notes separado para acompanhar no dia seguinte, tendo essa visão limpa entre “comandos” e “release notes”.&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-2.png" alt="image.png" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h3>&lt;strong>Organização do Bot&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="organização-do-bot">&lt;/span>
&lt;a href="#organiza%c3%a7%c3%a3o-do-bot" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Para configurar o bot é simples, deve-se seguir a documentação oficial neste link: &lt;a href="https://docs.discord.com/developers/quick-start/getting-started"target="_blank" rel="noopener">&lt;strong>Building your first Discord Bot&lt;/strong>&lt;/a>&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-3.png" alt="image.png" loading="lazy" />&lt;/p>
&lt;p>&lt;strong>Para estes estudo de caso | Como configurar o Bot:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Vá no Developer Portal do Discord.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Abrir o app ladydebug-bot-planner.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Vá em Bot.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Clique em Reset Token.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Copie o token novo.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Atualize DISCORD_TOKEN no .env.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Rode de novo:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -a&lt;span class="p">;&lt;/span> &lt;span class="nb">source&lt;/span> .env&lt;span class="p">;&lt;/span> &lt;span class="nb">set&lt;/span> +a
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">python -m daily.main&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;/li>
&lt;li>
&lt;p>Configuração Mínima Local&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Seu .env local deve ter pelo menos:&lt;/p>
&lt;p>&lt;code>DISCORD_TOKEN=token_do_bot DISCORD_GUILD_ID=807481361916100628 DB_PATH=daily.db&lt;/code>&lt;/p>
&lt;hr>
&lt;h3>Plano de Testes Bot Planner&lt;span class="hx:absolute hx:-mt-20" id="plano-de-testes-bot-planner">&lt;/span>
&lt;a href="#plano-de-testes-bot-planner" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Visão geral&lt;/p>
&lt;p>&lt;strong>Checklist&lt;/strong>:&lt;/p>
&lt;h4>Todos&lt;span class="hx:absolute hx:-mt-20" id="todos">&lt;/span>
&lt;a href="#todos" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h4>&lt;p>[•] Mapear módulos e funcionalidades existentes em src/daily
[ ] Mapear testes existentes por funcionalidade
[ ] Executar testes/cobertura disponível
[ ] Consolidar lacunas de cobertura e recomendações&lt;/p>
&lt;h3>Funcionalidades Com Testes&lt;span class="hx:absolute hx:-mt-20" id="funcionalidades-com-testes">&lt;/span>
&lt;a href="#funcionalidades-com-testes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Criei o report em docs/TEST_COVERAGE_REPORT.md aqui ele documenta o seguinte:&lt;/p>
&lt;ul>
&lt;li>Estado atual da suíte: 79 passed.&lt;/li>
&lt;li>Diretrizes para evitar testes enviesados/falso positivo.&lt;/li>
&lt;li>Lacunas restantes por prioridade.&lt;/li>
&lt;li>Cenários exatos que precisam ser implementados.&lt;/li>
&lt;li>Critérios de aceite para novas rodadas.&lt;/li>
&lt;li>Recomendação para adicionar pytest-cov.&lt;/li>
&lt;li>Ordem sugerida de execução.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Principais áreas priorizadas no report:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>CommandRouter&lt;/li>
&lt;li>SqliteStorage&lt;/li>
&lt;li>SimpleFetcher&lt;/li>
&lt;li>VCS adapters&lt;/li>
&lt;li>Report de fim de dia&lt;/li>
&lt;li>Discord adapter callbacks&lt;/li>
&lt;li>Models/DTOs&lt;/li>
&lt;li>Métrica objetiva com coverage&lt;/li>
&lt;/ol>
&lt;hr>
&lt;p>&lt;strong>Erros encontrado:&lt;/strong>&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-jsx" data-lang="jsx">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">python&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="nx">m&lt;/span> &lt;span class="nx">daily&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="mi">2026&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">07&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">09&lt;/span> &lt;span class="mi">09&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">45&lt;/span> &lt;span class="nx">INFO&lt;/span> &lt;span class="nx">discord&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">client&lt;/span> &lt;span class="nx">logging&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">using&lt;/span> &lt;span class="kr">static&lt;/span> &lt;span class="nx">token&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="mi">2026&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">07&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">09&lt;/span> &lt;span class="mi">09&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">47&lt;/span> &lt;span class="nx">INFO&lt;/span> &lt;span class="nx">discord&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">gateway&lt;/span> &lt;span class="nx">Shard&lt;/span> &lt;span class="nx">ID&lt;/span> &lt;span class="nx">None&lt;/span> &lt;span class="nx">has&lt;/span> &lt;span class="nx">connected&lt;/span> &lt;span class="nx">to&lt;/span> &lt;span class="nx">Gateway&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">Session&lt;/span> &lt;span class="nx">ID&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">b25a5b78274ede64c286f2fc11e8c2e3&lt;/span>&lt;span class="p">).&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">Bot&lt;/span> &lt;span class="nx">online&lt;/span> &lt;span class="nx">como&lt;/span> &lt;span class="nx">ladydebug&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="nx">bot&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="nx">planner&lt;/span>&lt;span class="err">#&lt;/span>&lt;span class="mi">3088&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="mi">2026&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">07&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">09&lt;/span> &lt;span class="mi">09&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">51&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">05&lt;/span> &lt;span class="nx">ERROR&lt;/span> &lt;span class="nx">discord&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">app_commands&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">tree&lt;/span> &lt;span class="nx">Ignoring&lt;/span> &lt;span class="nx">exception&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">command&lt;/span> &lt;span class="s1">&amp;#39;inicio&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">Traceback&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">most&lt;/span> &lt;span class="nx">recent&lt;/span> &lt;span class="nx">call&lt;/span> &lt;span class="nx">last&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/commands.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">859&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">_do_call&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="nx">self&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_callback&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">interaction&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">**&lt;/span>&lt;span class="nx">params&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="err">#&lt;/span> &lt;span class="nx">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">ignore&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/src/daily/adapters/discord_bot.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">90&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">inicio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">msg&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">router&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">inicio&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">interaction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">user&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">id&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nx">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">interaction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">channel_id&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/src/daily/command_router.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">inicio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">s&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">self&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_day&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">start_day&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">user_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">channel_id&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/src/daily/core/day_service.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">start_day&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">raise&lt;/span> &lt;span class="nx">DayAlreadyOpen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Já existe um dia aberto para este usuário.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">daily&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">core&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">day_service&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">DayAlreadyOpen&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">Já&lt;/span> &lt;span class="nx">existe&lt;/span> &lt;span class="nx">um&lt;/span> &lt;span class="nx">dia&lt;/span> &lt;span class="nx">aberto&lt;/span> &lt;span class="nx">para&lt;/span> &lt;span class="nx">este&lt;/span> &lt;span class="nx">usuário&lt;/span>&lt;span class="p">.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">The&lt;/span> &lt;span class="nx">above&lt;/span> &lt;span class="nx">exception&lt;/span> &lt;span class="nx">was&lt;/span> &lt;span class="nx">the&lt;/span> &lt;span class="nx">direct&lt;/span> &lt;span class="nx">cause&lt;/span> &lt;span class="k">of&lt;/span> &lt;span class="nx">the&lt;/span> &lt;span class="nx">following&lt;/span> &lt;span class="nx">exception&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">Traceback&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">most&lt;/span> &lt;span class="nx">recent&lt;/span> &lt;span class="nx">call&lt;/span> &lt;span class="nx">last&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/tree.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">1302&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">_call&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">await&lt;/span> &lt;span class="nx">command&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_invoke_with_namespace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">interaction&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">namespace&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/commands.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">884&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">_invoke_with_namespace&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="nx">self&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_do_call&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">interaction&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">transformed_values&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">File&lt;/span> &lt;span class="s2">&amp;#34;/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/commands.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">line&lt;/span> &lt;span class="mi">877&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="nx">_do_call&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">raise&lt;/span> &lt;span class="nx">CommandInvokeError&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">e&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="nx">e&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">discord&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">app_commands&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">errors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">CommandInvokeError&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">Command&lt;/span> &lt;span class="s1">&amp;#39;inicio&amp;#39;&lt;/span> &lt;span class="nx">raised&lt;/span> &lt;span class="nx">an&lt;/span> &lt;span class="nx">exception&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">DayAlreadyOpen&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">Já&lt;/span> &lt;span class="nx">existe&lt;/span> &lt;span class="nx">um&lt;/span> &lt;span class="nx">dia&lt;/span> &lt;span class="nx">aberto&lt;/span> &lt;span class="nx">para&lt;/span> &lt;span class="nx">este&lt;/span> &lt;span class="nx">usuário&lt;/span>&lt;span class="p">.&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Motivo&lt;/strong>:&lt;/p>
&lt;p>DayAlreadyOpen: Já existe um dia aberto para este usuário.
Isso acontece porque você executou /inicio, o bot abriu uma sessão no daily.db, e depois você chamou /inicio de novo sem antes fechar com /fim.&lt;/p>
&lt;p>&lt;strong>Explicação&lt;/strong>:&lt;/p>
&lt;p>Causa Técnica
O core está correto em impedir dois dias abertos:
if self._storage.get_open_session(user_id) is not None:
raise DayAlreadyOpen(&amp;ldquo;Já existe um dia aberto para este usuário.&amp;rdquo;)
O problema é que essa exceção está vazando até o Discord, gerando stack trace. O bot deveria responder algo amigável, como:
Já existe um dia aberto para você. Use /fim para fechar antes de iniciar outro.&lt;/p>
&lt;p>&lt;strong>Correções:&lt;/strong>&lt;/p>
&lt;p>Plano De Ajustes
Ainda em modo planejamento, então não vou editar arquivos agora. O ajuste recomendado é:&lt;/p>
&lt;ol>
&lt;li>Tratar DayAlreadyOpen no CommandRouter.inicio.&lt;/li>
&lt;li>Tratar NoOpenDay em /nota, /link e /fim.&lt;/li>
&lt;li>Evitar que exceções esperadas do core virem erro no Discord.&lt;/li>
&lt;li>Melhorar diagnóstico de ambiente Discord com DISCORD_CLIENT_ID.&lt;/li>
&lt;li>Documentar configuração local e produção no README.&lt;/li>
&lt;li>Adicionar testes para esses casos.&lt;/li>
&lt;/ol>
&lt;h2>Comportamento Esperado Após Ajustes&lt;span class="hx:absolute hx:-mt-20" id="comportamento-esperado-após-ajustes">&lt;/span>
&lt;a href="#comportamento-esperado-ap%c3%b3s-ajustes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Validar &lt;code>/inicio&lt;/code> com dia já aberto mas sem terminar atividades:
Deve retornar:
Mensagem:
🟡 Já existe um dia aberto para você. Use &lt;code>/continuar&lt;/code> para seguir o seu dia.
Comportamento: ao enviar comando &lt;code>/continue&lt;/code> deve seguir inserindo as atividades, do dia. Ou seja;&lt;/p>
&lt;p>&lt;strong>Cenário&lt;/strong>:
Dado que usuário envia o comando /iniciar no dia 1
E no dia 1 usuário envia o comando /iniciar
Quando retornar a mensagem: 🟡 Já existe um dia aberto para você. Use &lt;code>/continuar&lt;/code> para seguir o seu dia.
Então usuário deve inserir comando /continuar
E deve seguir até finalizar o dia&lt;/p>
&lt;p>Validar &lt;code>/nota&lt;/code> sem dia aberto:
Deve retornar:
Mensagem: ⚠️ Nenhum dia aberto. Use /inicio primeiro.&lt;/p>
&lt;p>Validar &lt;code>/fim&lt;/code> sem dia aberto:
Deve retornar:
Mensagem: ⚠️ Nenhum dia aberto para fechar. Use /inicio para começar.&lt;/p>
&lt;p>Validar &lt;code>/link&lt;/code> sem dia aberto:
Deve retornar:
Mensagem:
⚠️ Nenhum dia aberto. Use /inicio primeiro.&lt;/p>
&lt;ol>
&lt;li>Arquivos Que Devem Mudar&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>src/daily/command_router.py&lt;/li>
&lt;li>src/daily/adapters/discord_bot.py&lt;/li>
&lt;li>src/daily/main.py&lt;/li>
&lt;li>.env.example&lt;/li>
&lt;li>&lt;a href="http://readme.md/"target="_blank" rel="noopener">README.md&lt;/a>&lt;/li>
&lt;li>tests/test_ingest_and_report.py&lt;/li>
&lt;li>tests/test_discord_bot.py&lt;/li>
&lt;li>tests/test_main_config.py&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>O Que Mudou:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>src/daily/command_router.py&lt;/li>
&lt;li>/inicio com dia já aberto agora retorna:
🟡 Já existe um dia aberto para você. Use /continuar para seguir o seu dia.&lt;/li>
&lt;li>Novo método continuar.&lt;/li>
&lt;li>/nota, /link e /fim agora tratam NoOpenDay com mensagens amigáveis.&lt;/li>
&lt;li>/link agora verifica dia aberto antes de buscar/resumir URL.&lt;/li>
&lt;li>src/daily/adapters/discord_bot.py&lt;/li>
&lt;li>Adicionado comando Discord /continuar.&lt;/li>
&lt;li>Melhorado diagnóstico quando o bot não vê o servidor.&lt;/li>
&lt;li>Se DISCORD_CLIENT_ID estiver configurado, o erro imprime URL de convite correta.&lt;/li>
&lt;li>src/daily/main.py&lt;/li>
&lt;li>Adicionada validação de ambiente:
DISCORD_TOKEN obrigatório.
DISCORD_GUILD_ID numérico se informado.
DISCORD_CLIENT_ID numérico se informado.&lt;/li>
&lt;li>.env.example&lt;/li>
&lt;li>Adicionado DISCORD_CLIENT_ID.&lt;/li>
&lt;li>&lt;a href="http://readme.md/"target="_blank" rel="noopener">README.md&lt;/a>&lt;/li>
&lt;li>Documentado /continuar.&lt;/li>
&lt;li>Documentado ambiente local e produção.&lt;/li>
&lt;li>Adicionado troubleshooting do Discord.&lt;/li>
&lt;li>Testes adicionados para:&lt;/li>
&lt;li>/inicio com dia aberto.&lt;/li>
&lt;li>/continuar com e sem dia aberto.&lt;/li>
&lt;li>/nota, /link, /fim sem dia aberto.&lt;/li>
&lt;li>validação de DISCORD_CLIENT_ID e DISCORD_GUILD_ID.&lt;/li>
&lt;li>URL de convite no diagnóstico.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3>Visão Geral de Testes com Discord&lt;span class="hx:absolute hx:-mt-20" id="visão-geral-de-testes-com-discord">&lt;/span>
&lt;a href="#vis%c3%a3o-geral-de-testes-com-discord" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-4.png" alt="image.png" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h3>&lt;strong>Updates e Melhorias&lt;/strong>&lt;span class="hx:absolute hx:-mt-20" id="updates-e-melhorias">&lt;/span>
&lt;a href="#updates-e-melhorias" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Foi colocado um segundo canal de texto onde que, com o comando &lt;code>/fim&lt;/code> finaliza o report e adiciona no canal que fez a chamada, o release-notes do dia.&lt;/p>
&lt;p>Agora foi visto que precisa ser finalizada as atividades criadas no dia. Para isso segue a nova funcionalidade.&lt;/p>
&lt;p>&lt;strong>Funcionalidade&lt;/strong>: Dado que o usuário conclua e foi finalizada a “Tarefa” criada, Então deve adicionar o comando &lt;code>/fim-task&lt;/code> com a seguinte ação:&lt;/p>
&lt;p>&lt;strong>Comportamento esperado:&lt;/strong>&lt;/p>
&lt;p>URL: para adicionar o link de uma atividade concluida
Titulo Tarefa: Nome da Minha task aqui
Tempo da atividade aberta: xx minutos / xx horas / xx dias&lt;/p>
&lt;p>Dado que a atividade contém comentário,
Quando concluir ação
Então release notes deve mostrar comentários adicionada a ação&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-5.png" alt="image.png" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h3>Fluxo De Produção&lt;span class="hx:absolute hx:-mt-20" id="fluxo-de-produção">&lt;/span>
&lt;a href="#fluxo-de-produ%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>Criar canal #release-notes.&lt;/li>
&lt;li>Copiar o ID do canal.&lt;/li>
&lt;li>Criar app/bot no Discord.&lt;/li>
&lt;li>Convidar o bot com bot applications.commands.&lt;/li>
&lt;li>Criar projeto Railway conectado ao GitHub.&lt;/li>
&lt;li>Configurar secrets no Railway.&lt;/li>
&lt;li>Configurar volume persistente.&lt;/li>
&lt;li>Start command: python -m daily.main.&lt;/li>
&lt;li>Fazer deploy.&lt;/li>
&lt;li>Testar no Discord:&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>/inicio&lt;/li>
&lt;li>/nota&lt;/li>
&lt;li>/pr url:&lt;a href="https://github.com/.../pull/"target="_blank" rel="noopener">https://github.com/&amp;hellip;/pull/&lt;/a>&amp;hellip;&lt;/li>
&lt;li>/fim&lt;/li>
&lt;/ul></description></item><item><title>Crush: agente de codificação com (TUI/UI) - Configurações de Ambiente em Windows</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/</link><pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/</guid><description>
&lt;p>Seguindo a &lt;strong>saga de estudos em Terminais/TUIs&lt;/strong>, aqui vamos para o entendimento sobre o CRUSH em uma máquina Windows: como foi que configurei e como está sendo o uso até o momento, realizando um teste com um repositório open source bem simples, voltado à configuração de ambiente de desenvolvimento no Windows.&lt;/p>
&lt;h3>Objetivo principal&lt;span class="hx:absolute hx:-mt-20" id="objetivo-principal">&lt;/span>
&lt;a href="#objetivo-principal" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Permitir que desenvolvedores tenham &lt;strong>assistência de IA diretamente no terminal&lt;/strong>, sem precisar alternar para um editor web ou &lt;strong>IDE com plugins integrados&lt;/strong> — ou melhor, mais leve ao executar, por exemplo, do que o VS Code. O que a ferramenta oferece:&lt;/p>
&lt;ul>
&lt;li>Integração com &lt;strong>múltiplos provedores de modelos de IA&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Sessões&lt;/strong> com contexto preservado por projeto&lt;/li>
&lt;li>Interface &lt;strong>TUI (Text User Interface)&lt;/strong> interativa opcional&lt;/li>
&lt;li>&lt;strong>CLI tradicional&lt;/strong> para automação ou uso em scripts&lt;/li>
&lt;li>Extensibilidade via padrões como &lt;strong>Agent Skills&lt;/strong> e &lt;strong>MCP&lt;/strong> (Model Context Protocol)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Fonte&lt;/strong>: &lt;a href="https://github.com/charmbracelet/crush"target="_blank" rel="noopener">github crush&lt;/a>&lt;/p>
&lt;h3>Segue abaixo o primeiro teste em ambiente Windows&lt;span class="hx:absolute hx:-mt-20" id="segue-abaixo-o-primeiro-teste-em-ambiente-windows">&lt;/span>
&lt;a href="#segue-abaixo-o-primeiro-teste-em-ambiente-windows" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/configurando-windows.jpg" alt="Configurando o Crush no Windows" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h2>A usabilidade em uma máquina com OS Windows&lt;span class="hx:absolute hx:-mt-20" id="a-usabilidade-em-uma-máquina-com-os-windows">&lt;/span>
&lt;a href="#a-usabilidade-em-uma-m%c3%a1quina-com-os-windows" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Instalação&lt;/strong>: via PowerShell optei por seguir o comando&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># NPM
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm install -g @charmland/crush&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Neste caso, foi tranquilo, para fazer integração com &lt;a href="https://openai.com/pt-BR/api/"target="_blank" rel="noopener">API da OpenAI&lt;/a> primeiro precisa criar a &lt;a href="https://platform.openai.com/api-keys"target="_blank" rel="noopener">chave da API&lt;/a>, eu segui o &lt;a href="https://platform.openai.com/docs/quickstart?desktop-os=windows"target="_blank" rel="noopener">tutorial deles aqui&lt;/a> voltado para o windows nesse caso. Então nesse caso, copie a sua chave e reserve em um bloco de Notas. No Windows após instalação do CRUSH, no seguinte caminho: &lt;code>C:\Users\SEU_USER&lt;/code> conforme o Windows tudo fica sob esse caminho &lt;code>C:\Users\&amp;lt;SEU_USUARIO&amp;gt;\.config\crush\&lt;/code>&lt;/p>
&lt;p>Caso ainda não exista essa pasta, então crie: &lt;code>mkdir $HOME\.config\crush&lt;/code> então pode seguir, fazendo a integração com uma IA — no caso aqui provedor OpenAI — abaixo os comandos para criar uma variável de ambiente primeiro via terminal PowerShell.&lt;/p>
&lt;h3>Criar variável de ambiente&lt;span class="hx:absolute hx:-mt-20" id="criar-variável-de-ambiente">&lt;/span>
&lt;a href="#criar-vari%c3%a1vel-de-ambiente" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;code>setx OPENAI_API_KEY &amp;quot;sua_chave_aqui&amp;quot;&lt;/code>&lt;/p>
&lt;p>Como de costume, feche sempre o terminal e inicie um novo, verifique com o comando: &lt;code>echo $Env:OPENAI_API_KEY&lt;/code>&lt;/p>
&lt;p>Segue para verificar se o Crush está funcionando: &lt;code>crush --version&lt;/code> e caso mostrada a versão segue para o uso:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">crush&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>O terminal PowerShell irá carregar a UI da ferramenta então pode iniciar o uso. Neste exemplo de testes eu decidi refatorar um projeto de setup para Windows: &lt;a href="https://github.com/kellen-xavier/scripts-config-windows"target="_blank" rel="noopener">https://github.com/kellen-xavier/scripts-config-windows&lt;/a> — particularmente não muito interessante mas necessário, e também útil quando precisar reinstalar o mesmo — aqui eu primeiro via VS Code baixei o repositório — sim, neste caso utilizei por agora o editor, mas com os demais &lt;a href="https://github.com/charmbracelet"target="_blank" rel="noopener">plugins do charmbracelet&lt;/a> pode-se personalizar; o foco aqui não é esse.&lt;/p>
&lt;h3>Para os usos práticos&lt;span class="hx:absolute hx:-mt-20" id="para-os-usos-práticos">&lt;/span>
&lt;a href="#para-os-usos-pr%c3%a1ticos" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Perguntar sobre código do projeto atual: neste caso fui até a pasta do meu projeto&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd meu-projeto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">crush&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Primeira pergunta pedi para analisar o projeto: de forma mais geral, tipo possíveis bugs. Após ele me responder as respostas.&lt;/p>
&lt;blockquote>
&lt;p>analyze possible errors&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/analisando-erros.jpg" alt="Analisando erros conforme solicitado" loading="lazy" />&lt;/p>
&lt;p>Eu tinha esquecido de criar o arquivo &lt;a href="https://github.com/kellen-xavier/scripts-config-windows/blob/main/AGENTS.md"target="_blank" rel="noopener">AGENT.md&lt;/a>, o próprio CRUSH recomenda isso em tela, mas aí fui lá criar.&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Arquivo de script PowerShell para configuração Windows&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">Repositório&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">scripts&lt;/span> &lt;span class="n">voltado&lt;/span> &lt;span class="n">para&lt;/span> &lt;span class="n">Windows&lt;/span>&lt;span class="err">:&lt;/span> &lt;span class="n">instalar&lt;/span> &lt;span class="n">e&lt;/span> &lt;span class="n">personalizar&lt;/span> &lt;span class="n">via&lt;/span> &lt;span class="n">Shell&lt;/span> &lt;span class="n">Script&lt;/span>&lt;span class="p">.&lt;/span> &lt;span class="n">Este&lt;/span> &lt;span class="n">repositório&lt;/span> &lt;span class="n">foi&lt;/span> &lt;span class="n">criado&lt;/span> &lt;span class="n">com&lt;/span> &lt;span class="n">o&lt;/span> &lt;span class="n">intuito&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">facilitar&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="n">instalação&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">Aplicativos&lt;/span> &lt;span class="n">Windows&lt;/span>&lt;span class="p">.&lt;/span> &lt;span class="n">Criar&lt;/span> &lt;span class="n">o&lt;/span> &lt;span class="n">arquivo&lt;/span> &lt;span class="nb">programas-new&lt;/span>&lt;span class="n">-apps&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">ps1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">## REGRAS: O script deve conter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Implementar&lt;/span> &lt;span class="n">Testes&lt;/span> &lt;span class="n">com&lt;/span> &lt;span class="n">Pester&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Usar&lt;/span> &lt;span class="n">análise&lt;/span> &lt;span class="n">estática&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">código&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Usar&lt;/span> &lt;span class="n">winget&lt;/span> &lt;span class="n">como&lt;/span> &lt;span class="n">gerenciador&lt;/span> &lt;span class="n">principal&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Instale&lt;/span> &lt;span class="n">programas&lt;/span> &lt;span class="n">com&lt;/span> &lt;span class="n">segurança&lt;/span> &lt;span class="n">usando&lt;/span> &lt;span class="n">winget&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Verificar&lt;/span> &lt;span class="n">se&lt;/span> &lt;span class="n">o&lt;/span> &lt;span class="n">winget&lt;/span> &lt;span class="n">está&lt;/span> &lt;span class="n">instalado&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Instalar&lt;/span> &lt;span class="n">programas&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">forma&lt;/span> &lt;span class="n">idempotente&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">não&lt;/span> &lt;span class="n">reinstalar&lt;/span> &lt;span class="n">se&lt;/span> &lt;span class="n">já&lt;/span> &lt;span class="n">existir&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Usar&lt;/span> &lt;span class="n">parâmetros&lt;/span> &lt;span class="n">silenciosos&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Gerar&lt;/span> &lt;span class="n">log&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">execução&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Falhar&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">forma&lt;/span> &lt;span class="n">segura&lt;/span> &lt;span class="n">em&lt;/span> &lt;span class="n">caso&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">erro&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Não&lt;/span> &lt;span class="n">baixar&lt;/span> &lt;span class="n">executáveis&lt;/span> &lt;span class="n">diretamente&lt;/span> &lt;span class="n">da&lt;/span> &lt;span class="n">internet&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Seguir&lt;/span> &lt;span class="n">boas&lt;/span> &lt;span class="n">práticas&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">segurança&lt;/span> &lt;span class="n">no&lt;/span> &lt;span class="n">Windows&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Download&lt;/span> &lt;span class="n">e&lt;/span> &lt;span class="n">Execução&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">Script&lt;/span> &lt;span class="n">Externo&lt;/span> &lt;span class="n">com&lt;/span> &lt;span class="n">validação&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">Win11Debloat&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Instalar&lt;/span> &lt;span class="n">gerenciadores&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">versão&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">Instalação&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">Múltiplas&lt;/span> &lt;span class="n">Versões&lt;/span> &lt;span class="k">do&lt;/span> &lt;span class="n">Java&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">Node&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">js&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Deve&lt;/span> &lt;span class="n">conter&lt;/span> &lt;span class="n">blocos&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">help&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Script&lt;/span> &lt;span class="n">verifica&lt;/span> &lt;span class="n">conectividade&lt;/span> &lt;span class="n">antes&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">tentar&lt;/span> &lt;span class="n">downloads&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Adicionar&lt;/span> &lt;span class="n">Suporte&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="n">-WhatIf&lt;/span> &lt;span class="n">e&lt;/span> &lt;span class="n">-Confirm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Transformar&lt;/span> &lt;span class="n">scripts&lt;/span> &lt;span class="n">em&lt;/span> &lt;span class="n">módulo&lt;/span> &lt;span class="n">PowerShell&lt;/span> &lt;span class="n">com&lt;/span> &lt;span class="n">funções&lt;/span> &lt;span class="n">reutilizáveis&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Consistência&lt;/span> &lt;span class="n">nos&lt;/span> &lt;span class="n">Nomes&lt;/span> &lt;span class="n">dos&lt;/span> &lt;span class="n">Scripts&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Verificação&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">Código&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">Saída&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">uso&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="nv">$LASTEXITCODE&lt;/span> &lt;span class="n">para&lt;/span> &lt;span class="n">validar&lt;/span> &lt;span class="n">sucesso&lt;/span> &lt;span class="n">das&lt;/span> &lt;span class="n">operações&lt;/span> &lt;span class="n">winget&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Feedback&lt;/span> &lt;span class="n">Visual&lt;/span> &lt;span class="n">ao&lt;/span> &lt;span class="n">Usuário&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">uso&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="nb">Write-Host&lt;/span> &lt;span class="n">com&lt;/span> &lt;span class="n">cores&lt;/span> &lt;span class="n">para&lt;/span> &lt;span class="n">indicar&lt;/span> &lt;span class="n">status&lt;/span> &lt;span class="n">das&lt;/span> &lt;span class="n">operações&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">-&lt;/span> &lt;span class="n">Todos&lt;/span> &lt;span class="n">os&lt;/span> &lt;span class="n">scripts&lt;/span> &lt;span class="n">principais&lt;/span> &lt;span class="n">possuem&lt;/span> &lt;span class="n">verificação&lt;/span> &lt;span class="n">de&lt;/span> &lt;span class="n">permissões&lt;/span> &lt;span class="n">administrativas&lt;/span> &lt;span class="n">no&lt;/span> &lt;span class="n">início&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;h2>Liste exemplos comuns de software&lt;span class="hx:absolute hx:-mt-20" id="liste-exemplos-comuns-de-software">&lt;/span>
&lt;a href="#liste-exemplos-comuns-de-software" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;h3>Trabalho uso VPNs&lt;span class="hx:absolute hx:-mt-20" id="trabalho-uso-vpns">&lt;/span>
&lt;a href="#trabalho-uso-vpns" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>VPN: Netskope Client&lt;/li>
&lt;/ul>
&lt;h3>Aplicativos&lt;span class="hx:absolute hx:-mt-20" id="aplicativos">&lt;/span>
&lt;a href="#aplicativos" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Android Studio, BlueStacks 5, Bitwarden, Cursor, Docker Desktop, DBeaver Community, Discord, Flameshot, Global VPN Cliente, LibreOffice, Powershell, PowerToys Awake, Intellij IDEA Community Edition, ScreenToGif, sqldeveloper, Sublime Text Free, Teams, Insomnia, Obsidian, VS Code, Visual Studio Installer, Logitech G Hub&lt;/p>
&lt;h3>Navegadores&lt;span class="hx:absolute hx:-mt-20" id="navegadores">&lt;/span>
&lt;a href="#navegadores" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Google Chrome, Edge, Firefox, Opera&lt;/p>
&lt;h3>Linguagens Desenvolvimento&lt;span class="hx:absolute hx:-mt-20" id="linguagens-desenvolvimento">&lt;/span>
&lt;a href="#linguagens-desenvolvimento" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>JAVA 11, 17, 18+&lt;/li>
&lt;li>NodeJS&lt;/li>
&lt;li>Python&lt;/li>
&lt;/ul>
&lt;h2>Documentação README.md&lt;span class="hx:absolute hx:-mt-20" id="documentação-readmemd">&lt;/span>
&lt;a href="#documenta%c3%a7%c3%a3o-readmemd" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>Especifica versão mínima do Windows 10 (requer 1809+ para winget)&lt;/li>
&lt;li>Necessidade do App Installer atualizado&lt;/li>
&lt;li>Seção de troubleshooting&lt;/li>
&lt;/ul>
&lt;h3>Registry com Backup&lt;span class="hx:absolute hx:-mt-20" id="registry-com-backup">&lt;/span>
&lt;a href="#registry-com-backup" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$BackupPath&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$PSScriptRoot&lt;/span>&lt;span class="s2">\backup\registry-&lt;/span>&lt;span class="k">$(&lt;/span>Get-Date -Format &lt;span class="s1">&amp;#39;yyyyMMdd-HHmmss&amp;#39;&lt;/span>&lt;span class="k">)&lt;/span>&lt;span class="s2">.reg&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">reg &lt;span class="nb">export&lt;/span> &lt;span class="s2">&amp;#34;HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize&amp;#34;&lt;/span> &lt;span class="nv">$BackupPath&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;h2>PRIORIDADES DE CORREÇÃO PARA OS SCRIPTS EXISTENTES&lt;span class="hx:absolute hx:-mt-20" id="prioridades-de-correção-para-os-scripts-existentes">&lt;/span>
&lt;a href="#prioridades-de-corre%c3%a7%c3%a3o-para-os-scripts-existentes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>Prioridade 1 (Segurança): adicionar validação de hash para Win11Debloat, criar backup do registro antes de alterações, implementar Try-Catch em todos os scripts&lt;/li>
&lt;li>Prioridade 2 (Funcionalidade): implementar logging persistente, adicionar verificação de pré-requisitos, corrigir comando de navegador padrão&lt;/li>
&lt;li>Prioridade 3 (Manutenibilidade): adicionar parâmetros aos scripts, implementar idempotência, adicionar comment-based help&lt;/li>
&lt;/ul>
&lt;h2>Referências&lt;span class="hx:absolute hx:-mt-20" id="referências">&lt;/span>
&lt;a href="#refer%c3%aancias" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;a href="https://learn.microsoft.com/en-us/powershell/scripting/developer/help/examples-of-comment-based-help?view=powershell-7.5"target="_blank" rel="noopener">Examples of Comment-based Help&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices"target="_blank" rel="noopener">Native interoperability best practices&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands?view=powershell-7.5"target="_blank" rel="noopener">Approved Verbs for PowerShell Commands&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/PowerShell/PSScriptAnalyzer"target="_blank" rel="noopener">PSScriptAnalyzer&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://pester.dev/"target="_blank" rel="noopener">The test framework for Powershell&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://learn.microsoft.com/en-us/powershell/scripting/windows-powershell/starting-windows-powershell?view=powershell-7.4#with-administrative-privileges-run-as-administrator"target="_blank" rel="noopener">Starting Windows PowerShell&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Tentei por tudo o que entendi ser o correto desta vez para criar o setup, eu tive que ler as referências também para entender as boas práticas em torno disso, importante entender exatamente como vai montar o arquivo do AGENT pois ele fica mais estruturado.&lt;/p>
&lt;p>&lt;strong>Agora solicitei para executar o arquivo do AGENT&lt;/strong>: based on the AGENT.md file execute&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/executando-agent.jpg" alt="Executando o AGENT em um repositório de setup Windows com Crush" loading="lazy" />&lt;/p>
&lt;p>Com base no primeiro comando ele retornou:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/solicitacao-correcao.jpg" alt="Solicitação para correção" loading="lazy" />&lt;/p>
&lt;p>Processando o arquivo AGENT:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/processando-agent.jpg" alt="Processando o AGENT" loading="lazy" />&lt;/p>
&lt;p>No VS Code quis dar uma olhada em como ele estava se comportando:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/modificacoes-vscode.jpg" alt="Modificações vistas no VS Code" loading="lazy" />&lt;/p>
&lt;p>Executando Lint:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/executando-lint.jpg" alt="Executando lint" loading="lazy" />&lt;/p>
&lt;p>Executando Testes:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/executando-testes.jpg" alt="Executando testes" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/analyze-repo-update-readme.jpg" alt="Analisando o repositório e atualizando o README" loading="lazy" />&lt;/p>
&lt;p>Solicitei para fazer um update do README.md:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/update-readme.jpg" alt="Update no README.md" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/readme-update-ok.jpg" alt="README atualizado com sucesso" loading="lazy" />&lt;/p>
&lt;p>Estrutura final do projeto:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/estrutura-final-projeto.jpg" alt="Estrutura final do projeto" loading="lazy" />&lt;/p></description></item><item><title>Cola do BPMN</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/bpmn-fluxogramas/</link><pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/setembro/bpmn-fluxogramas/</guid><description>
&lt;p>Para quem esta começando a desenhar fluxogramas, segue as opções para os eventos do BPMN.&lt;/p>
&lt;p>Start inicia o fluxo, intermediate acontece no meio, boundary fica colado numa atividade para tratá-la, e end encerra o caminho. Regra de ouro: catch = espera algo; throw = dispara algo.&lt;/p>
&lt;hr>
&lt;h2>Start events (iniciam o processo)&lt;span class="hx:absolute hx:-mt-20" id="start-events-iniciam-o-processo">&lt;/span>
&lt;a href="#start-events-iniciam-o-processo" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Start event (none):&lt;/strong> começa sem condição.&lt;/li>
&lt;li>&lt;strong>Message start:&lt;/strong> inicia quando chega uma mensagem (ex.: webhook).&lt;/li>
&lt;li>&lt;strong>Timer start:&lt;/strong> agenda/cron (data, atraso, repetição).&lt;/li>
&lt;li>&lt;strong>Conditional start:&lt;/strong> começa quando uma expressão fica verdadeira.&lt;/li>
&lt;li>&lt;strong>Signal start:&lt;/strong> começa ao receber um &amp;ldquo;broadcast&amp;rdquo; (sinal geral).&lt;/li>
&lt;/ul>
&lt;h2>Intermediate events (no meio do fluxo)&lt;span class="hx:absolute hx:-mt-20" id="intermediate-events-no-meio-do-fluxo">&lt;/span>
&lt;a href="#intermediate-events-no-meio-do-fluxo" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Message intermediate (throw):&lt;/strong> envia mensagem a outro participante.&lt;/li>
&lt;li>&lt;strong>Timer intermediate (catch):&lt;/strong> espera um tempo/data.&lt;/li>
&lt;li>&lt;strong>Escalation intermediate (throw):&lt;/strong> avisa/escalona sem tratar como erro.&lt;/li>
&lt;li>&lt;strong>Conditional intermediate (catch):&lt;/strong> pausa até a condição ficar verdadeira.&lt;/li>
&lt;li>&lt;strong>Link (catch/throw):&lt;/strong> &amp;ldquo;teletransporte&amp;rdquo; dentro do mesmo diagrama (conecta pontos).&lt;/li>
&lt;li>&lt;strong>Compensation intermediate (throw):&lt;/strong> dispara compensação (desfazer algo).&lt;/li>
&lt;li>&lt;strong>Signal intermediate (catch/throw):&lt;/strong> pub/sub (broadcast) – qualquer ouvinte capta.&lt;/li>
&lt;/ul>
&lt;h2>Boundary events (colados numa tarefa/subprocesso)&lt;span class="hx:absolute hx:-mt-20" id="boundary-events-colados-numa-tarefasubprocesso">&lt;/span>
&lt;a href="#boundary-events-colados-numa-tarefasubprocesso" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Disparam quando ocorre algo &lt;strong>durante&lt;/strong> a atividade.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Interrupting (borda contínua):&lt;/strong> cancela a atividade e desvia o fluxo.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Non-interrupting (borda tracejada):&lt;/strong> cria um fluxo alternativo sem cancelar.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Tipos comuns: &lt;strong>Timer, Message, Conditional, Signal, Escalation, Compensation&lt;/strong>.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3>Especiais&lt;span class="hx:absolute hx:-mt-20" id="especiais">&lt;/span>
&lt;a href="#especiais" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;strong>Error boundary:&lt;/strong> só interruptivo; captura erros do subprocesso.
&lt;strong>Cancel boundary:&lt;/strong> só em &lt;strong>Transaction subprocess&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>As variações &lt;strong>(non-interrupting)&lt;/strong> mantêm a atividade rodando.&lt;/li>
&lt;/ul>
&lt;h2>End events (encerram o caminho)&lt;span class="hx:absolute hx:-mt-20" id="end-events-encerram-o-caminho">&lt;/span>
&lt;a href="#end-events-encerram-o-caminho" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Message end:&lt;/strong> envia mensagem e termina.&lt;/li>
&lt;li>&lt;strong>Escalation end:&lt;/strong> notifica o nível acima e termina.&lt;/li>
&lt;li>&lt;strong>Error end:&lt;/strong> lança erro; sai do subprocesso até um &lt;em>error boundary&lt;/em> capturar.&lt;/li>
&lt;li>&lt;strong>Cancel end:&lt;/strong> cancela uma &lt;strong>Transaction&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Compensation end:&lt;/strong> solicita compensações registradas.&lt;/li>
&lt;li>&lt;strong>Signal end:&lt;/strong> emite sinal (broadcast) e termina.&lt;/li>
&lt;li>&lt;strong>Terminate end:&lt;/strong> mata &lt;strong>todas&lt;/strong> as atividades ativas do processo/subprocesso.&lt;/li>
&lt;/ul></description></item><item><title>Aprofundamento sobre: Terminal Comandos Git - Parte 1</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/comandos-git/</link><pubDate>Tue, 17 Jun 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/comandos-git/</guid><description>
&lt;p>Esse post começou com a ideia de ser somente sobre alguns &amp;ldquo;comandos de Git&amp;rdquo; que são práticos no dia a dia. Porém, eu não tinha nada por escrito que reunisse um compilado de estudos sobre o assunto de terminais também: o que é um terminal, como usar um, onde ler mais sobre terminais, antes de entrar em comandos Git.&lt;/p>
&lt;p>&lt;em>Eu sempre comento que é importante saber usar o terminal. Minimamente, precisamos saber usar essas ferramentas; não adianta fugir disso, mesmo que tua IDE seja perfeita e toda visual, pois inevitavelmente vamos ter que lidar com problemas fora da interface visual.&lt;/em>&lt;/p>
&lt;p>Eu gosto da metáfora de dirigir um carro, por exemplo: eu imagino como se tu estivesses dirigindo um carro, ele para depois de apitar e tu precisas abrir o capô do carro para ver o que aconteceu. Pode ser um BYD totalmente automático, mas esse carro contém logs, uma caixa-preta — chamada EDR (Event Data Recorder). Aqui vou usar o termo &amp;ldquo;sujar as mãos&amp;rdquo; e não ter medo de comandos assim; entender como funciona por baixo dos panos traz uma clareza muito mais profunda.&lt;/p>
&lt;hr>
&lt;h2>Alguns Conceitos Base Importantes&lt;span class="hx:absolute hx:-mt-20" id="alguns-conceitos-base-importantes">&lt;/span>
&lt;a href="#alguns-conceitos-base-importantes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;h3>O que é um terminal&lt;span class="hx:absolute hx:-mt-20" id="o-que-é-um-terminal">&lt;/span>
&lt;a href="#o-que-%c3%a9-um-terminal" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Um terminal é uma interface de texto para interação direta com o sistema operacional. Ele envia comandos ao shell (ex.: Bash, Zsh, PowerShell), que interpreta e executa instruções usando as APIs do sistema.&lt;/p>
&lt;h3>Fontes sobre Terminais - Lista de leituras e vídeos&lt;span class="hx:absolute hx:-mt-20" id="fontes-sobre-terminais---lista-de-leituras-e-vídeos">&lt;/span>
&lt;a href="#fontes-sobre-terminais---lista-de-leituras-e-v%c3%addeos" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;a href="https://pt.wikipedia.org/wiki/Terminal_%28inform%C3%A1tica%29"target="_blank" rel="noopener">Wikipédia&lt;/a>
&lt;a href="https://akitaonrails.com/2020/02/05/akitando-70-entendendo-git-nao-e-um-tutorial/"target="_blank" rel="noopener">[Akitando] #70 - Entendendo GIT | (não é um tutorial!)&lt;/a>
&lt;a href="https://akitaonrails.com/2020/02/12/akitando-71-usando-git-direito-limpando-seus-commits/"target="_blank" rel="noopener">[Akitando] #71 - Usando Git Direito | Limpando seus Commits!&lt;/a>&lt;/p>
&lt;h3>Sistema de arquivos e navegação&lt;span class="hx:absolute hx:-mt-20" id="sistema-de-arquivos-e-navegação">&lt;/span>
&lt;a href="#sistema-de-arquivos-e-navega%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Quando de modo geral, vamos navegar em um terminal, ou seja, entrar e sair de pastas manipular arquivos, é igual como se fosse navegar em uma tela, mas aqui é por comandos. Quando aqui a gente dizer &amp;ldquo;faça tal coisa no repositório projeto/automação&amp;rdquo; estamos comentando que é dentro da pasta em questão.&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/comandos-git/navegando-em-pastas.png" alt="Navegando em pastas" loading="lazy" />&lt;/p>
&lt;p>Visualmente temos, uma tela e onde precisa navegar. Quando abri o terminal (exemplo no ambiente Windows) talvez você veja algo como &lt;code>C:\Users\meu.nome\Sua-pasta&lt;/code> no exemplo da imagem seria algo como: &lt;code>C:\Users\kellen.xavier\Documents\Estudos\docs-estudos-obsidian&lt;/code> aqui minha organização pessoal é por em Documentos, dentro da pasta estudo, então aqui quando me referir a &amp;ldquo;entre no projeto de estudos obsidian, faça o git pull&amp;rdquo;.&lt;/p>
&lt;p>Exemplo abaixo uma pasta qualquer, aí tenho que ir só que agora via terminal: se por acaso (a grande maioria abrir o terminal) vai ser algo parecido assim:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">PS C:\Users\kellen.xavier&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Então vem os comandos para navegar até ele.&lt;/p>
&lt;h3>Comandos geralmente mais utilizados&lt;span class="hx:absolute hx:-mt-20" id="comandos-geralmente-mais-utilizados">&lt;/span>
&lt;a href="#comandos-geralmente-mais-utilizados" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Navegação:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">pwd # mostra o diretório atual
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ls # lista arquivos e pastas
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ls -la # lista detalhada (inclui ocultos)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cd pasta # entra na pasta
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cd .. # volta um nível
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cd ~ # vai para a home&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Se clicar aqui na barra conseguimos ver os caminhos a partir de kellen.xavier&lt;/strong> (meu caso) → eu estou aqui: &lt;code>C:\Users\kellen.xavier\Documents\Estudos\docs-estudos-obsidian&lt;/code> então via terminal:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">Documents&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Estudos&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">docs-estudos&lt;/span>&lt;span class="n">-obsidian&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Aqui entrei na pasta:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/comandos-git/entrando-na-pasta.png" alt="Entrando na pasta pelo terminal" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h2>GIT&lt;span class="hx:absolute hx:-mt-20" id="git">&lt;/span>
&lt;a href="#git" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Segue abaixo uma sequência de comandos para utilizar, quando se (e principalmente) está trabalhando em projetos com mais de uma pessoa atuando. — Não esquecer —&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/comandos-git/pc-fire.png" alt="PC pegando fogo" loading="lazy" />&lt;/p>
&lt;p>&lt;strong>Para fazer um merge da sua branch atual para a branch principal (&amp;ldquo;main&amp;rdquo;), você pode seguir esses passos:&lt;/strong>&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout sua-branch
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git fetch origin &lt;span class="c1"># Puxa as últimas informações do repositório remoto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git rebase origin/main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Atualiza sua branch com as alterações da branch main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git rebase origin/main &lt;span class="c1"># Atualiza sua branch com as alterações da branch main&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Depois de ter sua branch (de desenvolvimento) atualizada, execute o comando git checkout para mudar para a branch &amp;ldquo;develop&amp;rdquo; (ou main):&lt;/strong>&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout develop&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Agora você está na branch &amp;ldquo;develop&amp;rdquo;. Realize o merge da sua branch de desenvolvimento usando o seguinte comando:&lt;/strong>&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git merge sua-branch&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;hr>
&lt;h2>Brevemente sobre Pull Request&lt;span class="hx:absolute hx:-mt-20" id="brevemente-sobre-pull-request">&lt;/span>
&lt;a href="#brevemente-sobre-pull-request" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>O objetivo de criar um Pull Request (PR) no GitHub (ou em outras plataformas de controle de versão) &lt;strong>é propor mudanças em um projeto de forma colaborativa e controlada&lt;/strong>. Ao criar um Pull Request, você está solicitando que suas alterações em um branch (ramo) específico sejam revisadas e, se aprovadas, incorporadas (mescladas) ao branch principal do projeto, como o main ou develop.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Agora vamos para o seguinte cenário&lt;/strong>: se caso você precise trabalhar especificamente com uma branch &lt;strong>que não é a main&lt;/strong>, você precisará criar uma nova branch local baseada na branch remota desejada. Suponhamos que você queira trabalhar na branch minha-branch:&lt;/p>
&lt;p>&lt;strong>Dado isso, segue o comando git:&lt;/strong>&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout -b minha-branch origin/minha-branch-remota-desejada&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Isso irá criar uma nova branch local chamada &lt;code>minha-branch&lt;/code> baseada na branch remota &lt;code>origin/minha-branch-remota-desejada&lt;/code>.&lt;/p>
&lt;p>Com esse comando, pode-se trabalhar com a &lt;strong>branch localmente&lt;/strong>, e fazer commits e outras operações como de costume.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Comandos do dia-a-dia:&lt;/strong>&lt;/p>
&lt;p>Antes de tudo, quando for iniciar o desenvolvimento no projeto, atualize seu ambiente local com o seu repositório remoto.&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git pull&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Ao fazer isso, seu ambiente local se atualiza com as demais alterações feitas pelos colaboradores do projeto em que estão envolvidos.&lt;/p>
&lt;p>O comando git pull é usado para buscar (&lt;code>fetch&lt;/code>) as alterações mais recentes de um repositório remoto e, em seguida, fazer um merge dessas alterações na branch atual em que você está trabalhando. Em outras palavras, ele combina os passos de &lt;code>git fetch&lt;/code> e &lt;code>git merge&lt;/code> em um único comando.&lt;/p>
&lt;p>Outro exemplo de git pull:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git pull &amp;lt;remote&amp;gt; &amp;lt;branch&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Onde &lt;code>&amp;lt;remote&amp;gt;&lt;/code> é o nome do repositório remoto de onde você deseja puxar as alterações (geralmente &amp;ldquo;&lt;code>origin&lt;/code>&amp;rdquo;) e &lt;code>&amp;lt;branch&amp;gt;&lt;/code> é a branch remota da qual você deseja puxar as alterações (por exemplo, &amp;ldquo;&lt;code>main&lt;/code>&amp;rdquo;, &amp;ldquo;&lt;code>develop&lt;/code>&amp;rdquo;, etc.).&lt;/p>
&lt;h3>Alterações feitas&lt;span class="hx:absolute hx:-mt-20" id="alterações-feitas">&lt;/span>
&lt;a href="#altera%c3%a7%c3%b5es-feitas" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Para enviar suas alterações para o repositório remoto, é preciso adicionar, seguindo de um comentário do que foi feito.&lt;/p>
&lt;p>Adicionar alteração:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git add .&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>⚠️ Cuidado ao utilizar o &lt;code>git add .&lt;/code> pois ele vai adicionar todas alterações realizadas. E isso precisa de atenção. Evite usar, recomenda-se utilizar o:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git add nome-do-arquivo-ou-pasta&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Após realizar faça o comentário:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git commit -m &lt;span class="s2">&amp;#34;padrao-de-commit: minha mensagem&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Leia aqui (por link depois) para saber mais sobre padrões de commits.&lt;/strong>&lt;/p>
&lt;p>Agora, analise o seu terminal, se caso não tiver nenhum erro ou conflito, pode seguir para subir as alterações:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git push&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>Para mesclar sua branch com a &lt;code>main&lt;/code> no repositório, faça:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git merge sua-branch&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;hr>
&lt;h2>Sobre git stash&lt;span class="hx:absolute hx:-mt-20" id="sobre-git-stash">&lt;/span>
&lt;a href="#sobre-git-stash" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>O comando &lt;code>git stash&lt;/code> é utilizado para armazenar temporariamente as alterações que você fez no seu diretório de trabalho, permitindo que você volte ao estado anterior do repositório sem precisar fazer commit das alterações. Isso é útil quando você deseja alternar rapidamente entre diferentes tarefas ou branches sem comprometer as alterações que não estão prontas para serem confirmadas.&lt;/p>
&lt;p>Aqui estão alguns exemplos de como você pode usar o &lt;code>git stash&lt;/code>:&lt;/p>
&lt;p>&lt;strong>Armazenar Alterações Temporariamente:&lt;/strong> se você fez algumas alterações no seu diretório de trabalho, mas ainda não deseja commitá-las, você pode usar o seguinte comando para armazená-las temporariamente:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git stash save &lt;span class="s2">&amp;#34;Descrição opcional&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>A descrição é opcional e pode ajudar a identificar por que você armazenou essas alterações.&lt;/p>
&lt;p>&lt;strong>Listar Stashes:&lt;/strong> você pode listar os stashes que você criou usando o seguinte comando:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git stash list&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Aplicar Stash:&lt;/strong> para aplicar o stash mais recente (ou um &lt;code>stash&lt;/code> específico), você pode usar:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git stash apply &lt;span class="c1"># Aplica o stash mais recente&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git stash apply stash@&lt;span class="o">{&lt;/span>n&lt;span class="o">}&lt;/span> &lt;span class="c1"># Aplica um stash específico pelo seu índice&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Remover Stash:&lt;/strong> depois de aplicar um stash, você pode removê-lo:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git stash drop &lt;span class="c1"># Remove o stash mais recente&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git stash drop stash@&lt;span class="o">{&lt;/span>n&lt;span class="o">}&lt;/span> &lt;span class="c1"># Remove um stash específico pelo seu índice&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Criar uma Nova Branch a partir do Stash:&lt;/strong> se você quiser criar uma nova branch baseada em um stash, pode usar:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git stash branch nova-branch &lt;span class="c1"># Cria uma nova branch e aplica o stash nela&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;hr>
&lt;p>&lt;strong>Outros pontos importantes:&lt;/strong>&lt;/p>
&lt;p>Atualize sua &lt;strong>branch&lt;/strong> com &lt;strong>as últimas alterações da branch principal&lt;/strong> (&amp;ldquo;main&amp;rdquo;). Isso ajudará a &lt;strong>evitar conflitos durante o merge&lt;/strong>. Execute os seguintes comandos:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git fetch origin &lt;span class="c1"># Puxa as últimas informações do repositório remoto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase origin/main &lt;span class="c1"># Atualiza sua branch com as alterações da branch main&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>⚠️ &lt;strong>Atenção&lt;/strong>&lt;/p>
&lt;p>Não faça git pull nessas situações. Leia novamente o que é &lt;strong>git pull&lt;/strong>.&lt;/p></description></item><item><title>As práticas ruins que devem ser evitadas em uma automação de testes</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/praticas-ruins-de-testes-para-evitar-ou/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/praticas-ruins-de-testes-para-evitar-ou/</guid><description>
&lt;p>Leia isso, imprimir, talvez imprima e cole no computador de uns aí…&lt;/p>
&lt;hr>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/praticas-ruins-de-testes-para-evitar-ou/cat-cansado.png" alt="Gato cansado" loading="lazy" />&lt;/p>
&lt;h2>1. Definição e Planejamento Inadequados&lt;span class="hx:absolute hx:-mt-20" id="1-definição-e-planejamento-inadequados">&lt;/span>
&lt;a href="#1-defini%c3%a7%c3%a3o-e-planejamento-inadequados" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Falta de Objetivos Claros:&lt;/strong> não definir claramente o objetivo da automação, os riscos envolvidos, o escopo e as partes interessadas. A automação sem objetivos bem definidos pode levar a esforços desperdiçados e resultados insatisfatórios.&lt;/p>
&lt;p>&lt;strong>Estratégia de Automação Mal Definida&lt;/strong>: não ter uma estratégia de automação de teste que seja aplicável, personalizável e mantida atualizada. Uma estratégia mal definida pode resultar em testes ineficientes e difíceis de manter.&lt;/p>
&lt;p>&lt;strong>Não Considerar Critérios de Investimento:&lt;/strong> ignorar fatores como custo inicial, fase do SDLC, duração do projeto e custo de manutenção ao decidir sobre a automação. A falta de análise desses fatores pode levar a investimentos inadequados e pouco retorno.&lt;/p>
&lt;p>&lt;strong>Não priorizar testes:&lt;/strong> não priorizar as condições de teste mais impactantes do ponto de vista do negócio. É preciso focar nos esforços de automação nos testes que trarão mais valor.&lt;/p>
&lt;hr>
&lt;h2>2. Aspectos Técnicos Problemáticos&lt;span class="hx:absolute hx:-mt-20" id="2-aspectos-técnicos-problemáticos">&lt;/span>
&lt;a href="#2-aspectos-t%c3%a9cnicos-problem%c3%a1ticos" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Má Testabilidade do SUT:&lt;/strong> automatizar um Sistema em Teste (SUT) que não é facilmente testável, dificultando o acesso às suas interfaces. A testabilidade é essencial para uma automação eficaz.&lt;/p>
&lt;p>&lt;strong>Arquitetura e Framework de Automação Ruins:&lt;/strong> não ter uma Arquitetura de Automação de Teste (TAA) clara e um Framework de Automação de Teste (TAF) fácil de usar e manter. Uma má arquitetura e framework podem levar a dificuldades na implementação e manutenção dos testes automatizados.&lt;/p>
&lt;p>&lt;strong>Relatórios de Teste Deficientes:&lt;/strong> não gerar relatórios de teste bem definidos, dificultando a solução de problemas e o acompanhamento dos resultados. A falta de relatórios claros impede a tomada de decisões eficazes.&lt;/p>
&lt;p>&lt;strong>Não ter um plano de implantação e execução:&lt;/strong> não ter um plano claro de implantação e execução de testes, remoção de testes quando necessário e tratamento eficaz de exceções. Sem esses planos, os testes podem não ser executados corretamente, ou causar problemas na execução.&lt;/p>
&lt;p>&lt;strong>Não Documentar os Casos de Teste:&lt;/strong> não documentar adequadamente os casos de teste automatizados, tornando-os difíceis de entender e manter. A documentação clara é crucial para a manutenção e rastreabilidade dos testes.&lt;/p>
&lt;hr>
&lt;h2>3. Escolha e Aplicação Inadequadas da Automação&lt;span class="hx:absolute hx:-mt-20" id="3-escolha-e-aplicação-inadequadas-da-automação">&lt;/span>
&lt;a href="#3-escolha-e-aplica%c3%a7%c3%a3o-inadequadas-da-automa%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Automatizar Testes Impróprios:&lt;/strong> escolher casos de teste para automação sem considerar a viabilidade técnica, esforço de codificação, frequência de execução, repetibilidade e facilidade de manutenção. Nem todos os testes são adequados para automação.&lt;/p>
&lt;p>&lt;strong>Automatizar Testes Difíceis:&lt;/strong> tentar automatizar condições de teste difíceis, como validações de design, interações humanas complexas e restrições técnicas no nível do sistema operacional. Alguns testes são mais eficazes quando realizados manualmente.&lt;/p>
&lt;p>&lt;strong>Focar apenas em testes de interface do usuário:&lt;/strong> criar uma estratégia que dependa principalmente de testes de interface do usuário (UI), que são caros e de difícil manutenção. Uma estratégia de testes equilibrada deve incluir testes de componentes, contrato e API.&lt;/p>
&lt;p>&lt;strong>Não otimizar a distribuição de testes:&lt;/strong> não equilibrar a quantidade de testes nos diferentes níveis (componente, serviço e UI), o que pode resultar em testes lentos e caros. É preciso buscar uma distribuição em forma de pirâmide para melhor eficiência.&lt;/p>
&lt;hr>
&lt;h2>4. Transição e Manutenção Ineficazes&lt;span class="hx:absolute hx:-mt-20" id="4-transição-e-manutenção-ineficazes">&lt;/span>
&lt;a href="#4-transi%c3%a7%c3%a3o-e-manuten%c3%a7%c3%a3o-ineficazes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Não Monitorar os Custos:&lt;/strong> não acompanhar os custos e o crescimento da suíte de testes durante a transição para testes contínuos. O monitoramento dos custos e do crescimento da suíte de testes é necessário para uma transição eficiente.&lt;/p>
&lt;p>&lt;strong>Sobreposição Funcional:&lt;/strong> criar scripts de teste com sobreposição funcional, como incluir as mesmas etapas de login em diferentes casos de teste. Isso dificulta a manutenção e aumenta o esforço necessário.&lt;/p>
&lt;p>&lt;strong>Compartilhamento de Dados Inadequados:&lt;/strong> não gerenciar corretamente o compartilhamento de dados entre os testes, levando à duplicação ou introdução de erros. Os dados devem ser armazenados e acessados de uma única fonte.&lt;/p>
&lt;p>&lt;strong>Não Documentar Pré-Condições:&lt;/strong> não documentar e automatizar as pré-condições necessárias para a execução dos testes, levando a falhas e inconsistências. É essencial definir e automatizar as pré-condições para garantir a repetibilidade dos testes.&lt;/p>
&lt;p>&lt;strong>Não Testar os Testes Automatizados:&lt;/strong> esquecer de que a automação é um software que também precisa ser testado. Os scripts de teste devem ser testados para garantir que funcionem corretamente.&lt;/p>
&lt;p>&lt;strong>Não Refatorar a Automação:&lt;/strong> não avaliar e refatorar a solução de automação, levando ao acúmulo de dívida técnica e dificuldades na manutenção. É preciso buscar melhorias contínuas e otimizações.&lt;/p>
&lt;p>&lt;strong>Não Adaptar a TAS às Mudanças&lt;/strong>: não adaptar a Solução de Automação de Teste (TAS) às novas versões do SUT. A TAS deve ser flexível e adaptável para acompanhar as mudanças no sistema.&lt;/p>
&lt;hr>
&lt;h2>5. Outras Práticas Ruins&lt;span class="hx:absolute hx:-mt-20" id="5-outras-práticas-ruins">&lt;/span>
&lt;a href="#5-outras-pr%c3%a1ticas-ruins" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Abstração Excessiva:&lt;/strong> utilizar abstrações excessivas que tornam o código de automação difícil de entender. A abstração deve ser usada com moderação para manter o código compreensível.&lt;/p>
&lt;p>&lt;strong>Tabelas de Dados Complexas:&lt;/strong> criar tabelas de dados de teste muito grandes e complexas, dificultando a migração para outros ambientes. Os dados de teste devem ser gerenciados de forma eficiente.&lt;/p>
&lt;p>&lt;strong>Dependências de Bibliotecas:&lt;/strong> criar dependências da TAS em bibliotecas ou componentes do sistema operacional que podem não estar disponíveis em todos os ambientes. A TAS deve ser independente e portável entre diferentes ambientes de teste.&lt;/p>
&lt;p>&lt;strong>Ignorar a Importância da Manutenção&lt;/strong>: deixar de planejar a manutenção da TAS devido a atualizações no SUT. A manutenção contínua da TAS é essencial para garantir sua eficácia.&lt;/p>
&lt;p>&lt;strong>Não usar métricas:&lt;/strong> não acompanhar métricas como taxa de aprovação/reprovação, proporção de falhas e defeitos, tempo de execução da automação, cobertura funcional e de código. Essas métricas ajudam a avaliar e otimizar a TAS.&lt;/p>
&lt;p>&lt;strong>Não aproveitar os resultados dos testes para melhorar o processo:&lt;/strong> não analisar os dados gerados nos relatórios de teste para identificar tendências e fazer melhorias no SDLC. Os dados dos testes devem ser usados para tomada de decisões e melhoria contínua.&lt;/p>
&lt;p>Feito por: Kellen Xavier | &lt;a href="https://keepo.io/ladydebug/"target="_blank" rel="noopener">Contato&lt;/a>&lt;/p></description></item><item><title>Passo a Passo para Adicionar o Shift-Left Testing no Processo de Qualidade</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/processo-shift-left-testing-basico/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/processo-shift-left-testing-basico/</guid><description>
&lt;p>Segue um breve resumo de aplicar um mínimo de processo de qualidade em um time.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Objetivo: Adotar o uso de backlog para refinar User Stories para desenvolvimento:&lt;/strong> criar um backlog de tarefas e atividades relacionadas ao teste desde o início do ciclo de desenvolvimento.&lt;/p>
&lt;p>&lt;strong>Escrever User Stories com Critérios de Aceitação (Separar Fluxo Completo em Funcionalidades):&lt;/strong>&lt;/p>
&lt;p>Identificar os requisitos de teste para cada funcionalidade através de User Stories. Incluir critérios de aceitação claros e específicos para garantir que cada funcionalidade seja testada adequadamente.&lt;/p>
&lt;p>&lt;strong>Desenvolver Casos de Teste para cada User Story:&lt;/strong> escrever casos de teste que abranjam todos os aspectos da funcionalidade descrita na User Story. Incluir casos de teste para cenários de sucesso e cenários de falha, abrangendo diferentes caminhos de uso.&lt;/p>
&lt;p>&lt;strong>Realizar Testes Estáticos e Análises Antes do Desenvolvimento:&lt;/strong> realizar revisões de código estáticas e análises de documentos para identificar potenciais problemas antes do início do desenvolvimento. Utilizar ferramentas de análise estática para identificar possíveis vulnerabilidades ou erros no código fonte.&lt;/p>
&lt;p>&lt;strong>Integrar Testes Automatizados na Esteira de Desenvolvimento:&lt;/strong> automatizar testes unitários, de integração e de regressão para garantir a estabilidade das funcionalidades desenvolvidas. Integrar os testes automatizados na esteira de desenvolvimento para execução contínua após cada alteração no código.&lt;/p>
&lt;p>&lt;strong>Implementar Revisões Contínuas e Feedback Iterativo:&lt;/strong> realizar revisões contínuas de código e funcionalidades em desenvolvimento para identificar e corrigir problemas rapidamente. Fornecer feedback iterativo aos desenvolvedores e equipe de qualidade para melhorar o processo de desenvolvimento.&lt;/p>
&lt;p>&lt;strong>Documentar e Analisar Métricas de Qualidade e Desempenho:&lt;/strong> registrar métricas de qualidade, cobertura de testes e desempenho do software para avaliar a eficácia dos testes e identificar áreas de melhoria. Analisar regularmente os resultados dos testes para ajustar estratégias de teste conforme necessário.&lt;/p></description></item><item><title>Passo a Passo para Dev Teste (Baseado na Pirâmide de Testes)</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/piramide-de-testes-para-dev/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/piramide-de-testes-para-dev/</guid><description>
&lt;h3>1. O que é Dev Teste?&lt;span class="hx:absolute hx:-mt-20" id="1-o-que-é-dev-teste">&lt;/span>
&lt;a href="#1-o-que-%c3%a9-dev-teste" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Antes de enviar um card para o status QA, o time de desenvolvimento deve validar o código aplicando testes sistemáticos em diferentes camadas (unitário, integração, funcional). Isso reduz retrabalho e melhora a qualidade do software.&lt;/p>
&lt;h3>2. Estruturando os Testes&lt;span class="hx:absolute hx:-mt-20" id="2-estruturando-os-testes">&lt;/span>
&lt;a href="#2-estruturando-os-testes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>A pirâmide de testes sugere:&lt;/p>
&lt;ul>
&lt;li>Leitura das US/Histórias de Usuário - Leitura dos testes que compõem a US e os critérios de aceite.&lt;/li>
&lt;li>&lt;strong>Testes Unitários (Base da pirâmide):&lt;/strong> Validam partes isoladas do código (ex.: funções, métodos).&lt;/li>
&lt;li>&lt;strong>Testes de Integração (Meio da pirâmide):&lt;/strong> Garantem que diferentes partes do sistema interagem corretamente.&lt;/li>
&lt;li>&lt;strong>Testes Funcionais/E2E (Topo da pirâmide):&lt;/strong> Validam o fluxo completo de usuário.&lt;/li>
&lt;/ul>
&lt;h3>3. Como aplicar no cenário do bug?&lt;span class="hx:absolute hx:-mt-20" id="3-como-aplicar-no-cenário-do-bug">&lt;/span>
&lt;a href="#3-como-aplicar-no-cen%c3%a1rio-do-bug" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;h3>Passo 1: Teste Unitário&lt;span class="hx:absolute hx:-mt-20" id="passo-1-teste-unitário">&lt;/span>
&lt;a href="#passo-1-teste-unit%c3%a1rio" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>✅ Criar testes para a query que busca o domínio correto no banco.&lt;/p>
&lt;ul>
&lt;li>Verificar se a query está retornando apenas domínios do tipo &lt;em>blog&lt;/em>.&lt;/li>
&lt;li>Garantir que não seja selecionado o primeiro domínio indiscriminadamente.&lt;/li>
&lt;/ul>
&lt;p>Exemplo de teste unitário (PHPUnit):&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span> &lt;span class="k">function&lt;/span> &lt;span class="nf">testBuscaDominioCorreto&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">$dominio&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">DominioRepository&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">$resultado&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nv">$dominio&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="na">buscarPorTipo&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;blog&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">$this&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="na">assertNotEmpty&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">$resultado&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">$this&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="na">assertEquals&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;blog&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nv">$resultado&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="na">tipo&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;hr>
&lt;h3>Passo 2: Teste de Integração&lt;span class="hx:absolute hx:-mt-20" id="passo-2-teste-de-integração">&lt;/span>
&lt;a href="#passo-2-teste-de-integra%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>✅ Validar se o job &lt;code>SaveSessionsUrlAnalyticsJob.php&lt;/code> está salvando corretamente os dados na tabela &lt;code>analytics_session_urls&lt;/code>.&lt;/p>
&lt;ul>
&lt;li>Simular uma execução do job com diferentes cenários de domínio.&lt;/li>
&lt;li>Checar se os dados são gravados corretamente.&lt;/li>
&lt;/ul>
&lt;h3>Passo 3: Teste Funcional (Opcional, caso necessário)&lt;span class="hx:absolute hx:-mt-20" id="passo-3-teste-funcional-opcional-caso-necessário">&lt;/span>
&lt;a href="#passo-3-teste-funcional-opcional-caso-necess%c3%a1rio" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>✅ Executar a funcionalidade completa e validar se os relatórios de RPS exibem os dados esperados.&lt;/p>
&lt;h3>4. Como seguir no Time?&lt;span class="hx:absolute hx:-mt-20" id="4-como-seguir-no-time">&lt;/span>
&lt;a href="#4-como-seguir-no-time" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>Antes de abrir um bug, garantir que o código passou pelos testes unitários e de integração.&lt;/li>
&lt;li>Adotar um fluxo de Dev Teste: &lt;strong>Desenvolvedor faz – Code Review – Dev Teste – QA&lt;/strong>.&lt;/li>
&lt;li>Registrar evidências dos testes, ter PR, evitando repassar códigos sem verificação prévia.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Como adicionar Evidências:&lt;/strong>&lt;/p>
&lt;p>&lt;strong>Teste executando em ambiente dev&lt;/strong>: os testes validados localmente, mesmo utilizando docker, não é válido, pois vários fatores de ambiente e rede não são validados nas conformidades. Gerando um falso positivo. Testes locais se enquadram por exemplo em outros tipos de testes, exemplo citado aqui os unitários.&lt;/p>
&lt;ul>
&lt;li>Ambiente de dev;&lt;/li>
&lt;li>Capturas de telas caso for testes do tipo End-to-end;&lt;/li>
&lt;li>Ter PRs no card;&lt;/li>
&lt;li>Validar os cenários dos testes no card, caso não tenha, avise o QA responsável;&lt;/li>
&lt;/ul></description></item><item><title>Quando se tem [data-cy="seu-elemento-x"], precisa ainda instalar o Testing Library?</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/testing-library-exemplos-de-configuracao/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/testing-library-exemplos-de-configuracao/</guid><description>
&lt;p>Segue exemplo abaixo de um código que usa o &lt;code>data-cy&lt;/code> para capturar elementos nas automação E2E com Cypress.&lt;/p>
&lt;hr>
&lt;p>O uso do &lt;strong>Testing Library&lt;/strong> é interessante quando não temos o elemento definido no E2E, ou seja, sem o data-test/cy. Para que o Testing Library reconheça dentro da automação, precisamos que, não tenha no elemento que vai ser buscado pelo cypress o &lt;code>data-cy&lt;/code> e então, o Testing Library o reconhece buscando pelo padrão &lt;code>findByText.('Sua palavra mágica').click();&lt;/code>&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/junho/testing-library-exemplos-de-configuracao/cypress-testinglibrary.png" alt="Cypress e Testing Library" loading="lazy" />&lt;/p>
&lt;p>&lt;strong>Opção 1: Configurar no arquivo &lt;code>setup-tests.js&lt;/code> (Cypress v10+):&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Crie o arquivo &lt;code>setup-tests.js&lt;/code>: se você ainda não tem esse arquivo, crie-o na raiz do seu projeto ou em outro local especificado na sua configuração do Cypress (veja a documentação para detalhes).&lt;/li>
&lt;li>Configure o atributo &lt;code>testIdAttribute&lt;/code>:&lt;/li>
&lt;/ol>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// cypress/support/setup-tests.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">configure&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;@testing-library/cypress&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">configure&lt;/span>&lt;span class="p">({&lt;/span> &lt;span class="nx">testIdAttribute&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;data-cy&amp;#39;&lt;/span> &lt;span class="p">})&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Opção 2: Configurar diretamente no teste (Cypress v9 e anteriores):&lt;/strong> se você estiver usando uma versão mais antiga do Cypress, você pode configurar a biblioteca diretamente no seu arquivo de teste:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// cypress/e2e/seu_teste.cy.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">configure&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;@testing-library/cypress&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">describe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Seus testes&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">before&lt;/span>&lt;span class="p">(()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">configure&lt;/span>&lt;span class="p">({&lt;/span> &lt;span class="nx">testIdAttribute&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;data-cy&amp;#39;&lt;/span> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ... seus testes aqui
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">})&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Opção 3: Criar um novo comando:&lt;/strong>&lt;/p>
&lt;p>Crie um comando personalizado para usar &lt;code>findByTestId&lt;/code> sempre com o &lt;code>data-cy&lt;/code>:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// cypress/support/commands.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="nx">Cypress&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Commands&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;findByCy&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">options&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cy&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">findByTestId&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="p">...&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">testIdAttribute&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;data-cy&amp;#39;&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;hr>
&lt;p>&lt;strong>Referências&lt;/strong>:&lt;/p>
&lt;p>&lt;a href="https://testing-library.com/docs/cypress-testing-library/intro/"target="_blank" rel="noopener">Testing Library&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://github.com/testing-library/cypress-testing-library/blob/97939da7d4707a71049884c0324c0eda56e26fc2/cypress/integration/find.spec.js"target="_blank" rel="noopener">https://github.com/testing-library/cypress-testing-library/blob/97939da7d4707a71049884c0324c0eda56e26fc2/cypress/integration/find.spec.js&lt;/a>&lt;/p>
&lt;p>&lt;strong>Cypress and Testing Library&lt;/strong> &lt;a href="https://docs.cypress.io/app/core-concepts/best-practices#Cypress-and-Testing-Library"target="_blank" rel="noopener">Link&lt;/a>&lt;/p></description></item><item><title>Quais ferramentas que estudamos você já experimentou e quais pretende experimentar para promover a inovação em seu ambiente de desenvolvimento de software?</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/</link><pubDate>Thu, 24 Apr 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/</guid><description>
&lt;p>Eu estou aplicando o estudo com a estúdio de musculação que frequento, aqui na Zona Norte de Porto Alegre. Solicitei permissão ao dono da academia — que está iniciando o negócio desde janeiro de 2025 — para aplicar estes estudos e desenvolver um projeto em um negócio real, baseado em necessidades reais.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>O projeto seria&lt;/strong>: criar uma landing page para o estúdio, aplicando as técnicas de Design Thinking e os estudos vistos em aula de Inovação e Empreendedorismo — Inovação e Empreendedorismo - Web 03.&lt;/p>
&lt;p>&lt;strong>Início do projeto:&lt;/strong> acompanhei a abertura do estúdio de musculação desde janeiro de 2025, e, desde então, fui a aluna — junto com outro amigo próximo — a treinar no novo local. Primeira coisa que perguntei ao dono foi: como vai funcionar a academia? Vai ter horários flexíveis? Quem vai treinar no local?&lt;/p>
&lt;p>Visando isso, procurei entender melhor, conversando com o dono do negócio — Academia Estúdio de Musculação — e levantei essas perguntas. Outro ponto em destaque é que eu treino lá desde o início — por conhecer o dono, fui a aluna-teste do local 😂 — o que acabou agregando ao projeto, pois tive pessoalmente a visão de alguns pontos importantes.&lt;/p>
&lt;h3>1. Empatia (entender o problema sob o ponto de vista do usuário)&lt;span class="hx:absolute hx:-mt-20" id="1-empatia-entender-o-problema-sob-o-ponto-de-vista-do-usuário">&lt;/span>
&lt;a href="#1-empatia-entender-o-problema-sob-o-ponto-de-vista-do-usu%c3%a1rio" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Como sou usuária da academia, enfrentei alguns problemas, como: quais são os valores? Como funcionam os pacotes com acompanhamento nutricional? Há parceria com lojas de suplementos? Quanto custa o whey protein? Entre outros. Percebi que os alunos que vieram depois também tinham essas dúvidas. Quando fui recomendar a academia, também tive dificuldades para compartilhar o endereço e informar os valores de cabeça — sabia apenas o que utilizava, no caso o TotalPass. Não havia um local centralizado para consultar essas informações.&lt;/p>
&lt;h3>2. Definição (refinar o problema)&lt;span class="hx:absolute hx:-mt-20" id="2-definição-refinar-o-problema">&lt;/span>
&lt;a href="#2-defini%c3%a7%c3%a3o-refinar-o-problema" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Com base nisso, organizei todas as informações que tinha em mãos e conversei com o dono do negócio para entender e refinar as questões. Utilizando técnicas de design thinking, apliquei o &lt;strong>Value Proposition Canvas&lt;/strong> para não deixar tudo apenas dentro da minha cabeça e também compartilhar com o envolvido — o dono do negócio. Segue abaixo:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/value-proposition-canvas.png" alt="Value Proposition Canvas" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/aplicado-value-proposition-canvas.png" alt="Value Proposition Canvas aplicado ao projeto do estúdio" loading="lazy" />&lt;/p>
&lt;p>Utilizei também o ChatGPT para estruturar de forma detalhada e organizar todas as informações nos devidos lugares, a fim de não perder o foco nos detalhes.&lt;/p>
&lt;h3>ChatGPT&lt;span class="hx:absolute hx:-mt-20" id="chatgpt">&lt;/span>
&lt;a href="#chatgpt" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/chatgpt-1.png" alt="Uso do ChatGPT para organizar as informações" loading="lazy" />&lt;/p>
&lt;p>Abaixo, utilizei como um checklist das informações que já havia mapeado, para manter a organização e não me perder no processo:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/checklist.png" alt="Checklist de informações mapeadas" loading="lazy" />&lt;/p>
&lt;p>Para tornar a entrevista mais clara, resolvi criar um formulário para enviar ao dono do negócio responder; &lt;strong>isso corresponde às &amp;ldquo;Definições&amp;rdquo; citadas e aplicadas aqui.&lt;/strong>&lt;/p>
&lt;hr>
&lt;h3>3. Ideação&lt;span class="hx:absolute hx:-mt-20" id="3-ideação">&lt;/span>
&lt;a href="#3-idea%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Visto acima no ChatGPT temos o seguinte:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/chatgpt-ideacao.png" alt="ChatGPT na fase de ideação" loading="lazy" />&lt;/p>
&lt;p>Vou mudar alguns pontos que acho importante reorganizar com base nas necessidades vistas lá no mapeamento com o &lt;strong>Value Proposition Canvas&lt;/strong>.&lt;/p>
&lt;p>Brainstorm para soluções da Landing Page: EDITADA&lt;/p>
&lt;ul>
&lt;li>Blocos organizados: Quem somos | Planos Diferenciais | Estrutura | Agendamento - Contato | FAQ&lt;/li>
&lt;li>Botão direto para WhatsApp&lt;/li>
&lt;li>Fotos do ambiente com qualidade - passando credibilidade&lt;/li>
&lt;li>Chamada de Ação: destaque no diferencial do negócio, avaliação gratuita física.&lt;/li>
&lt;li>FAQ rápido com as dúvidas levantadas pelos novos usuários (isso vai ser coletado no formulário).&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3>4. Prototipagem&lt;span class="hx:absolute hx:-mt-20" id="4-prototipagem">&lt;/span>
&lt;a href="#4-prototipagem" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/prototipagem-1.png" alt="Prototipagem inicial" loading="lazy" />&lt;/p>
&lt;p>Eu sou péssima com Design 😭 &lt;strong>então utilizei a ferramenta do Canva para dar vida&lt;/strong> a isso, e não deixar isso ser meu impedimento.&lt;/p>
&lt;p>&lt;strong>OBS&lt;/strong>: vamos relembrar brevemente da aula ao vivo sobre &amp;ldquo;legal, vamos lá fazer isso&amp;rdquo;&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/prototipagem-2.png" alt="Aula ao vivo sobre prototipagem" loading="lazy" />&lt;/p>
&lt;p>EU não sei design&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/prototipagem-3.png" alt="Tentativa de prototipagem no Canva" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h2>5. O Teste&lt;span class="hx:absolute hx:-mt-20" id="5-o-teste">&lt;/span>
&lt;a href="#5-o-teste" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Criação do protótipo: como citado, este protótipo foi feito no Canva, com o objetivo de tornar visual todo o planejamento do Value Proposition Canvas. Abaixo, segue a sequência das telas:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-1.png" alt="Tela 1 do protótipo" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-2.png" alt="Tela 2 do protótipo" loading="lazy" />&lt;/p>
&lt;p>Incluir parte dos serviços que falta para responder do formulário.&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-3.png" alt="Tela 3 do protótipo" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-4.png" alt="Tela 4 do protótipo" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-5.png" alt="Tela 5 do protótipo" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-6.png" alt="Tela 6 do protótipo" loading="lazy" />&lt;/p>
&lt;p>Foi desenvolvido este rascunho inicial do protótipo, com o objetivo de validar as necessidades do proprietário do negócio em relação ao atendimento de seus clientes.&lt;/p>
&lt;p>A construção do protótipo possibilitou a identificação de pontos relevantes e, sobretudo, representou um avanço significativo ao transformar ideias em uma versão prática e visual. O processo de desenvolvimento mostrou-se ágil e funcional, permitindo direcionar os próximos passos.&lt;/p>
&lt;p>Como continuidade, propõe-se a realização de novos testes com usuários e a execução do site em ambiente real, a fim de avaliar se as funcionalidades implementadas atendem às necessidades previamente mapeadas.&lt;/p>
&lt;p>&lt;strong>Protótipo Canva&lt;/strong>: &lt;a href="https://testeladybug.my.canva.site/cada-rotina-e-pessoa-diferente-por-isso-nos-certificamos-de-que-voc-possa-escolher-um-plano-que-funcione-melhor-para-voc"target="_blank" rel="noopener">link&lt;/a>&lt;/p>
&lt;hr>
&lt;h2>Pesquisa em Formulário para melhor análise e entendimento&lt;span class="hx:absolute hx:-mt-20" id="pesquisa-em-formulário-para-melhor-análise-e-entendimento">&lt;/span>
&lt;a href="#pesquisa-em-formul%c3%a1rio-para-melhor-an%c3%a1lise-e-entendimento" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;h1>2. Questionário baseado no Design Thinking&lt;/h1>&lt;p>(Para usar na fase &lt;strong>Empatia + Definição&lt;/strong> com o cliente)&lt;/p>
&lt;h2>Perguntas sobre o Negócio&lt;span class="hx:absolute hx:-mt-20" id="perguntas-sobre-o-negócio">&lt;/span>
&lt;a href="#perguntas-sobre-o-neg%c3%b3cio" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>Como você descreveria a missão e os valores do seu estúdio?&lt;/li>
&lt;li>Qual a principal diferença do seu estúdio para outras academias?&lt;/li>
&lt;li>Quais serviços ou vantagens você mais gostaria de destacar para novos alunos?&lt;/li>
&lt;li>Qual sentimento ou impressão você gostaria que o aluno tivesse ao visitar o estúdio?&lt;/li>
&lt;/ol>
&lt;h2>Perguntas sobre os Clientes&lt;span class="hx:absolute hx:-mt-20" id="perguntas-sobre-os-clientes">&lt;/span>
&lt;a href="#perguntas-sobre-os-clientes" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>Quem são seus principais clientes hoje? (idade, perfil, objetivos)&lt;/li>
&lt;li>O que seus alunos costumam elogiar mais no seu serviço?&lt;/li>
&lt;li>&lt;strong>Quais dúvidas ou receios os novos alunos mais demonstram quando entram em contato?&lt;/strong>&lt;/li>
&lt;li>O que já ouviu de feedback positivo ou negativo sobre a experiência na academia?&lt;/li>
&lt;/ol>
&lt;h2>Perguntas sobre Comunicação&lt;span class="hx:absolute hx:-mt-20" id="perguntas-sobre-comunicação">&lt;/span>
&lt;a href="#perguntas-sobre-comunica%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>Hoje, quais canais você usa para divulgar seu estúdio? (Instagram, WhatsApp, indicações, etc.)&lt;/li>
&lt;/ol>
&lt;h2>Perguntas sobre Serviços Extras&lt;span class="hx:absolute hx:-mt-20" id="perguntas-sobre-serviços-extras">&lt;/span>
&lt;a href="#perguntas-sobre-servi%c3%a7os-extras" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>Como funciona a parceria com a nutricionista? (valores, agendamento, diferenciais)&lt;/li>
&lt;li>Como funciona a parceria com suplementos? (marcas, descontos, vantagens)&lt;/li>
&lt;/ol>
&lt;h2>Perguntas sobre Experiência&lt;span class="hx:absolute hx:-mt-20" id="perguntas-sobre-experiência">&lt;/span>
&lt;a href="#perguntas-sobre-experi%c3%aancia" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>Que tipo de benefícios você gostaria de oferecer para novos alunos? (promoções, aula experimental, desconto na 1ª mensalidade)&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2>Links de Referência&lt;span class="hx:absolute hx:-mt-20" id="links-de-referência">&lt;/span>
&lt;a href="#links-de-refer%c3%aancia" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Confira o Protótipo do site&lt;/strong>: &lt;a href="https://site-academia-app.vercel.app/"target="_blank" rel="noopener">https://site-academia-app.vercel.app/&lt;/a>&lt;/p>
&lt;p>Pesquisa de Sites | Mercado com foco em Academias - &lt;a href="https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/pesquisa-de-sites-mercado-foco-em-academias/">Link&lt;/a>&lt;/p>
&lt;p>&lt;strong>Referências de Estudos&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Link&lt;/strong> sobre qualidade do produto - Rian Dutra: &lt;a href="https://www.linkedin.com/posts/riandutra_prestes-a-falir-cortam-o-design-e-marketing-activity-7315692085477539840-InMr"target="_blank" rel="noopener">LinkedIn&lt;/a>&lt;/li>
&lt;li>Livro: Não me faça pensar - Steve Krug&lt;/li>
&lt;li>Livro: O Design do dia a dia - Donald A. Norman&lt;/li>
&lt;li>Livro: Value Proposition Design - pág: 142, 228, 232&lt;/li>
&lt;li>Pós-graduação Unisinos - Aulas Inovação e Empreendedorismo com a &lt;a href="https://www.linkedin.com/in/rmaryf"target="_blank" rel="noopener">Profª Rosemary Francisco&lt;/a>&lt;/li>
&lt;li>Ferramentas: &lt;a href="https://www.canva.com/"target="_blank" rel="noopener">Canva&lt;/a>, Vercel App para deploy do site&lt;/li>
&lt;li>&lt;a href="https://psicologia.design/como-identificar-e-resolver-pontos-de-dor-user-pain-points-do-usuario-no-ux-design-com-psicologia-aplicada/"target="_blank" rel="noopener">Como identificar e resolver pontos de dor (pain points) do usuário no UX Design&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://psicologia.design/como-usar-storytelling-no-ux-design/"target="_blank" rel="noopener">Como usar storytelling no UX Design&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Pesquisa de Sites | Mercado com foco em Academias</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/pesquisa-de-sites-mercado-foco-em-academias/</link><pubDate>Thu, 17 Apr 2025 00:00:00 +0000</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2025/abril/pesquisa-de-sites-mercado-foco-em-academias/</guid><description>
&lt;h3>Estudos e Análise Geral de Sites de Academias de Atividades Físicas&lt;span class="hx:absolute hx:-mt-20" id="estudos-e-análise-geral-de-sites-de-academias-de-atividades-físicas">&lt;/span>
&lt;a href="#estudos-e-an%c3%a1lise-geral-de-sites-de-academias-de-atividades-f%c3%adsicas" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h3>&lt;p>Essa breve pesquisa foi realizada para um protótipo de site no nicho de academias, com o objetivo de divulgar um estúdio de academia, focado em objetivos pessoais, voltado a pessoas que não gostam de academias lotadas e sem atenção de instrutores, priorizando a pessoalidade no atendimento.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>1. Padrão dos sites de academias:&lt;/strong>&lt;/p>
&lt;p>Normalmente, sites de academias são construídos com foco em três grandes pilares:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Apresentação de serviços:&lt;/strong> mostrar os tipos de treinos (musculação, funcional, spinning, pilates, yoga etc.).&lt;/li>
&lt;li>&lt;strong>Captação de novos alunos:&lt;/strong> destacar promoções, planos, aulas experimentais e formulários rápidos de contato.&lt;/li>
&lt;li>&lt;strong>Prova social:&lt;/strong> exibir fotos reais, depoimentos de alunos e resultados alcançados.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. Estrutura comum que aparece nesses sites:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Página inicial chamativa:&lt;/strong> com imagens de pessoas treinando, mensagens motivacionais, e destaque para diferenciais da academia (24h, avaliação física grátis, estacionamento, etc.).&lt;/li>
&lt;li>&lt;strong>Planos e preços:&lt;/strong> muita gente procura rapidamente o valor da mensalidade — alguns sites mostram, outros obrigam o usuário a preencher um formulário primeiro (o que pode gerar abandono).&lt;/li>
&lt;li>&lt;strong>Agenda de aulas coletivas:&lt;/strong> algumas academias disponibilizam a programação semanal de aulas no próprio site.&lt;/li>
&lt;li>&lt;strong>Localização:&lt;/strong> um mapa integrado (Google Maps) é quase obrigatório, já que localização é fator decisivo.&lt;/li>
&lt;li>&lt;strong>Área do aluno:&lt;/strong> alguns sites mais modernos oferecem login para alunos acompanharem treinos, pagamentos e evolução física.&lt;/li>
&lt;li>&lt;strong>Blog ou dicas de saúde:&lt;/strong> pouco usado, mas quando existe, ajuda no SEO (atrair mais visitantes via Google).&lt;/li>
&lt;li>&lt;strong>Chat ou WhatsApp direto:&lt;/strong> muitos sites têm botões flutuantes para contato rápido via WhatsApp.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>3. Comportamento de quem procura sites de academias:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Busca por praticidade:&lt;/strong> as pessoas querem informações rápidas. Sites lentos ou com excesso de formulários perdem usuários.&lt;/li>
&lt;li>&lt;strong>Comparação:&lt;/strong> é comum o usuário abrir vários sites de academias próximas para comparar preços, estrutura e diferenciais.&lt;/li>
&lt;li>&lt;strong>Busca por credibilidade:&lt;/strong> fotos de qualidade, estrutura física mostrada e depoimentos reais aumentam a confiança.&lt;/li>
&lt;li>&lt;strong>Interesse em benefícios imediatos:&lt;/strong> promoções de matrícula grátis, descontos na primeira mensalidade ou aula experimental gratuita costumam ser gatilhos decisivos.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>4. SEO e tráfego:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Boa parte das buscas vem de palavras-chave locais, como &amp;ldquo;&lt;strong>academia em [nome da cidade/bairro]&lt;/strong>&amp;rdquo; ou &amp;ldquo;&lt;strong>academia perto de mim&lt;/strong>&amp;rdquo;.&lt;/li>
&lt;li>Sites otimizados para essas buscas locais têm muito mais chances de serem encontrados organicamente (sem precisar pagar anúncios).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>5. Design e tendências atuais:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Visual clean e moderno (nada poluído).&lt;/li>
&lt;li>Vídeos curtos na homepage mostrando o ambiente.&lt;/li>
&lt;li>Integração com redes sociais (principalmente Instagram).&lt;/li>
&lt;/ul></description></item><item><title>Cypress e Boas Práticas de Automação</title><link>https://deploy-preview-18--ladydebug.netlify.app/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/</link><pubDate>Thu, 24 Oct 2024 13:07:00 -0300</pubDate><guid>https://deploy-preview-18--ladydebug.netlify.app/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/</guid><description>
&lt;p>Evitando o uso de &lt;em>Falsos Positivos&lt;/em> com Cypress. Segue abaixo um exemplo de um código, e um arquivo commands com um simples login na aplicação:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/exemplo-praticas-ruins.png" alt="exemplo-praticas-ruins" loading="lazy" />&lt;/p>
&lt;p>Essa aplicação estava ocorrendo um certo erro ao realizar o login, e foi adicionado o seguinte trecho de código na automação para poder realizar o login com sucesso:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/o_que_o_erro_faz.png" alt="o que o erro faz?" loading="lazy" />&lt;/p>
&lt;p>Mas o que esse trecho diz? Serve para suprimir os erros que ocorrem na aplicação durante a execução dos testes do Cypress.&lt;/p>
&lt;p>Como assim? Ao usar &lt;code>cy.on('uncaught:exception')&lt;/code> e retornar false, está instruindo o Cypress a ignorar qualquer erro que ocorra na sua aplicação. Isso permite que o teste continue mesmo que a página ainda não esteja totalmente carregada, dando tempo para que os elementos sejam renderizados antes que o Cypress tente interagir com eles.&lt;/p>
&lt;p>Por que remover &lt;code>cy.on('uncaught:exception')&lt;/code> é importante? Nesse caso, como está sendo manipulado o teste, forçando a “ignorar esse erro retornando que ele seja falso” é adicionado um falso positivo no nosso teste. Segue abaixo:&lt;/p>
&lt;p>&lt;img src="https://deploy-preview-18--ladydebug.netlify.app/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/login_com_sucesso.png" alt="alt text" loading="lazy" />&lt;/p>
&lt;h2>Alternativas e soluções para lidar com o tempo de carregamento e evitar adicionar “falso positivo”&lt;span class="hx:absolute hx:-mt-20" id="alternativas-e-soluções-para-lidar-com-o-tempo-de-carregamento-e-evitar-adicionar-falso-positivo">&lt;/span>
&lt;a href="#alternativas-e-solu%c3%a7%c3%b5es-para-lidar-com-o-tempo-de-carregamento-e-evitar-adicionar-falso-positivo" class="subheading-anchor" aria-label="Link permanente para esta secção">&lt;/a>&lt;/h2>&lt;p>Em vez de suprimir erros, deve-se usar as ferramentas do Cypress para garantir que os elementos estejam presentes e prontos para interação antes de tentar acessá-los. Algumas opções incluem:&lt;/p>
&lt;p>&lt;code>cy.wait()&lt;/code>: Aguarde um determinado tempo ou até que um elemento ou condição específica seja atendida antes de prosseguir com o teste.&lt;/p>
&lt;p>OBS: cuide as más práticas ao usar o comando &lt;code>cy.wait(número)&lt;/code> , leia a documentação sobre Anti-Pattern.&lt;/p>
&lt;p>&lt;a href="https://docs.cypress.io/app/core-concepts/best-practices#Unnecessary-Waiting"target="_blank" rel="noopener">Unnecessary Waiting aqui&lt;/a>&lt;/p>
&lt;p>Em vez disso, use:&lt;/p>
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
&lt;div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cy.intercept&lt;span class="o">(&lt;/span>&lt;span class="s1">&amp;#39;GET&amp;#39;&lt;/span>, &lt;span class="s1">&amp;#39;/users&amp;#39;&lt;/span>, &lt;span class="o">[{&lt;/span> name: &lt;span class="s1">&amp;#39;Maggy&amp;#39;&lt;/span> &lt;span class="o">}&lt;/span>, &lt;span class="o">{&lt;/span> name: &lt;span class="s1">&amp;#39;Joan&amp;#39;&lt;/span> &lt;span class="o">}])&lt;/span>.as&lt;span class="o">(&lt;/span>&lt;span class="s1">&amp;#39;getUsers&amp;#39;&lt;/span>&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cy.get&lt;span class="o">(&lt;/span>&lt;span class="s1">&amp;#39;[data-testid=&amp;#34;fetch-users&amp;#34;]&amp;#39;&lt;/span>&lt;span class="o">)&lt;/span>.click&lt;span class="o">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cy.wait&lt;span class="o">(&lt;/span>&lt;span class="s1">&amp;#39;@getUsers&amp;#39;&lt;/span>&lt;span class="o">)&lt;/span> // &amp;lt;--- &lt;span class="nb">wait&lt;/span> explicitly &lt;span class="k">for&lt;/span> this route to finish&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copiar código"
aria-label="Copiar código"
data-copied-label="Copiado!"
>
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4">&lt;/div>
&lt;/button>
&lt;/div>
&lt;/div>
&lt;p>&lt;code>cy.get(...).should('exist')&lt;/code> ou&lt;/p>
&lt;p>&lt;code>cy.get(...).should('be.visible')&lt;/code>&lt;/p>
&lt;p>Precisa garantir de que o elemento existe e está visível na página antes de tentar interagir com ele.&lt;/p></description></item></channel></rss>