<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Lady{de}bug – Lady{de}bug</title><link>https://ladydebug.com.br/en/</link><description>Recent content on Lady{de}bug</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Fri, 06 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://ladydebug.com.br/en/index.xml" rel="self" type="application/rss+xml"/><item><title>Setting up SonarQube locally</title><link>https://ladydebug.com.br/en/docs/2025/setembro/configurando-o-sonar-qube-localmente/</link><pubDate>Sat, 20 Sep 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/setembro/configurando-o-sonar-qube-localmente/</guid><description>
&lt;p>&lt;strong>This is not a tutorial.&lt;/strong> These are study notes on understanding the tool and applying it to small and medium-sized projects in private repositories. Since I already had SonarQube installed on my machine, here is how I configured Docker.&lt;/p>
&lt;hr>
&lt;h2>Option 1 — Remove the existing container&lt;span class="hx:absolute hx:-mt-20" id="option-1--remove-the-existing-container">&lt;/span>
&lt;a href="#option-1--remove-the-existing-container" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>I had configured it for a code analysis study project as part of my postgraduate coursework. In this case I reconfigured it for another project; later I will set it up correctly again for the code analysis project.&lt;/p>
&lt;p>&lt;code>docker rm sonarqube&lt;/code>&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/image1.png" alt="Removing the existing container" loading="lazy" />&lt;/p>
&lt;p>Now I can run the command to start a new 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>Yes, this is the free version, for learning before paying for something I do not yet know how to use.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/image2.png" alt="Starting a new container" loading="lazy" />&lt;/p>
&lt;h3>Option 2 — Replace the container automatically&lt;span class="hx:absolute hx:-mt-20" id="option-2--replace-the-container-automatically">&lt;/span>
&lt;a href="#option-2--replace-the-container-automatically" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>To force replacement, use &lt;code>--rm&lt;/code>, which removes the container when stopped, or &lt;code>--replace&lt;/code> with Podman. With Docker, we generally remove it manually as above.&lt;/p>
&lt;h3>Option 3 — Check the container status&lt;span class="hx:absolute hx:-mt-20" id="option-3--check-the-container-status">&lt;/span>
&lt;a href="#option-3--check-the-container-status" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;code>docker start sonarqube&lt;/code>&lt;/p>
&lt;p>To stop it, use:&lt;/p>
&lt;p>&lt;code>docker stop sonarqube&lt;/code>&lt;/p>
&lt;h2>Run SonarQube locally&lt;span class="hx:absolute hx:-mt-20" id="run-sonarqube-locally">&lt;/span>
&lt;a href="#run-sonarqube-locally" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Now for the interesting part: configuring SonarQube locally and running a basic scan.&lt;/p>
&lt;p>First, some initial configuration. I think this is worth adding to the development setup script.&lt;/p>
&lt;h3>1. Prerequisites&lt;span class="hx:absolute hx:-mt-20" id="1-prerequisites">&lt;/span>
&lt;a href="#1-prerequisites" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Java 11 or later&lt;/strong> installed on the machine; SonarQube needs Java to run.&lt;/li>
&lt;li>&lt;strong>Docker&lt;/strong>, optional but it really makes running SonarQube easier.&lt;/li>
&lt;/ul>
&lt;h3>2. Download and run SonarQube&lt;span class="hx:absolute hx:-mt-20" id="2-download-and-run-sonarqube">&lt;/span>
&lt;a href="#2-download-and-run-sonarqube" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Download: &lt;a href="https://www.sonarsource.com/open-source-editions/sonarqube-community-edition/"target="_blank" rel="noopener">SonarQube Community Edition&lt;/a>&lt;/p>
&lt;p>The first step is adjusting Docker, so make sure it is running correctly without problems.&lt;/p>
&lt;p>&lt;code>docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community&lt;/code>&lt;/p>
&lt;p>Done! SonarQube is running locally.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/image3.png" alt="SonarQube running locally" loading="lazy" />&lt;/p>
&lt;p>Adjust the password settings and continue to the page:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/image4.png" alt="SonarQube configuration page" loading="lazy" />&lt;/p>
&lt;h3>SonarQube configuration&lt;span class="hx:absolute hx:-mt-20" id="sonarqube-configuration">&lt;/span>
&lt;a href="#sonarqube-configuration" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>Open &lt;a href="http://localhost:9000/"target="_blank" rel="noopener">http://localhost:9000&lt;/a>.&lt;/li>
&lt;li>Default login:
&lt;ul>
&lt;li>Username: admin&lt;/li>
&lt;li>Password: admin&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>Now let&amp;rsquo;s configure a project scan.&lt;/p>
&lt;h3>Generate an authentication token&lt;span class="hx:absolute hx:-mt-20" id="generate-an-authentication-token">&lt;/span>
&lt;a href="#generate-an-authentication-token" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>In the top-right menu, click your user &amp;gt; My Account &amp;gt; Security.&lt;/li>
&lt;li>Under &amp;ldquo;Generate Tokens&amp;rdquo;, create a token, such as nome-projeto-token.&lt;/li>
&lt;li>Save the token; the scanner will use it.&lt;/li>
&lt;/ol>
&lt;h3>Install SonarScanner&lt;span class="hx:absolute hx:-mt-20" id="install-sonarscanner">&lt;/span>
&lt;a href="#install-sonarscanner" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;strong>SonarScanner&lt;/strong> is the CLI that sends your code to SonarQube. Through the local terminal, we tell it to read the project and then obtain the analysis.&lt;/p>
&lt;h3>Install through NPM for Node projects&lt;span class="hx:absolute hx:-mt-20" id="install-through-npm-for-node-projects">&lt;/span>
&lt;a href="#install-through-npm-for-node-projects" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;code>npm install -g sonarqube-scanner&lt;/code>&lt;/p>
&lt;p>For project-specific references, see &lt;a href="https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/scanners/sonarscanner"target="_blank" rel="noopener">SonarScanner documentation&lt;/a>.&lt;/p>
&lt;h3>Configure SonarScanner in the project&lt;span class="hx:absolute hx:-mt-20" id="configure-sonarscanner-in-the-project">&lt;/span>
&lt;a href="#configure-sonarscanner-in-the-project" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Create a file called &lt;code>sonar-project.properties&lt;/code> in the project root:&lt;/p>
&lt;p>Example:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Problems encountered&lt;span class="hx:absolute hx:-mt-20" id="problems-encountered">&lt;/span>
&lt;a href="#problems-encountered" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/problema-encontrado-ao-rodar-o-escaneamento-2025-09-20-09-24.png" alt="Problem encountered when running the scan" 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>What does this error mean?&lt;span class="hx:absolute hx:-mt-20" id="what-does-this-error-mean">&lt;/span>
&lt;a href="#what-does-this-error-mean" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>SonarScanner is trying to send the analysis results to SonarQube, but the configured user or token &lt;strong>does not have permission&lt;/strong> to perform this operation on the configured SonarQube project.&lt;/p>
&lt;p>&lt;strong>Great! Let&amp;rsquo;s see what I did wrong:&lt;/strong> the project name in &lt;code>sonar-project.properties&lt;/code> did not match the one I configured in local SonarQube.&lt;/p>
&lt;p>Now it is ready: running &lt;code>sonar-scanner&lt;/code> scans the project and displays the results.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/terminal-sucesso-2025-09-20-09-33.png" alt="Successful terminal output" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/setembro/configurando-o-sonar-qube-localmente/executado-2025-09-20-09-32.png" alt="Completed scan" loading="lazy" />&lt;/p></description></item><item><title>Building a portfolio website and organizing the work I have done</title><link>https://ladydebug.com.br/en/docs/2026/novembro/criando-um-site-portfolio-e-como-estou-organizando-os-trabalhos-realizados/</link><pubDate>Fri, 06 Nov 2026 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2026/novembro/criando-um-site-portfolio-e-como-estou-organizando-os-trabalhos-realizados/</guid><description>
&lt;h2>Building a portfolio website and organizing the work I have done&lt;span class="hx:absolute hx:-mt-20" id="building-a-portfolio-website-and-organizing-the-work-i-have-done">&lt;/span>
&lt;a href="#building-a-portfolio-website-and-organizing-the-work-i-have-done" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Recently I started organizing my portfolio in a way that would help me present my work more clearly. I wanted more than a list of technologies or repository links. I also wanted to explain what I did, how I organized the stages, and what evidence is available to check each contribution.&lt;/p>
&lt;p>The project is on GitHub: &lt;a href="https://github.com/kellen-xavier/ladydebug-workstation"target="_blank" rel="noopener">https://github.com/kellen-xavier/ladydebug-workstation&lt;/a>. The published version is available at &lt;a href="https://kellen-xavier.github.io/ladydebug-workstation/"target="_blank" rel="noopener">https://kellen-xavier.github.io/ladydebug-workstation/&lt;/a>.&lt;/p>
&lt;h2>What I wanted to organize&lt;span class="hx:absolute hx:-mt-20" id="what-i-wanted-to-organize">&lt;/span>
&lt;a href="#what-i-wanted-to-organize" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Throughout my career, I have worked in support, frontend development, mobile and backend applications, testing, and documentation. Some of that work took place in private repositories, so it is not always possible to show the code or reproduce a run through a public link alone.&lt;/p>
&lt;p>That is why I am organizing the accounts to distinguish what was implemented, what appears in the available records, and the limits of each piece of evidence. An implementation described in a report does not, by itself, mean that every scenario was executed or that a pipeline was published. I want readers to be able to see that distinction.&lt;/p>
&lt;h2>A website with several pages&lt;span class="hx:absolute hx:-mt-20" id="a-website-with-several-pages">&lt;/span>
&lt;a href="#a-website-with-several-pages" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>The site is a static application built with React and TypeScript. Instead of creating one long page with every subject mixed together, I divided the navigation into pages for my career, contributions, workflow, setup, tools, and games. The homepage works as a map to reach those sections. This map is still in development, as I would like a layout inspired by Stardew Valley.&lt;/p>
&lt;p>For the visual design, I used a retro workstation reference, with cream, beige, brown, and pink tones and a pixel art illustration. I wanted the identity to connect with my Ladydebug blog while keeping the focus on reading and the work presented.&lt;/p>
&lt;p>In the &lt;strong>In practice&lt;/strong> section, each contribution can be opened to read its account and references. Public projects also link to their repositories. This keeps the content in one place while giving each subject its own context.&lt;/p>
&lt;h2>Content separated from components&lt;span class="hx:absolute hx:-mt-20" id="content-separated-from-components">&lt;/span>
&lt;a href="#content-separated-from-components" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>An important decision was to move long texts out of the components. The introduction, about section, career history, and project accounts live in Markdown files inside &lt;code>src/content/&lt;/code>. Components handle the page structure, and content can be edited without changing the layout. Keeping those responsibilities separate made more sense than hardcoding text into components.&lt;/p>
&lt;p>For the accounts, I use Markdown with headings, paragraphs, lists, links, and references. The &lt;code>react-markdown&lt;/code> library turns that content into page elements. Local images can also be referenced in Markdown; the build process packages the files and generates paths that work on &lt;a href="https://github.com/remarkjs/react-markdown"target="_blank" rel="noopener">GitHub Pages — see the repository here&lt;/a>.&lt;/p>
&lt;p>Information with a predictable structure stays in TypeScript. Workflow stages and project data, for example, need an order, identifiers, descriptions, and links. Keeping that data typed helps reveal inconsistencies during development.&lt;/p>
&lt;p>This division also makes maintenance easier: editorial content stays in Markdown, data feeding cards and stages stays typed, and components are responsible for presentation.&lt;/p>
&lt;h2>The workflow is part of the portfolio too&lt;span class="hx:absolute hx:-mt-20" id="the-workflow-is-part-of-the-portfolio-too">&lt;/span>
&lt;a href="#the-workflow-is-part-of-the-portfolio-too" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>I included a page to record how I usually work. The flow involves understanding the context, building and testing, reviewing evidence, and following up on what needs to improve. The idea is to show some of the decisions and practices behind the deliveries, as well as the final result. I reached this approach through analysis, gathering information, applying tests, and validating the results.&lt;/p>
&lt;p>I also organized examples of tools and setup, along with a list of game studies. These sections reflect the subjects I follow and help show how I organize my environment and keep learning. They also include my experience with the Arch Linux-based system &lt;a href="https://omarchy.org/"target="_blank" rel="noopener">Omarchy&lt;/a>.&lt;/p>
&lt;h2>Testing and publishing&lt;span class="hx:absolute hx:-mt-20" id="testing-and-publishing">&lt;/span>
&lt;a href="#testing-and-publishing" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>The project has unit tests and browser tests with &lt;a href="https://playwright.dev/"target="_blank" rel="noopener">Playwright&lt;/a>. In the browser tests, I am prioritizing behaviors someone can perform: navigating between pages, opening an account, following an anchor, downloading a file, copying a command, and filtering the games list. I also check layout behavior at different widths, such as horizontal scrolling and touch target sizes.&lt;/p>
&lt;p>I organized the E2E tests into separate files by flow, including navigation, home, career, accounts, workflow, tools, and responsiveness. That makes it easier to locate a scenario and understand which part of the site it covers. The tests validate features and interface states without comparing the wording of editorial texts.&lt;/p>
&lt;p>The site is generated as &lt;a href="https://github.com/kellen-xavier/ladydebug-workstation/blob/main/.github/workflows/pages.yml"target="_blank" rel="noopener">static files and published through GitHub Pages&lt;/a>. The pipeline runs lint, type checks, tests, and browser tests against the production build before publishing the main branch version.&lt;/p>
&lt;h2>What I am still learning&lt;span class="hx:absolute hx:-mt-20" id="what-i-am-still-learning">&lt;/span>
&lt;a href="#what-i-am-still-learning" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Building this portfolio is also helping me think about presenting technical experience clearly. I need to choose which details help explain a contribution, which links are useful, and where to state limitations instead of making claims that go beyond the available records.&lt;/p>
&lt;p>I still want to review the accounts and keep improving navigation and readability on smaller screens. The structure already lets me update each part more independently: I can adjust Markdown text, reorganize a project in the typed data, or improve a component without rewriting the whole site.&lt;/p>
&lt;p>The goal is to keep this space as a living record of my work and studies, with ways to check what is public and enough context to understand the rest.&lt;/p></description></item><item><title>An analysis of PC game releases</title><link>https://ladydebug.com.br/en/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc/</link><pubDate>Thu, 29 Oct 2026 15:53:10 -0300</pubDate><guid>https://ladydebug.com.br/en/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc/</guid><description>
&lt;p>Simple but crucial examples of testing in your project.&lt;/p>
&lt;p>PC gaming has been growing considerably for a long time, and gaming setups are gaining more space. They compete strongly with, and even surpass, video game consoles in power and performance. They also let people configure their own machines, from entry-level hardware to the latest components, choosing what best suits their needs at a given moment. Improvements include CPUs, motherboards, graphics cards, memory, and peripherals such as keyboards, mice, and monitors.&lt;/p>
&lt;p>With PC gaming becoming increasingly prominent, Sony made a major announcement in 2020 about bringing its &lt;strong>exclusive PlayStation games to PC&lt;/strong>. Horizon Zero Dawn was the first release, followed in subsequent years by titles ranging from Days Gone to the award-winning God of War.&lt;/p>
&lt;p>Sony gained a dedicated page on &lt;strong>Steam&lt;/strong>, one of the largest PC gaming platforms, followed by its own official site listing releases for these platforms. Games that were once console exclusives can now be played on PC by many more people, including those using entry-level hardware, with excellent performance.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/playstation-studios-steam.png" alt="PlayStation Studios page on Steam" loading="lazy" />&lt;/p>
&lt;p>This week, as March draws to a close, we have had some good game releases. Actually, they are not entirely new games: one is a remastered game with &lt;strong>performance improvements and graphical fixes&lt;/strong>, the acclaimed &lt;strong>Resident Evil 4&lt;/strong>.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/resident-evil-4-steam.png" alt="Resident Evil 4 page on Steam" loading="lazy" />&lt;/p>
&lt;p>The other release reaching PC is Sony&amp;rsquo;s acclaimed exclusive &lt;strong>The Last of Us Part I&lt;/strong>. Anyone who did not play it on PlayStation 3, PS4, or the latest console generation at the time, PS5, can now play it on PC. &lt;strong>Or try to play it on PC.&lt;/strong>&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/the-last-of-us-steam.png" alt="The Last of Us Part I page on Steam" loading="lazy" />&lt;/p>
&lt;p>Since its PC release, the game has faced valid criticism from users reporting &lt;strong>performance problems on PCs&lt;/strong>. Even high-end machines &lt;strong>cannot run the game&lt;/strong> without a variety of bugs. Reviews report issues including:&lt;/p>
&lt;ul>
&lt;li>Slow game installation.&lt;/li>
&lt;li>Poor graphics optimization, regardless of hardware.&lt;/li>
&lt;li>Long shader compilation times, regardless of hardware, especially on high-end PCs considered top-of-the-line setups.&lt;/li>
&lt;li>Extremely slow loading, even with the game installed on an M.2 SSD.&lt;/li>
&lt;li>Constant crashes: when the game finally loads, it repeatedly closes, putting us back at square one.&lt;/li>
&lt;/ul>
&lt;p>The game is clearly having problems. Naughty Dog and Iron Galaxy released a statement and a patch of only 36 MB.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/naughty-dog-hotfix.png" alt="Naughty Dog announcement about the PC hotfix" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/avaliacoes-resumo-steam.png" alt="Summary of The Last of Us Part I reviews on Steam" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/avaliacoes-usuarios-steam.png" alt="User reviews of The Last of Us Part I on Steam" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/problema-grafico-the-last-of-us.png" alt="A graphical issue in The Last of Us Part I" loading="lazy" />&lt;/p>
&lt;h2>What can we think about this? Testing was missing&lt;span class="hx:absolute hx:-mt-20" id="what-can-we-think-about-this-testing-was-missing">&lt;/span>
&lt;a href="#what-can-we-think-about-this-testing-was-missing" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>The PC release &lt;strong>did not have a demo version for users to test&lt;/strong>. Clearly, the quality team did not test enough, or did not test at all, before approving the release. Performance is far below the available minimum requirements, consuming all the hardware resources even on high-end PCs.&lt;/p>
&lt;h2>What could cause a system, application, or game to have so many problems?&lt;span class="hx:absolute hx:-mt-20" id="what-could-cause-a-system-application-or-game-to-have-so-many-problems">&lt;/span>
&lt;a href="#what-could-cause-a-system-application-or-game-to-have-so-many-problems" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>A lack of seriousness toward the end user: talk to users and release a test version so they can try it on their devices or platforms and see how it behaves. Involving real users in development should not be a challenge or something to fear. If the team is afraid to show its work, something is wrong.&lt;/p>
&lt;p>Not talking to your team: sometimes, and often, the team does not communicate or interact. That is the perfect recipe for disaster. A daily meeting should not be a status report. Technical conversations need enough clarity, with collaborative work and &lt;strong>minute-by-minute communication&lt;/strong>. When the team communicates this way, daily or weekly ceremonies are unnecessary because everyone already understands what is happening and how things stand.&lt;/p>
&lt;p>Not including quality from the start: a new project should include testing and &lt;strong>refinement and validation of the collected requirements&lt;/strong>, remember the users and the defects found in code and documentation. Every development activity has a corresponding testing activity. Testing involves every stage of the software development lifecycle. What are the priorities, risks, product type, and project goals? It may be necessary to combine and organize tests and their levels.&lt;/p>
&lt;p>Not completing testing: review defect reports, create a test summary for project management, &lt;strong>analyze lessons learned from defects and reports&lt;/strong>, and improve process maturity. How can a stage or task be finished without completing its testing?&lt;/p>
&lt;p>A lack of test work products: &lt;strong>work products are deliverables from each testing activity&lt;/strong>. We need planning, through a test plan, and analysis of conditions, defects, and priorities. We also need monitoring and control, through progress, summary, and completion reports.&lt;/p>
&lt;p>Managing fear: when afraid, we communicate less, hesitate often, and withdraw from recurring feedback. A team that manages fear communicates clearly and frequently. It does not hesitate to learn something new and share it. It asks for more feedback to seek improvements.&lt;/p>
&lt;p>We can imagine something at this level happened during the game&amp;rsquo;s development. How do we know? The result is there. It is unacceptable to keep seeing errors like these in games. Let us use good practices and understand the importance of software testing throughout the project and process. Now we can only wait for new fixes and a drastic improvement as soon as possible.&lt;/p>
&lt;h2>Sources for research and reading&lt;span class="hx:absolute hx:-mt-20" id="sources-for-research-and-reading">&lt;/span>
&lt;a href="#sources-for-research-and-reading" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>TDD — Test-Driven Development — Kent Beck — Book here.&lt;/p>
&lt;p>Link to Naughty Dog feedback.&lt;/p>
&lt;p>Adrenaline video: The Last of Us Part 1 on PC — testing hardware live! Adrenaline video: Resident Evil 4 Remake — is it good on PC? [review]&lt;/p>
&lt;p>Adrenaline video: The Last of Us Part 1 — five reasons it is one of the worst ports ever made.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/outubro/uma-analise-de-lancamentos-de-jogos-no-pc-imagens/joel-the-last-of-us.png" alt="Joel in a scene from The Last of Us Part I" loading="lazy" />&lt;/p>
&lt;h2>A tip for improving team communication&lt;span class="hx:absolute hx:-mt-20" id="a-tip-for-improving-team-communication">&lt;/span>
&lt;a href="#a-tip-for-improving-team-communication" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Try tools people feel comfortable with. Examples for communication are Gather Town and Discord.&lt;/p>
&lt;p>Create relaxed environments that bring clarity to communication and help people understand their colleagues better.&lt;/p>
&lt;p>Take part in code reviews and project development too.&lt;/p></description></item><item><title>Refactoring my blog</title><link>https://ladydebug.com.br/en/docs/2026/julho/refactor-blog/</link><pubDate>Fri, 10 Jul 2026 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2026/julho/refactor-blog/</guid><description>
&lt;h2>Analysis of the notion-blog repository&lt;span class="hx:absolute hx:-mt-20" id="analysis-of-the-notion-blog-repository">&lt;/span>
&lt;a href="#analysis-of-the-notion-blog-repository" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>My personal blog was full of bugs because I had not done the necessary maintenance since creating it, perhaps two years ago. Now the idea is to fix bugs and add features I would like.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/refactor-blog/repo-atual-notion-blog.png" alt="Old blog using Next.js and Notion" loading="lazy" />&lt;/p>
&lt;p>Broken pagination, slow loading, and content centralized in one tool.&lt;/p>
&lt;p>&lt;strong>What I want to improve:&lt;/strong> decentralize the content, organize routine versioned backups, and deploy to dev as well as main.&lt;/p>
&lt;hr>
&lt;h2>1. Overview&lt;span class="hx:absolute hx:-mt-20" id="1-overview">&lt;/span>
&lt;a href="#1-overview" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>It is a &lt;strong>static Next.js blog using Notion as its CMS/backend&lt;/strong>. It is a fork of the original &lt;a href="https://github.com/ijjk/notion-blog"target="_blank" rel="noopener">&lt;code>ijjk/notion-blog&lt;/code>&lt;/a> template, customized by me. Post content lives in a Notion table, and the site is generated through &lt;strong>SSG, Static Site Generation&lt;/strong>, with incremental revalidation, hosted on Vercel.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Current deployment:&lt;/strong> &lt;code>https://notion-blog-lake-two.vercel.app/&lt;/code>&lt;/li>
&lt;li>&lt;strong>Current branch:&lt;/strong> &lt;code>claude/repository-analysis-ieglo6&lt;/code>, identical to develop, with no differences.&lt;/li>
&lt;li>&lt;strong>License:&lt;/strong> present, &lt;code>license&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h2>2. Stack and dependencies&lt;span class="hx:absolute hx:-mt-20" id="2-stack-and-dependencies">&lt;/span>
&lt;a href="#2-stack-and-dependencies" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Layer&lt;/th>
&lt;th>Technology&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>Language&lt;/td>
&lt;td>TypeScript &lt;code>5.8&lt;/code>, with &lt;code>strict: false&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Content&lt;/td>
&lt;td>&lt;strong>Unofficial private Notion API&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>, equations; &lt;code>prismjs&lt;/code>, syntax highlighting; &lt;code>@zeit/react-jsx-parser&lt;/code>; &lt;code>async-sema&lt;/code>, rate limiting; &lt;code>github-slugger&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Quality&lt;/td>
&lt;td>Prettier, lint-staged, pre-commit&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Deployment&lt;/td>
&lt;td>Vercel&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2>3. Structure&lt;span class="hx:absolute hx:-mt-20" id="3-structure">&lt;/span>
&lt;a href="#3-structure" class="subheading-anchor" aria-label="Permalink for this section">&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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. How it works — Data flow&lt;span class="hx:absolute hx:-mt-20" id="4-how-it-works--data-flow">&lt;/span>
&lt;a href="#4-how-it-works--data-flow" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>&lt;strong>&lt;code>rpc.ts&lt;/code>&lt;/strong> sends authenticated POST requests to Notion&amp;rsquo;s private endpoint using the &lt;code>token_v2=$NOTION_TOKEN&lt;/code> cookie.&lt;/li>
&lt;li>&lt;strong>&lt;code>getBlogIndex&lt;/code>&lt;/strong> loads the table, &lt;code>BLOG_INDEX_ID&lt;/code>, builds the post map through &lt;code>getTableData&lt;/code>, which interprets the Notion collection schema, and fetches previews for the 10 most recent posts with concurrency limited to three through &lt;code>async-sema&lt;/code>. It uses disk caching, &lt;code>.blog_index_data*&lt;/code>, during builds, &lt;code>USE_CACHE&lt;/code>.&lt;/li>
&lt;li>&lt;strong>&lt;code>blog/index.tsx&lt;/code>&lt;/strong> filters drafts in production, &lt;code>Published === 'Yes'&lt;/code>, and lists posts.&lt;/li>
&lt;li>&lt;strong>&lt;code>blog/[slug].tsx&lt;/code>&lt;/strong> retrieves post content through &lt;code>getPageData&lt;/code> and paginated &lt;code>loadPageChunk&lt;/code>, resolves tweet embeds, and uses a large switch to convert each Notion block type into JSX: text, header, image, code, quote, callout, equation, bookmark, tweet, and others.&lt;/li>
&lt;li>&lt;strong>&lt;code>api/asset.ts&lt;/code>&lt;/strong> acts as a proxy: it retrieves the signed Notion file URL with &lt;code>getSignedFileUrls&lt;/code>, then redirects with status 307 to serve images and videos.&lt;/li>
&lt;li>&lt;strong>&lt;code>build-rss.ts&lt;/code>&lt;/strong> runs at build time and generates the Atom feed at &lt;code>/public/atom&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Preview mode:&lt;/strong> &lt;code>api/preview.ts&lt;/code> and &lt;code>preview-post.ts&lt;/code> enable Next&amp;rsquo;s draft mode.&lt;/li>
&lt;/ol>
&lt;h2>5. Strengths&lt;span class="hx:absolute hx:-mt-20" id="5-strengths">&lt;/span>
&lt;a href="#5-strengths" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>A lean architecture with clear separation between lib, pages, and components.&lt;/li>
&lt;li>Correct use of SSG with &lt;code>revalidate&lt;/code>, ISR, and &lt;code>fallback: true&lt;/code>.&lt;/li>
&lt;li>Preview-fetch rate limiting and build caching.&lt;/li>
&lt;li>Rich Notion block support: KaTeX equations, Prism code, callouts, bookmarks, videos, tweets.&lt;/li>
&lt;li>Formatting tools: Prettier and lint-staged.&lt;/li>
&lt;/ul>
&lt;h2>6. Problems and risks I found&lt;span class="hx:absolute hx:-mt-20" id="6-problems-and-risks-i-found">&lt;/span>
&lt;a href="#6-problems-and-risks-i-found" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;h3>Security and practical concerns&lt;span class="hx:absolute hx:-mt-20" id="security-and-practical-concerns">&lt;/span>
&lt;a href="#security-and-practical-concerns" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;strong>&lt;code>NOTION_TOKEN&lt;/code> used as the preview password:&lt;/strong> &lt;code>preview.ts&lt;/code> and &lt;code>preview-post.ts&lt;/code> compare &lt;code>req.query.token === process.env.NOTION_TOKEN&lt;/code>. This puts the &lt;strong>secret Notion token in the URL&lt;/strong>, exposing it to logs, history, and referrers. A separate secret such as &lt;code>NEXT_PREVIEW_SECRET&lt;/code> should be used.&lt;/li>
&lt;li>&lt;strong>Private Notion API&lt;/strong>, &lt;code>token_v2&lt;/code> and &lt;code>/api/v3&lt;/code>: unofficial, potentially subject to breaking changes, and the token is your personal session. The preferred approach is migration to the &lt;strong>official Notion API&lt;/strong>, &lt;code>@notionhq/client&lt;/code>.&lt;/li>
&lt;li>&lt;strong>&lt;code>api/asset.ts&lt;/code> is an open proxy&lt;/strong>, &lt;code>Access-Control-Allow-Origin: *&lt;/code>, signing URLs for any supplied &lt;code>assetUrl&lt;/code> or &lt;code>blockId&lt;/code>. It is worth restricting.&lt;/li>
&lt;/ul>
&lt;h3>Undeclared dependencies&lt;span class="hx:absolute hx:-mt-20" id="undeclared-dependencies">&lt;/span>
&lt;a href="#undeclared-dependencies" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;code>node-fetch&lt;/code>, &lt;code>@next/env&lt;/code>, and &lt;code>shell-quote&lt;/code> are &lt;strong>imported but absent from package.json&lt;/strong>, working only through transitive dependencies or hoisting. This is fragile and can break builds with a clean lockfile. They should be explicit dependencies.&lt;/li>
&lt;/ul>
&lt;h3>Leftovers from the original template and inconsistent branding&lt;span class="hx:absolute hx:-mt-20" id="leftovers-from-the-original-template-and-inconsistent-branding">&lt;/span>
&lt;a href="#leftovers-from-the-original-template-and-inconsistent-branding" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;code>header.tsx&lt;/code>: the Source Code link and OG image point to &lt;code>ijjk/notion-blog&lt;/code> and &lt;code>notion-blog.now.sh&lt;/code>, whose now.sh domain is disabled; Twitter points to &lt;code>@_ijjk&lt;/code>.&lt;/li>
&lt;li>&lt;code>footer.tsx&lt;/code>: links to ijjk&amp;rsquo;s repository.&lt;/li>
&lt;li>&lt;code>index.tsx&lt;/code>: still uses the Vercel + Notion image and branding.&lt;/li>
&lt;li>Generic metadata and &lt;code>&amp;lt;title&amp;gt;&lt;/code>, such as My Notion Blog and An example Next.js site…&lt;/li>
&lt;li>&lt;strong>Mixed Portuguese and English&lt;/strong> in the interface.&lt;/li>
&lt;/ul>
&lt;h3>Potentially broken or fragile code&lt;span class="hx:absolute hx:-mt-20" id="potentially-broken-or-fragile-code">&lt;/span>
&lt;a href="#potentially-broken-or-fragile-code" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Tweet embeds&lt;/strong> use &lt;code>api.twitter.com/1/statuses/oembed.json&lt;/code>, the discontinued v1 API, and probably no longer work.&lt;/li>
&lt;li>&lt;code>[slug].tsx&lt;/code> uses &lt;code>unstable_revalidate&lt;/code>, an old API ignored in Next 11, alongside &lt;code>revalidate&lt;/code>.&lt;/li>
&lt;li>&lt;code>equation.tsx&lt;/code>: &lt;code>render()&lt;/code> can return &lt;code>undefined&lt;/code> if an error is not a &lt;code>ParseError&lt;/code>, because &lt;code>result&lt;/code> is never assigned.&lt;/li>
&lt;li>&lt;code>getPageData&lt;/code> removes table blocks with a fixed &lt;code>splice(0, 3)&lt;/code>, which is brittle.&lt;/li>
&lt;li>&lt;strong>Inconsistent Node versions:&lt;/strong> the README asks for Node &lt;code>&amp;gt;=18&lt;/code>, but &lt;code>getBlogIndex.ts&lt;/code> uses &lt;code>Array.prototype.toSorted()&lt;/code>, requiring &lt;strong>Node 20+&lt;/strong>. Meanwhile, &lt;code>vercel.json&lt;/code> forces &lt;code>-openssl-legacy-provider&lt;/code> as a workaround for old builds. I recommend explicitly fixing Node 20.&lt;/li>
&lt;/ul>
&lt;h3>Quality and maintenance&lt;span class="hx:absolute hx:-mt-20" id="quality-and-maintenance">&lt;/span>
&lt;a href="#quality-and-maintenance" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>&lt;code>tsconfig&lt;/code> uses &lt;code>strict: false&lt;/code>, reducing type safety, with many uses of &lt;code>any&lt;/code>.&lt;/li>
&lt;li>&lt;strong>No tests or CI&lt;/strong>, with &lt;code>.github/&lt;/code> absent.&lt;/li>
&lt;li>Small README errors, such as using &lt;code>´´´&lt;/code> instead of Markdown code fences.&lt;/li>
&lt;/ul>
&lt;h2>7. Prioritized recommendations&lt;span class="hx:absolute hx:-mt-20" id="7-prioritized-recommendations">&lt;/span>
&lt;a href="#7-prioritized-recommendations" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Replace the preview secret&lt;/strong> with a dedicated variable, avoiding &lt;code>NOTION_TOKEN&lt;/code> in the URL.&lt;/li>
&lt;li>&lt;strong>Declare &lt;code>node-fetch&lt;/code>, &lt;code>@next/env&lt;/code>, and &lt;code>shell-quote&lt;/code>&lt;/strong> in package.json.&lt;/li>
&lt;li>&lt;strong>Update branding:&lt;/strong> links, OG image, title, and Twitter should use mine, removing ijjk and now.sh leftovers.&lt;/li>
&lt;li>&lt;strong>Fix or remove tweet embeds&lt;/strong>, the dead v1 API, and &lt;code>unstable_revalidate&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Align the Node version&lt;/strong>, fixing &lt;code>engines: node &amp;gt;=20&lt;/code> because of &lt;code>toSorted()&lt;/code>.&lt;/li>
&lt;li>In the medium term, &lt;strong>migrate to the official Notion API&lt;/strong> and consider upgrading Next.js from version 11 for security and performance.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2>Blog fixes&lt;span class="hx:absolute hx:-mt-20" id="blog-fixes">&lt;/span>
&lt;a href="#blog-fixes" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/refactor-blog/correcoes-blog.png" alt="Fixes applied to the blog" loading="lazy" />&lt;/p>
&lt;p>First I requested an analysis through claude.ai, then wrote the following instructions:&lt;/p>
&lt;blockquote>
&lt;p>📚 claude/repository-analysis-ieglo6? I can start with low-risk, high-impact changes: package.json dependencies, branding, the preview secret, and small bugs. Since this was an analysis task, I have not made changes yet.&lt;/p>
&lt;p>Implement as follows.&lt;/p>
&lt;ul>
&lt;li>Fix the issues and always run the necessary tests. Do not implement without testing.&lt;/li>
&lt;li>Open PRs after validation tests.&lt;/li>
&lt;li>Handle sensitive updates carefully to avoid breaking production.&lt;/li>
&lt;li>Document changes only in my kellen-xavier repository.&lt;/li>
&lt;li>Create /docs for documentation.&lt;/li>
&lt;li>Do not share keys or sensitive data, including in documentation or README.md.&lt;/li>
&lt;li>Create an .agents setup for persistent information.&lt;/li>
&lt;li>Include .AGENTS.md in the setup.&lt;/li>
&lt;/ul>
&lt;p>Pay attention and test at every step.&lt;/p>
&lt;/blockquote>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Stage&lt;/th>
&lt;th>Change&lt;/th>
&lt;th>Validation&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Dependencies&lt;/strong>&lt;/td>
&lt;td>Declared &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> as dev, and &lt;code>@types/node-fetch&lt;/code>; added &lt;code>engines.node &amp;gt;=20&lt;/code> and typecheck/test scripts&lt;/td>
&lt;td>Passing tsc&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Security, sensitive&lt;/strong>&lt;/td>
&lt;td>Dedicated &lt;code>PREVIEW_TOKEN&lt;/code> in &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>with fallback&lt;/strong> to &lt;code>NOTION_TOKEN&lt;/code> to avoid breaking production&lt;/td>
&lt;td>Four tests: 401, 404, success, fallback&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Branding&lt;/strong>&lt;/td>
&lt;td>Removed ijjk and now.sh leftovers from header, footer, and server constants&lt;/td>
&lt;td>Regression test&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Bugs&lt;/strong>&lt;/td>
&lt;td>&lt;code>equation.render&lt;/code> never returns undefined; &lt;code>unstable_revalidate&lt;/code> replaced by &lt;code>revalidate&lt;/code>; dead v1 tweet oEmbed replaced by &lt;code>publish.twitter.com&lt;/code>&lt;/td>
&lt;td>Render test and build&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Docs&lt;/strong>&lt;/td>
&lt;td>/docs with SETUP, ARCHITECTURE, SECURITY, CHANGELOG, only in my repository&lt;/td>
&lt;td>—&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Agents&lt;/strong>&lt;/td>
&lt;td>AGENTS.md in the root and .agents/ for persistent context and conventions&lt;/td>
&lt;td>—&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;ul>
&lt;li>For &lt;code>.AGENTS.md&lt;/code>, with a leading dot, I used the standard &lt;code>AGENTS.md&lt;/code> convention at the root, the name agent tools recognize, plus an &lt;code>.agents/&lt;/code> folder for persistent setup.&lt;/li>
&lt;li>The PR targeted &lt;strong>develop&lt;/strong>, the repository&amp;rsquo;s default branch, in four thematic commits.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3>How did it turn out?&lt;span class="hx:absolute hx:-mt-20" id="how-did-it-turn-out">&lt;/span>
&lt;a href="#how-did-it-turn-out" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>I was still using Notion, but wanted to extract all the text and keep it in my own repository. That started the migration to a different layout: the &lt;a href="https://themes.gohugo.io/themes/hextra/"target="_blank" rel="noopener">Hextra template&lt;/a>. I used AI to migrate the posts first. Since Notion can export Markdown files, moving everything at once was simpler. Then I configured the new template, added the features I wanted, and adapted its cleaner, simpler layout. This continues in “Refactoring the blog — part 2”, which is still a draft.&lt;/p></description></item><item><title>Bot Planner — Tracking personal development work</title><link>https://ladydebug.com.br/en/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/</guid><description>
&lt;p>Recently I have been developing some AI study projects, and I needed a way to organize how long I spent working on them: elapsed time.&lt;/p>
&lt;p>While developing something, I usually read language documentation for practices, collect document links, and write documentation for particular project features. I also remember tasks while working and notice things I can finish right after the current task. Add comments about what was done, and that is the general tracking I needed.&lt;/p>
&lt;p>Based on that problem, I thought of something practical to use during development: &lt;code>/inicio&lt;/code> when starting an activity, &lt;code>/link&lt;/code> to add documentation and other important references, &lt;code>/nota&lt;/code> for notes and comments, &lt;code>task&lt;/code> to create tasks, and &lt;code>fim&lt;/code> when finishing everything. Afterward, it should generate release notes describing completed work and pending tasks.&lt;/p>
&lt;p>Then I read &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">a blog post&lt;/a> and thought of creating a personal management bot to support my development cycle with little friction and generate notes at the end of the work.&lt;/p>
&lt;p>It could also be used for sharing with someone on the team, following XP-oriented development.&lt;/p>
&lt;hr>
&lt;p>I created the repository at &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>initially private, with plans to release it afterward&lt;/del>, now open source. I am fixing some security issues and first creating the bot. Initially interaction is through Discord, but it will support multiple communication channels. I mainly considered Slack and Discord; the others did not particularly interest me.&lt;/p>
&lt;h2>First development phase&lt;span class="hx:absolute hx:-mt-20" id="first-development-phase">&lt;/span>
&lt;a href="#first-development-phase" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image.png" alt="Initial bot development" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-1.png" alt="First commands" loading="lazy" />&lt;/p>
&lt;p>During initial testing, commands cluttered the unified chat. I considered creating a second text channel for separate release notes, making it easier to review the following day with a clear distinction between commands and release notes.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-2.png" alt="Separating commands and release notes" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h3>Bot organization&lt;span class="hx:absolute hx:-mt-20" id="bot-organization">&lt;/span>
&lt;a href="#bot-organization" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Configuring the bot is straightforward. Follow the official documentation: &lt;a href="https://docs.discord.com/developers/quick-start/getting-started"target="_blank" rel="noopener">Building your first Discord bot&lt;/a>.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-3.png" alt="Bot configuration" loading="lazy" />&lt;/p>
&lt;p>&lt;strong>Configuring the bot for this case study:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Go to the Discord Developer Portal.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Open the ladydebug-bot-planner app.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Go to Bot.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Click Reset Token.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Copy the new token.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Update DISCORD_TOKEN in &lt;code>.env&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Run again:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Set up the minimum local configuration.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Your local &lt;code>.env&lt;/code> should contain at least:&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>Bot Planner test plan&lt;span class="hx:absolute hx:-mt-20" id="bot-planner-test-plan">&lt;/span>
&lt;a href="#bot-planner-test-plan" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Overview.&lt;/p>
&lt;p>&lt;strong>Checklist:&lt;/strong>&lt;/p>
&lt;h4>All items&lt;span class="hx:absolute hx:-mt-20" id="all-items">&lt;/span>
&lt;a href="#all-items" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h4>&lt;p>[•] Map existing modules and features in src/daily.
[ ] Map existing tests by feature.
[ ] Run available tests and coverage.
[ ] Consolidate coverage gaps and recommendations.&lt;/p>
&lt;h3>Features with tests&lt;span class="hx:absolute hx:-mt-20" id="features-with-tests">&lt;/span>
&lt;a href="#features-with-tests" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>I created the report at docs/TEST_COVERAGE_REPORT.md, documenting:&lt;/p>
&lt;ul>
&lt;li>Current suite status: 79 passed.&lt;/li>
&lt;li>Guidelines for avoiding biased tests and false positives.&lt;/li>
&lt;li>Remaining gaps by priority.&lt;/li>
&lt;li>Exact scenarios to implement.&lt;/li>
&lt;li>Acceptance criteria for subsequent rounds.&lt;/li>
&lt;li>A recommendation to add pytest-cov.&lt;/li>
&lt;li>Suggested execution order.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Main areas prioritized in the 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>End-of-day report.&lt;/li>
&lt;li>Discord adapter callbacks.&lt;/li>
&lt;li>Models/DTOs.&lt;/li>
&lt;li>Objective coverage measurements.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;p>&lt;strong>Errors encountered:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Reason:&lt;/strong>&lt;/p>
&lt;p>DayAlreadyOpen: a day is already open for this user.
This happens because &lt;code>/inicio&lt;/code> opened a session in daily.db, and then &lt;code>/inicio&lt;/code> was called again without first closing it with &lt;code>/fim&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Explanation:&lt;/strong>&lt;/p>
&lt;p>Technical cause: the core correctly prevents two days from being open:&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-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">_storage&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_open_session&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">user_id&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">raise&lt;/span> &lt;span class="n">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;/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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>The problem is that this exception reaches Discord and produces a stack trace. The bot should respond with a friendly message, such as: &amp;ldquo;You already have an open day. Use /fim to close it before starting another.&amp;rdquo;&lt;/p>
&lt;p>&lt;strong>Corrections:&lt;/strong>&lt;/p>
&lt;p>Adjustment plan: still in planning mode, so no files will be edited yet. The recommended changes are:&lt;/p>
&lt;ol>
&lt;li>Handle DayAlreadyOpen in CommandRouter.inicio.&lt;/li>
&lt;li>Handle NoOpenDay in &lt;code>/nota&lt;/code>, &lt;code>/link&lt;/code>, and &lt;code>/fim&lt;/code>.&lt;/li>
&lt;li>Prevent expected core exceptions from becoming Discord errors.&lt;/li>
&lt;li>Improve Discord environment diagnostics with DISCORD_CLIENT_ID.&lt;/li>
&lt;li>Document local and production configuration in the README.&lt;/li>
&lt;li>Add tests for these cases.&lt;/li>
&lt;/ol>
&lt;h2>Expected behavior after the adjustments&lt;span class="hx:absolute hx:-mt-20" id="expected-behavior-after-the-adjustments">&lt;/span>
&lt;a href="#expected-behavior-after-the-adjustments" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Validate &lt;code>/inicio&lt;/code> with a day already open and activities unfinished.
Expected message:&lt;/p>
&lt;p>🟡 You already have an open day. Use &lt;code>/continuar&lt;/code> to resume your day.&lt;/p>
&lt;p>Behavior: submitting &lt;code>/continue&lt;/code> should continue adding activities to the day. In other words:&lt;/p>
&lt;p>&lt;strong>Scenario:&lt;/strong>&lt;/p>
&lt;p>Given the user sends &lt;code>/iniciar&lt;/code> on day 1,
and sends &lt;code>/iniciar&lt;/code> again on day 1,
when the message returns, &amp;ldquo;🟡 You already have an open day. Use &lt;code>/continuar&lt;/code> to resume your day,&amp;rdquo;
then the user should enter &lt;code>/continuar&lt;/code>
and continue until finishing the day.&lt;/p>
&lt;p>Validate &lt;code>/nota&lt;/code> without an open day.
Expected message: ⚠️ No open day. Use /inicio first.&lt;/p>
&lt;p>Validate &lt;code>/fim&lt;/code> without an open day.
Expected message: ⚠️ No open day to close. Use /inicio to start.&lt;/p>
&lt;p>Validate &lt;code>/link&lt;/code> without an open day.
Expected message: ⚠️ No open day. Use /inicio first.&lt;/p>
&lt;h3>Files that should change&lt;span class="hx:absolute hx:-mt-20" id="files-that-should-change">&lt;/span>
&lt;a href="#files-that-should-change" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&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>What changed:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>src/daily/command_router.py.&lt;/li>
&lt;li>&lt;code>/inicio&lt;/code> with an open day now returns: 🟡 You already have an open day. Use /continuar to resume your day.&lt;/li>
&lt;li>New continuar method.&lt;/li>
&lt;li>&lt;code>/nota&lt;/code>, &lt;code>/link&lt;/code>, and &lt;code>/fim&lt;/code> now handle NoOpenDay with friendly messages.&lt;/li>
&lt;li>&lt;code>/link&lt;/code> checks for an open day before fetching and summarizing a URL.&lt;/li>
&lt;li>src/daily/adapters/discord_bot.py.&lt;/li>
&lt;li>Added the Discord &lt;code>/continuar&lt;/code> command.&lt;/li>
&lt;li>Improved diagnostics when the bot cannot see the server.&lt;/li>
&lt;li>If DISCORD_CLIENT_ID is configured, the error prints the correct invitation URL.&lt;/li>
&lt;li>src/daily/main.py.&lt;/li>
&lt;li>Added environment validation: DISCORD_TOKEN is required; DISCORD_GUILD_ID and DISCORD_CLIENT_ID must be numeric when supplied.&lt;/li>
&lt;li>.env.example.&lt;/li>
&lt;li>Added 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>Documented &lt;code>/continuar&lt;/code>.&lt;/li>
&lt;li>Documented local and production environments.&lt;/li>
&lt;li>Added Discord troubleshooting.&lt;/li>
&lt;li>Added tests for &lt;code>/inicio&lt;/code> with an open day.&lt;/li>
&lt;li>Added tests for &lt;code>/continuar&lt;/code> with and without an open day.&lt;/li>
&lt;li>Added tests for &lt;code>/nota&lt;/code>, &lt;code>/link&lt;/code>, and &lt;code>/fim&lt;/code> without an open day.&lt;/li>
&lt;li>Added tests for DISCORD_CLIENT_ID and DISCORD_GUILD_ID validation.&lt;/li>
&lt;li>Added tests for the invitation URL in diagnostics.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3>Overview of Discord tests&lt;span class="hx:absolute hx:-mt-20" id="overview-of-discord-tests">&lt;/span>
&lt;a href="#overview-of-discord-tests" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-4.png" alt="Testing with Discord" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h3>Updates and improvements&lt;span class="hx:absolute hx:-mt-20" id="updates-and-improvements">&lt;/span>
&lt;a href="#updates-and-improvements" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>A second text channel was added. The &lt;code>/fim&lt;/code> command finishes the report and adds the day&amp;rsquo;s release notes to the channel that made the call.&lt;/p>
&lt;p>We then noticed that activities created during the day need to be completed. This leads to the next feature.&lt;/p>
&lt;p>&lt;strong>Feature:&lt;/strong> given that a user completes a created task, they should submit &lt;code>/fim-task&lt;/code> with the following action.&lt;/p>
&lt;p>&lt;strong>Expected behavior:&lt;/strong>&lt;/p>
&lt;p>URL: add the link to the completed activity.
Task title: my task&amp;rsquo;s name.
Time the activity was open: xx minutes / xx hours / xx days.&lt;/p>
&lt;p>Given that the activity contains a comment,
when the action is completed,
then the release notes should display the comments added to that action.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal/image-5.png" alt="Completing a task" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h3>Production workflow&lt;span class="hx:absolute hx:-mt-20" id="production-workflow">&lt;/span>
&lt;a href="#production-workflow" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>Create a #release-notes channel.&lt;/li>
&lt;li>Copy its channel ID.&lt;/li>
&lt;li>Create an app/bot in Discord.&lt;/li>
&lt;li>Invite the bot with bot applications.commands.&lt;/li>
&lt;li>Create a Railway project connected to GitHub.&lt;/li>
&lt;li>Configure secrets on Railway.&lt;/li>
&lt;li>Configure persistent storage.&lt;/li>
&lt;li>Start command: python -m daily.main.&lt;/li>
&lt;li>Deploy.&lt;/li>
&lt;li>Test in 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 coding agent with TUI and UI on Windows</title><link>https://ladydebug.com.br/en/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/</link><pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/</guid><description>
&lt;p>Continuing my &lt;strong>terminal and TUI studies&lt;/strong>, here I explore CRUSH on a Windows machine: how I configured it and how it has worked so far. I tested it with a simple open-source repository for setting up a Windows development environment.&lt;/p>
&lt;h3>Main goal&lt;span class="hx:absolute hx:-mt-20" id="main-goal">&lt;/span>
&lt;a href="#main-goal" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Let developers use &lt;strong>AI assistance directly in the terminal&lt;/strong>, without switching to a web editor or an &lt;strong>IDE with integrated plugins&lt;/strong>. It is also lighter to run than VS Code, for example. The tool offers:&lt;/p>
&lt;ul>
&lt;li>Integration with &lt;strong>multiple AI model providers&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Sessions&lt;/strong> with project context preserved.&lt;/li>
&lt;li>An optional interactive &lt;strong>TUI, Text User Interface&lt;/strong>.&lt;/li>
&lt;li>A &lt;strong>traditional CLI&lt;/strong> for automation or scripts.&lt;/li>
&lt;li>Extensibility through standards such as &lt;strong>Agent Skills&lt;/strong> and &lt;strong>MCP, Model Context Protocol&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Source:&lt;/strong> &lt;a href="https://github.com/charmbracelet/crush"target="_blank" rel="noopener">Crush on GitHub&lt;/a>&lt;/p>
&lt;h3>My first test on Windows&lt;span class="hx:absolute hx:-mt-20" id="my-first-test-on-windows">&lt;/span>
&lt;a href="#my-first-test-on-windows" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/configurando-windows.jpg" alt="Configuring Crush on Windows" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h2>Using it on a Windows machine&lt;span class="hx:absolute hx:-mt-20" id="using-it-on-a-windows-machine">&lt;/span>
&lt;a href="#using-it-on-a-windows-machine" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Installation:&lt;/strong> in PowerShell, I chose this command:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>That part was straightforward. To integrate the &lt;a href="https://openai.com/pt-BR/api/"target="_blank" rel="noopener">OpenAI API&lt;/a>, first create an &lt;a href="https://platform.openai.com/api-keys"target="_blank" rel="noopener">API key&lt;/a>. I followed &lt;a href="https://platform.openai.com/docs/quickstart?desktop-os=windows"target="_blank" rel="noopener">their Windows quickstart&lt;/a>. Copy your key and set it aside in a text note. After installing CRUSH on Windows, the configuration lives under &lt;code>C:\Users\SEU_USER&lt;/code>, specifically &lt;code>C:\Users\&amp;lt;SEU_USUARIO&amp;gt;\.config\crush\&lt;/code>.&lt;/p>
&lt;p>If the folder does not exist, create it with &lt;code>mkdir $HOME\.config\crush&lt;/code>. Then continue integrating an AI provider, OpenAI in this case. Below are the PowerShell commands for first creating an environment variable.&lt;/p>
&lt;h3>Create an environment variable&lt;span class="hx:absolute hx:-mt-20" id="create-an-environment-variable">&lt;/span>
&lt;a href="#create-an-environment-variable" class="subheading-anchor" aria-label="Permalink for this section">&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>As usual, close the terminal and start a new one. Check it with &lt;code>echo $Env:OPENAI_API_KEY&lt;/code>.&lt;/p>
&lt;p>Check that Crush works with &lt;code>crush --version&lt;/code>. If the version is displayed, start it:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>PowerShell loads the tool&amp;rsquo;s UI, and you can begin. For this test I decided to refactor a Windows setup project: &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>. It is not particularly exciting, but it is necessary and useful when reinstalling the environment. First I downloaded the repository through VS Code. Yes, I used the editor for now, although the other &lt;a href="https://github.com/charmbracelet"target="_blank" rel="noopener">Charmbracelet plugins&lt;/a> offer customization. That is not the focus here.&lt;/p>
&lt;h3>Practical use&lt;span class="hx:absolute hx:-mt-20" id="practical-use">&lt;/span>
&lt;a href="#practical-use" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Ask about the current project&amp;rsquo;s code. In this case, I went to my project folder:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>My first request was to analyze the project in general terms, looking for possible bugs. It then returned its findings.&lt;/p>
&lt;blockquote>
&lt;p>analyze possible errors&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/analisando-erros.jpg" alt="Analyzing errors as requested" loading="lazy" />&lt;/p>
&lt;p>I had forgotten to create &lt;a href="https://github.com/kellen-xavier/scripts-config-windows/blob/main/AGENTS.md"target="_blank" rel="noopener">AGENT.md&lt;/a>. CRUSH itself recommends it on screen, so I went ahead and created it. This is the original instruction block:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>List common software examples&lt;span class="hx:absolute hx:-mt-20" id="list-common-software-examples">&lt;/span>
&lt;a href="#list-common-software-examples" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;h3>Work VPNs&lt;span class="hx:absolute hx:-mt-20" id="work-vpns">&lt;/span>
&lt;a href="#work-vpns" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ul>
&lt;li>VPN: Netskope Client.&lt;/li>
&lt;/ul>
&lt;h3>Applications&lt;span class="hx:absolute hx:-mt-20" id="applications">&lt;/span>
&lt;a href="#applications" class="subheading-anchor" aria-label="Permalink for this section">&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>Browsers&lt;span class="hx:absolute hx:-mt-20" id="browsers">&lt;/span>
&lt;a href="#browsers" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Google Chrome, Edge, Firefox, Opera.&lt;/p>
&lt;h3>Development languages&lt;span class="hx:absolute hx:-mt-20" id="development-languages">&lt;/span>
&lt;a href="#development-languages" class="subheading-anchor" aria-label="Permalink for this section">&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>README.md documentation&lt;span class="hx:absolute hx:-mt-20" id="readmemd-documentation">&lt;/span>
&lt;a href="#readmemd-documentation" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>Specify the minimum Windows 10 version: 1809+ is required for winget.&lt;/li>
&lt;li>Require an up-to-date App Installer.&lt;/li>
&lt;li>Include troubleshooting.&lt;/li>
&lt;/ul>
&lt;h3>Registry backup&lt;span class="hx:absolute hx:-mt-20" id="registry-backup">&lt;/span>
&lt;a href="#registry-backup" class="subheading-anchor" aria-label="Permalink for this section">&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Correction priorities for the existing scripts&lt;span class="hx:absolute hx:-mt-20" id="correction-priorities-for-the-existing-scripts">&lt;/span>
&lt;a href="#correction-priorities-for-the-existing-scripts" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>Priority 1, security: add hash validation for Win11Debloat, back up the registry before changes, and implement Try-Catch in every script.&lt;/li>
&lt;li>Priority 2, functionality: implement persistent logging, add prerequisite checks, and correct the default-browser command.&lt;/li>
&lt;li>Priority 3, maintainability: add script parameters, implement idempotency, and add comment-based help.&lt;/li>
&lt;/ul>
&lt;h2>References&lt;span class="hx:absolute hx:-mt-20" id="references">&lt;/span>
&lt;a href="#references" class="subheading-anchor" aria-label="Permalink for this section">&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>I tried to include everything I understood to be appropriate for creating this setup. I also had to read the references to understand the best practices. It is important to understand exactly how to structure the AGENT file.&lt;/p>
&lt;p>&lt;strong>Then I asked it to execute the AGENT file:&lt;/strong> based on the AGENT.md file execute.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/executando-agent.jpg" alt="Running AGENT in a Windows setup repository with Crush" loading="lazy" />&lt;/p>
&lt;p>Based on the first command, it returned:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/solicitacao-correcao.jpg" alt="Request for corrections" loading="lazy" />&lt;/p>
&lt;p>Processing the AGENT file:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/processando-agent.jpg" alt="Processing AGENT" loading="lazy" />&lt;/p>
&lt;p>I opened VS Code to see how it was behaving:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/modificacoes-vscode.jpg" alt="Changes viewed in VS Code" loading="lazy" />&lt;/p>
&lt;p>Running lint:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/executando-lint.jpg" alt="Running lint" loading="lazy" />&lt;/p>
&lt;p>Running tests:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/executando-testes.jpg" alt="Running tests" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/analyze-repo-update-readme.jpg" alt="Analyzing the repository and updating the README" loading="lazy" />&lt;/p>
&lt;p>I asked for a README.md update:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/update-readme.jpg" alt="README.md update" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/readme-update-ok.jpg" alt="README successfully updated" loading="lazy" />&lt;/p>
&lt;p>Final project structure:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2026/janeiro/crush-agente-de-configuracao-no-terminal-tui-ui/estrutura-final-projeto.jpg" alt="Final project structure" loading="lazy" />&lt;/p></description></item><item><title>A BPMN cheat sheet</title><link>https://ladydebug.com.br/en/docs/2025/setembro/bpmn-fluxogramas/</link><pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/setembro/bpmn-fluxogramas/</guid><description>
&lt;p>For anyone starting to draw flowcharts, here are the BPMN event options.&lt;/p>
&lt;p>Start begins the flow, intermediate happens along the way, boundary attaches to an activity to handle something, and end finishes the path. The rule of thumb: catch waits for something; throw triggers something.&lt;/p>
&lt;hr>
&lt;h2>Start events&lt;span class="hx:absolute hx:-mt-20" id="start-events">&lt;/span>
&lt;a href="#start-events" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Start event, none:&lt;/strong> starts without a condition.&lt;/li>
&lt;li>&lt;strong>Message start:&lt;/strong> starts when a message arrives, such as a webhook.&lt;/li>
&lt;li>&lt;strong>Timer start:&lt;/strong> schedule/cron, using a date, delay, or repetition.&lt;/li>
&lt;li>&lt;strong>Conditional start:&lt;/strong> starts when an expression becomes true.&lt;/li>
&lt;li>&lt;strong>Signal start:&lt;/strong> starts upon receiving a broadcast signal.&lt;/li>
&lt;/ul>
&lt;h2>Intermediate events&lt;span class="hx:absolute hx:-mt-20" id="intermediate-events">&lt;/span>
&lt;a href="#intermediate-events" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Message intermediate, throw:&lt;/strong> sends a message to another participant.&lt;/li>
&lt;li>&lt;strong>Timer intermediate, catch:&lt;/strong> waits for a time or date.&lt;/li>
&lt;li>&lt;strong>Escalation intermediate, throw:&lt;/strong> raises an escalation without treating it as an error.&lt;/li>
&lt;li>&lt;strong>Conditional intermediate, catch:&lt;/strong> pauses until a condition becomes true.&lt;/li>
&lt;li>&lt;strong>Link, catch/throw:&lt;/strong> a jump within the same diagram, connecting points.&lt;/li>
&lt;li>&lt;strong>Compensation intermediate, throw:&lt;/strong> triggers compensation to undo something.&lt;/li>
&lt;li>&lt;strong>Signal intermediate, catch/throw:&lt;/strong> publish/subscribe broadcasting; any listener can receive it.&lt;/li>
&lt;/ul>
&lt;h2>Boundary events attached to a task or subprocess&lt;span class="hx:absolute hx:-mt-20" id="boundary-events-attached-to-a-task-or-subprocess">&lt;/span>
&lt;a href="#boundary-events-attached-to-a-task-or-subprocess" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Trigger when something happens &lt;strong>during&lt;/strong> the activity.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Interrupting, solid border:&lt;/strong> cancels the activity and redirects the flow.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Non-interrupting, dashed border:&lt;/strong> creates an alternative flow without cancelling the activity.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Common types: &lt;strong>Timer, Message, Conditional, Signal, Escalation, Compensation&lt;/strong>.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3>Special cases&lt;span class="hx:absolute hx:-mt-20" id="special-cases">&lt;/span>
&lt;a href="#special-cases" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;strong>Error boundary:&lt;/strong> interrupting only; catches errors from the subprocess.&lt;/p>
&lt;p>&lt;strong>Cancel boundary:&lt;/strong> only on a &lt;strong>Transaction subprocess&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Non-interrupting&lt;/strong> variations keep the activity running.&lt;/li>
&lt;/ul>
&lt;h2>End events&lt;span class="hx:absolute hx:-mt-20" id="end-events">&lt;/span>
&lt;a href="#end-events" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Message end:&lt;/strong> sends a message and ends.&lt;/li>
&lt;li>&lt;strong>Escalation end:&lt;/strong> notifies the level above and ends.&lt;/li>
&lt;li>&lt;strong>Error end:&lt;/strong> throws an error; leaves the subprocess until an &lt;em>error boundary&lt;/em> catches it.&lt;/li>
&lt;li>&lt;strong>Cancel end:&lt;/strong> cancels a &lt;strong>Transaction&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Compensation end:&lt;/strong> requests registered compensations.&lt;/li>
&lt;li>&lt;strong>Signal end:&lt;/strong> emits a broadcast signal and ends.&lt;/li>
&lt;li>&lt;strong>Terminate end:&lt;/strong> terminates &lt;strong>all&lt;/strong> active activities in the process or subprocess.&lt;/li>
&lt;/ul></description></item><item><title>Understanding terminals and everyday Git commands — part 1</title><link>https://ladydebug.com.br/en/docs/2025/junho/comandos-git/</link><pubDate>Tue, 17 Jun 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/junho/comandos-git/</guid><description>
&lt;p>This post started as a few practical Git commands for everyday use. But I had no written collection of terminal studies either: what a terminal is, how to use one, and where to read more before getting into Git commands.&lt;/p>
&lt;p>&lt;em>I always say it is important to know how to use the terminal. At a minimum, we need to know how to use these tools. There is no avoiding it, even if your IDE is perfect and entirely visual, because we will inevitably face problems outside the visual interface.&lt;/em>&lt;/p>
&lt;p>I like the driving analogy: imagine you are driving a car, it beeps and stops, and you need to open the hood to find out what happened. It could be a fully automatic BYD, but the car still contains logs and a black box called an EDR, Event Data Recorder. Here I use the expression &amp;ldquo;get your hands dirty&amp;rdquo; and encourage not being afraid of these commands. Understanding what happens under the hood brings much deeper clarity.&lt;/p>
&lt;hr>
&lt;h2>Some important basic concepts&lt;span class="hx:absolute hx:-mt-20" id="some-important-basic-concepts">&lt;/span>
&lt;a href="#some-important-basic-concepts" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;h3>What is a terminal?&lt;span class="hx:absolute hx:-mt-20" id="what-is-a-terminal">&lt;/span>
&lt;a href="#what-is-a-terminal" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>A terminal is a text interface for interacting directly with the operating system. It sends commands to a shell, such as Bash, Zsh, or PowerShell, which interprets and executes instructions through system APIs.&lt;/p>
&lt;h3>Terminal references — Reading and videos&lt;span class="hx:absolute hx:-mt-20" id="terminal-references--reading-and-videos">&lt;/span>
&lt;a href="#terminal-references--reading-and-videos" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;a href="https://pt.wikipedia.org/wiki/Terminal_%28inform%C3%A1tica%29"target="_blank" rel="noopener">Wikipedia&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 — Understanding Git, not a 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 — Using Git properly and cleaning up commits&lt;/a>&lt;/p>
&lt;h3>File system and navigation&lt;span class="hx:absolute hx:-mt-20" id="file-system-and-navigation">&lt;/span>
&lt;a href="#file-system-and-navigation" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Generally, navigating in a terminal means entering and leaving folders and handling files. It is like navigating a visual interface, but with commands. When we say &amp;ldquo;do this in the project/automation repository&amp;rdquo;, we mean inside that folder.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/junho/comandos-git/navegando-em-pastas.png" alt="Navigating folders" loading="lazy" />&lt;/p>
&lt;p>Visually, we have a screen and somewhere to navigate. When opening a terminal on Windows, for example, you may see &lt;code>C:\Users\meu.nome\Sua-pasta&lt;/code>. In the screenshot, this would be something like &lt;code>C:\Users\kellen.xavier\Documents\Estudos\docs-estudos-obsidian&lt;/code>. My personal organization puts projects in Documents, inside the study folder. So when I say &amp;ldquo;enter the Obsidian study project and run git pull&amp;rdquo;, that is the location I mean.&lt;/p>
&lt;p>For example, here is a folder I need to reach through the terminal. When opening it, most people will see something like:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Then we use commands to navigate there.&lt;/p>
&lt;h3>Commonly used commands&lt;span class="hx:absolute hx:-mt-20" id="commonly-used-commands">&lt;/span>
&lt;a href="#commonly-used-commands" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Navigation:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>In order, these commands show the current directory, list files and folders, show a detailed listing including hidden files, enter a folder, go up one level, and go to the home directory.&lt;/p>
&lt;p>&lt;strong>Clicking the address bar shows the path starting from kellen.xavier&lt;/strong>, in my case. My location is &lt;code>C:\Users\kellen.xavier\Documents\Estudos\docs-estudos-obsidian&lt;/code>, so in the 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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Now I have entered the folder:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/junho/comandos-git/entrando-na-pasta.png" alt="Entering the folder through the 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="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Here is a sequence of useful commands, especially when working on projects with more than one contributor. Do not forget them.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/junho/comandos-git/pc-fire.png" alt="Computer on fire" loading="lazy" />&lt;/p>
&lt;p>&lt;strong>To merge your current branch into the main branch, follow these steps:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>After updating your development branch, use git checkout to switch to develop or 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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Now you are on develop. Merge your development branch with this command:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>A brief note on pull requests&lt;span class="hx:absolute hx:-mt-20" id="a-brief-note-on-pull-requests">&lt;/span>
&lt;a href="#a-brief-note-on-pull-requests" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Creating a pull request, PR, on GitHub or another version control platform &lt;strong>proposes changes collaboratively and in a controlled way&lt;/strong>. A PR asks for changes on a specific branch to be reviewed and, if approved, merged into the project&amp;rsquo;s primary branch, such as main or develop.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Consider this scenario:&lt;/strong> if you need to work specifically on a branch &lt;strong>other than main&lt;/strong>, create a local branch based on the desired remote branch. Suppose you want to work on minha-branch.&lt;/p>
&lt;p>&lt;strong>Use this Git command:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>This creates a local branch called &lt;code>minha-branch&lt;/code> based on the remote &lt;code>origin/minha-branch-remota-desejada&lt;/code> branch.&lt;/p>
&lt;p>You can then work on the &lt;strong>local branch&lt;/strong>, committing and performing other operations as usual.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Everyday commands:&lt;/strong>&lt;/p>
&lt;p>Before starting development, update your local environment from the remote repository.&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>This updates the local environment with changes made by the project&amp;rsquo;s other contributors.&lt;/p>
&lt;p>The git pull command fetches the latest changes from a remote repository and then merges them into your current branch. In other words, it combines &lt;code>git fetch&lt;/code> and &lt;code>git merge&lt;/code>.&lt;/p>
&lt;p>Another git pull example:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Here, &lt;code>&amp;lt;remote&amp;gt;&lt;/code> names the remote repository you want to pull from, usually &lt;code>origin&lt;/code>, and &lt;code>&amp;lt;branch&amp;gt;&lt;/code> is the remote branch, such as &lt;code>main&lt;/code> or &lt;code>develop&lt;/code>.&lt;/p>
&lt;h3>Committing changes&lt;span class="hx:absolute hx:-mt-20" id="committing-changes">&lt;/span>
&lt;a href="#committing-changes" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>To send changes to the remote repository, stage them and write a message describing what changed.&lt;/p>
&lt;p>Stage a change:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>⚠️ Be careful with &lt;code>git add .&lt;/code>: it stages every change. Avoid using it indiscriminately; prefer:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Then write the commit message:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Read more about commit conventions here; the link will be added later.&lt;/strong>&lt;/p>
&lt;p>Now check your terminal. If there are no errors or conflicts, upload the changes:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>To merge your branch into &lt;code>main&lt;/code> in the repository, 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">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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>About git stash&lt;span class="hx:absolute hx:-mt-20" id="about-git-stash">&lt;/span>
&lt;a href="#about-git-stash" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>The &lt;code>git stash&lt;/code> command temporarily stores changes from your working directory, allowing you to return to the repository&amp;rsquo;s earlier state without committing them. This is useful when switching quickly between tasks or branches while preserving work that is not ready to commit.&lt;/p>
&lt;p>Here are some examples:&lt;/p>
&lt;p>&lt;strong>Temporarily store changes:&lt;/strong> if you have made changes but do not want to commit them yet, 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">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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>The description is optional and helps identify why you stashed the changes.&lt;/p>
&lt;p>&lt;strong>List stashes:&lt;/strong> list the stashes you created:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Apply a stash:&lt;/strong> apply the most recent stash or a specific one:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Remove a stash:&lt;/strong> after applying one, you can remove it:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Create a branch from a stash:&lt;/strong> create a new branch based on a stash:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Other important points:&lt;/strong>&lt;/p>
&lt;p>Update your &lt;strong>branch&lt;/strong> with &lt;strong>the latest changes from main&lt;/strong> to help &lt;strong>avoid merge conflicts&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 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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Attention&lt;/strong>&lt;/p>
&lt;p>Do not use git pull in these situations. Read the explanation of &lt;strong>git pull&lt;/strong> again.&lt;/p></description></item><item><title>A development testing workflow based on the test pyramid</title><link>https://ladydebug.com.br/en/docs/2025/junho/piramide-de-testes-para-dev/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/junho/piramide-de-testes-para-dev/</guid><description>
&lt;h3>1. What is development testing?&lt;span class="hx:absolute hx:-mt-20" id="1-what-is-development-testing">&lt;/span>
&lt;a href="#1-what-is-development-testing" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Before moving a card to QA, the development team should validate its code with systematic tests at different levels: unit, integration, and functional. This reduces rework and improves software quality.&lt;/p>
&lt;h3>2. Structuring the tests&lt;span class="hx:absolute hx:-mt-20" id="2-structuring-the-tests">&lt;/span>
&lt;a href="#2-structuring-the-tests" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>The test pyramid suggests:&lt;/p>
&lt;ul>
&lt;li>Read the user stories, their tests, and their acceptance criteria.&lt;/li>
&lt;li>&lt;strong>Unit tests, at the base:&lt;/strong> validate isolated pieces of code, such as functions and methods.&lt;/li>
&lt;li>&lt;strong>Integration tests, in the middle:&lt;/strong> ensure different parts of the system interact correctly.&lt;/li>
&lt;li>&lt;strong>Functional/E2E tests, at the top:&lt;/strong> validate the complete user flow.&lt;/li>
&lt;/ul>
&lt;h3>3. How can this be applied to a bug?&lt;span class="hx:absolute hx:-mt-20" id="3-how-can-this-be-applied-to-a-bug">&lt;/span>
&lt;a href="#3-how-can-this-be-applied-to-a-bug" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;h3>Step 1 — Unit test&lt;span class="hx:absolute hx:-mt-20" id="step-1--unit-test">&lt;/span>
&lt;a href="#step-1--unit-test" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>✅ Write tests for the query that retrieves the correct domain from the database.&lt;/p>
&lt;ul>
&lt;li>Check that the query returns only domains of the &lt;em>blog&lt;/em> type.&lt;/li>
&lt;li>Ensure the first domain is not selected indiscriminately.&lt;/li>
&lt;/ul>
&lt;p>Unit test example with 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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Step 2 — Integration test&lt;span class="hx:absolute hx:-mt-20" id="step-2--integration-test">&lt;/span>
&lt;a href="#step-2--integration-test" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>✅ Validate that &lt;code>SaveSessionsUrlAnalyticsJob.php&lt;/code> correctly saves data to the &lt;code>analytics_session_urls&lt;/code> table.&lt;/p>
&lt;ul>
&lt;li>Simulate running the job with different domain scenarios.&lt;/li>
&lt;li>Check that the data is recorded correctly.&lt;/li>
&lt;/ul>
&lt;h3>Step 3 — Functional test, if needed&lt;span class="hx:absolute hx:-mt-20" id="step-3--functional-test-if-needed">&lt;/span>
&lt;a href="#step-3--functional-test-if-needed" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>✅ Run the complete functionality and validate that RPS reports display the expected data.&lt;/p>
&lt;h3>4. How can the team adopt this?&lt;span class="hx:absolute hx:-mt-20" id="4-how-can-the-team-adopt-this">&lt;/span>
&lt;a href="#4-how-can-the-team-adopt-this" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>Before opening a bug, ensure the code passed unit and integration tests.&lt;/li>
&lt;li>Adopt a development testing workflow: &lt;strong>Developer implements – Code review – Development testing – QA&lt;/strong>.&lt;/li>
&lt;li>Record test evidence and include a PR, avoiding handing off code without prior verification.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>How to add evidence:&lt;/strong>&lt;/p>
&lt;p>&lt;strong>Tests running in the development environment:&lt;/strong> local validation, even with Docker, is not sufficient here because various environment and network factors have not been checked against the requirements. This can produce a false positive. Local tests belong to other testing categories, such as the unit tests mentioned above.&lt;/p>
&lt;ul>
&lt;li>Use the development environment.&lt;/li>
&lt;li>Include screenshots for end-to-end tests.&lt;/li>
&lt;li>Attach PRs to the card.&lt;/li>
&lt;li>Validate the test scenarios on the card. If they are missing, notify the responsible QA person.&lt;/li>
&lt;/ul></description></item><item><title>Adding shift-left testing to the quality process step by step</title><link>https://ladydebug.com.br/en/docs/2025/junho/processo-shift-left-testing-basico/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/junho/processo-shift-left-testing-basico/</guid><description>
&lt;p>Here is a brief overview of introducing a basic quality process to a team.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Goal — Use a backlog to refine user stories for development:&lt;/strong> create a backlog of testing tasks and activities from the beginning of the development cycle.&lt;/p>
&lt;p>&lt;strong>Write user stories with acceptance criteria, splitting complete flows into features:&lt;/strong> identify testing requirements for each feature through user stories. Include clear, specific acceptance criteria so every feature can be tested properly.&lt;/p>
&lt;p>&lt;strong>Develop test cases for each user story:&lt;/strong> write test cases that cover all aspects of the feature described in the story. Include both success and failure scenarios, covering different usage paths.&lt;/p>
&lt;p>&lt;strong>Perform static testing and analysis before development:&lt;/strong> review documents and perform static code reviews to identify potential problems before development begins. Use static analysis tools to identify possible vulnerabilities or errors in the source code.&lt;/p>
&lt;p>&lt;strong>Integrate automated tests into the development pipeline:&lt;/strong> automate unit, integration, and regression tests to protect the stability of developed features. Integrate those tests into the development pipeline for continuous execution after each code change.&lt;/p>
&lt;p>&lt;strong>Implement continuous reviews and iterative feedback:&lt;/strong> continuously review code and features under development to identify and correct problems quickly. Use iterative feedback with developers and the quality team to improve development.&lt;/p>
&lt;p>&lt;strong>Document and analyze quality and performance metrics:&lt;/strong> record quality metrics, test coverage, and software performance to assess testing effectiveness and identify improvements. Regularly analyze test results to adjust testing strategies as needed.&lt;/p></description></item><item><title>Do you still need Testing Library when an element has a data-cy attribute?</title><link>https://ladydebug.com.br/en/docs/2025/junho/testing-library-exemplos-de-configuracao/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/junho/testing-library-exemplos-de-configuracao/</guid><description>
&lt;p>Below is an example of code that uses &lt;code>data-cy&lt;/code> to locate elements in Cypress E2E automation.&lt;/p>
&lt;hr>
&lt;p>Using &lt;strong>Testing Library&lt;/strong> is useful when an element has not been defined for E2E testing, meaning it has no data-test/cy attribute. For Testing Library to recognize it in the automation, the element Cypress searches for should not have &lt;code>data-cy&lt;/code>; Testing Library then finds it using the pattern &lt;code>findByText.('Sua palavra mágica').click();&lt;/code>.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/junho/testing-library-exemplos-de-configuracao/cypress-testinglibrary.png" alt="Cypress and Testing Library" loading="lazy" />&lt;/p>
&lt;p>&lt;strong>Option 1 — Configure the &lt;code>setup-tests.js&lt;/code> file, Cypress v10+:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Create &lt;code>setup-tests.js&lt;/code> if it does not exist, in the project root or another location specified by your Cypress configuration. See the documentation for details.&lt;/li>
&lt;li>Configure the &lt;code>testIdAttribute&lt;/code> attribute:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Option 2 — Configure it directly in the test, Cypress v9 and earlier:&lt;/strong> if you use an older Cypress version, configure the library in the test file:&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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>Option 3 — Create a new command:&lt;/strong>&lt;/p>
&lt;p>Create a custom command that always uses &lt;code>findByTestId&lt;/code> with &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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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>References:&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>Poor practices to avoid in test automation</title><link>https://ladydebug.com.br/en/docs/2025/junho/praticas-ruins-de-testes-para-evitar-ou/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/junho/praticas-ruins-de-testes-para-evitar-ou/</guid><description>
&lt;p>Read this, print it, maybe print it and stick it on a few people&amp;rsquo;s computers…&lt;/p>
&lt;hr>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/junho/praticas-ruins-de-testes-para-evitar-ou/cat-cansado.png" alt="Tired cat" loading="lazy" />&lt;/p>
&lt;h2>1. Inadequate definition and planning&lt;span class="hx:absolute hx:-mt-20" id="1-inadequate-definition-and-planning">&lt;/span>
&lt;a href="#1-inadequate-definition-and-planning" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>No clear goals:&lt;/strong> failing to clearly define the goal of automation, the risks, scope, and stakeholders. Automation without well-defined goals can waste effort and deliver disappointing results.&lt;/p>
&lt;p>&lt;strong>A poorly defined automation strategy:&lt;/strong> lacking a test automation strategy that is applicable, customizable, and kept up to date. A poorly defined strategy can produce inefficient tests that are difficult to maintain.&lt;/p>
&lt;p>&lt;strong>Ignoring investment criteria:&lt;/strong> overlooking factors such as initial cost, SDLC stage, project duration, and maintenance costs when deciding what to automate. Failing to analyze these can lead to inappropriate investment and a low return.&lt;/p>
&lt;p>&lt;strong>Not prioritizing tests:&lt;/strong> failing to prioritize the test conditions with the greatest business impact. Automation effort should focus on the tests that deliver the most value.&lt;/p>
&lt;hr>
&lt;h2>2. Technical problems&lt;span class="hx:absolute hx:-mt-20" id="2-technical-problems">&lt;/span>
&lt;a href="#2-technical-problems" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Poor SUT testability:&lt;/strong> automating a System Under Test that is not easily testable, making its interfaces difficult to access. Testability is essential for effective automation.&lt;/p>
&lt;p>&lt;strong>Poor automation architecture and framework:&lt;/strong> lacking a clear Test Automation Architecture, TAA, and a Test Automation Framework, TAF, that is easy to use and maintain. Poor architecture and frameworks make automated tests harder to implement and maintain.&lt;/p>
&lt;p>&lt;strong>Inadequate test reports:&lt;/strong> failing to generate well-defined reports, making troubleshooting and tracking results difficult. Without clear reports, effective decisions become harder.&lt;/p>
&lt;p>&lt;strong>No deployment and execution plan:&lt;/strong> lacking a clear plan for deploying and executing tests, removing tests when necessary, and handling exceptions effectively. Without these plans, tests may not run correctly or may cause execution problems.&lt;/p>
&lt;p>&lt;strong>Undocumented test cases:&lt;/strong> failing to document automated test cases adequately, making them difficult to understand and maintain. Clear documentation is crucial for maintenance and traceability.&lt;/p>
&lt;hr>
&lt;h2>3. Inappropriate automation choices and applications&lt;span class="hx:absolute hx:-mt-20" id="3-inappropriate-automation-choices-and-applications">&lt;/span>
&lt;a href="#3-inappropriate-automation-choices-and-applications" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Automating unsuitable tests:&lt;/strong> selecting cases without considering technical feasibility, coding effort, execution frequency, repeatability, and maintainability. Not every test is suitable for automation.&lt;/p>
&lt;p>&lt;strong>Automating difficult tests:&lt;/strong> trying to automate difficult conditions such as design validation, complex human interactions, and operating system restrictions. Some tests are more effective when performed manually.&lt;/p>
&lt;p>&lt;strong>Focusing only on user interface tests:&lt;/strong> building a strategy that relies primarily on UI tests, which are expensive and difficult to maintain. A balanced strategy should include component, contract, and API tests.&lt;/p>
&lt;p>&lt;strong>Not optimizing test distribution:&lt;/strong> failing to balance tests across component, service, and UI levels, which can make tests slow and expensive. A pyramid-shaped distribution can improve efficiency.&lt;/p>
&lt;hr>
&lt;h2>4. Ineffective transition and maintenance&lt;span class="hx:absolute hx:-mt-20" id="4-ineffective-transition-and-maintenance">&lt;/span>
&lt;a href="#4-ineffective-transition-and-maintenance" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Not monitoring costs:&lt;/strong> failing to track costs and test suite growth during the transition to continuous testing. Monitoring both is necessary for an efficient transition.&lt;/p>
&lt;p>&lt;strong>Functional overlap:&lt;/strong> writing test scripts with overlapping functionality, such as repeating the same login steps in different test cases. This makes maintenance harder and increases the required effort.&lt;/p>
&lt;p>&lt;strong>Inadequate data sharing:&lt;/strong> failing to manage shared test data correctly, introducing duplication or errors. Data should be stored and accessed from a single source.&lt;/p>
&lt;p>&lt;strong>Undocumented preconditions:&lt;/strong> failing to document and automate the preconditions required to run tests, leading to failures and inconsistencies. Defining and automating preconditions is essential for repeatability.&lt;/p>
&lt;p>&lt;strong>Not testing automated tests:&lt;/strong> forgetting that automation is software and needs testing too. Test scripts should be tested to ensure they work correctly.&lt;/p>
&lt;p>&lt;strong>Not refactoring automation:&lt;/strong> failing to assess and refactor the automation solution, allowing technical debt and maintenance difficulties to accumulate. Seek continuous improvements and optimization.&lt;/p>
&lt;p>&lt;strong>Not adapting the TAS to changes:&lt;/strong> failing to adapt the Test Automation Solution to new SUT versions. The TAS should be flexible enough to follow system changes.&lt;/p>
&lt;hr>
&lt;h2>5. Other poor practices&lt;span class="hx:absolute hx:-mt-20" id="5-other-poor-practices">&lt;/span>
&lt;a href="#5-other-poor-practices" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>Excessive abstraction:&lt;/strong> using so much abstraction that automation code becomes hard to understand. Use abstraction in moderation to keep code understandable.&lt;/p>
&lt;p>&lt;strong>Complex data tables:&lt;/strong> creating very large, complex test data tables that make migration to other environments difficult. Manage test data efficiently.&lt;/p>
&lt;p>&lt;strong>Library dependencies:&lt;/strong> creating TAS dependencies on libraries or operating system components that may not be available everywhere. The TAS should be independent and portable across test environments.&lt;/p>
&lt;p>&lt;strong>Ignoring maintenance:&lt;/strong> failing to plan TAS maintenance as the SUT is updated. Continuous maintenance is essential to its effectiveness.&lt;/p>
&lt;p>&lt;strong>Not using metrics:&lt;/strong> failing to track pass/fail rates, failure and defect proportions, automation execution time, and functional and code coverage. These metrics help assess and optimize the TAS.&lt;/p>
&lt;p>&lt;strong>Not using test results to improve the process:&lt;/strong> failing to analyze report data to identify trends and improve the SDLC. Use test data for decisions and continuous improvement.&lt;/p>
&lt;p>By Kellen Xavier | &lt;a href="https://keepo.io/ladydebug/"target="_blank" rel="noopener">Contact&lt;/a>&lt;/p></description></item><item><title>Applying design thinking to a real fitness studio website project</title><link>https://ladydebug.com.br/en/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://ladydebug.com.br/en/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/</guid><description>
&lt;p>I am applying these studies to the strength training studio I attend in northern Porto Alegre. I asked the owner, who started the business in January 2025, for permission to apply the studies and develop a project for a real business with real needs.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>The project:&lt;/strong> create a landing page for the studio, applying Design Thinking techniques and the material from Innovation and Entrepreneurship — Inovação e Empreendedorismo - Web 03.&lt;/p>
&lt;p>&lt;strong>Project beginnings:&lt;/strong> I followed the studio&amp;rsquo;s opening from January 2025. Since then, a close friend and I have been members training at the new location. The first things I asked the owner were: how will the gym work? Will there be flexible hours? Who will train here?&lt;/p>
&lt;p>I tried to understand this better by talking to the owner of the strength training studio and asking these questions. Another important point is that I have trained there from the start. Since I knew the owner, I was the studio&amp;rsquo;s test member 😂. That helped the project because I experienced some important issues firsthand.&lt;/p>
&lt;h3>1. Empathy — Understand the problem from the user&amp;rsquo;s perspective&lt;span class="hx:absolute hx:-mt-20" id="1-empathy--understand-the-problem-from-the-users-perspective">&lt;/span>
&lt;a href="#1-empathy--understand-the-problem-from-the-users-perspective" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>As a gym member, I ran into questions: what are the prices? How do the packages with nutritional support work? Are there partnerships with supplement stores? How much does whey protein cost? And others. I noticed that later members had the same questions. When recommending the gym, I also struggled to share its address and quote prices from memory. I only knew what I used myself, which was TotalPass. There was no central place to consult this information.&lt;/p>
&lt;h3>2. Define — Refine the problem&lt;span class="hx:absolute hx:-mt-20" id="2-define--refine-the-problem">&lt;/span>
&lt;a href="#2-define--refine-the-problem" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>Based on this, I organized the information I had and talked to the owner to understand and refine the questions. Using design thinking techniques, I applied the &lt;strong>Value Proposition Canvas&lt;/strong> to get the ideas out of my head and share them with the person involved: the business owner. See below:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/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://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/aplicado-value-proposition-canvas.png" alt="Value Proposition Canvas applied to the studio project" loading="lazy" />&lt;/p>
&lt;p>I also used ChatGPT to structure the details and organize the information in the appropriate places, so I would not lose focus on the details.&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="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/chatgpt-1.png" alt="Using ChatGPT to organize information" loading="lazy" />&lt;/p>
&lt;p>Below, I used a checklist of the information I had already mapped to stay organized throughout the process:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/checklist.png" alt="Checklist of mapped information" loading="lazy" />&lt;/p>
&lt;p>To make the interview clearer, I decided to create a form for the owner to answer. &lt;strong>This corresponds to the &amp;ldquo;Define&amp;rdquo; stage mentioned and applied here.&lt;/strong>&lt;/p>
&lt;hr>
&lt;h3>3. Ideate&lt;span class="hx:absolute hx:-mt-20" id="3-ideate">&lt;/span>
&lt;a href="#3-ideate" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>The ChatGPT output above gives us the following:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/chatgpt-ideacao.png" alt="ChatGPT during ideation" loading="lazy" />&lt;/p>
&lt;p>I will reorganize some points I consider important based on the needs mapped with the &lt;strong>Value Proposition Canvas&lt;/strong>.&lt;/p>
&lt;p>Landing page solution brainstorm, edited:&lt;/p>
&lt;ul>
&lt;li>Organized sections: About us | Plans and advantages | Facilities | Booking and contact | FAQ.&lt;/li>
&lt;li>A direct WhatsApp button.&lt;/li>
&lt;li>High-quality photos of the space to build credibility.&lt;/li>
&lt;li>A call to action highlighting the business&amp;rsquo;s distinguishing feature: a free fitness assessment.&lt;/li>
&lt;li>A quick FAQ with questions raised by new users, collected through the form.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3>4. Prototype&lt;span class="hx:absolute hx:-mt-20" id="4-prototype">&lt;/span>
&lt;a href="#4-prototype" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/prototipagem-1.png" alt="Initial prototype" loading="lazy" />&lt;/p>
&lt;p>I am terrible at design 😭, &lt;strong>so I used Canva to bring this to life&lt;/strong> instead of letting that stop me.&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> a quick reminder of the live class discussion: &amp;ldquo;Great, let&amp;rsquo;s go and do it.&amp;rdquo;&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/prototipagem-2.png" alt="Live class about prototyping" loading="lazy" />&lt;/p>
&lt;p>I do not know design.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/prototipagem-3.png" alt="Prototyping attempt in Canva" loading="lazy" />&lt;/p>
&lt;hr>
&lt;h2>5. Test&lt;span class="hx:absolute hx:-mt-20" id="5-test">&lt;/span>
&lt;a href="#5-test" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Creating the prototype: as mentioned, this prototype was made in Canva to visualize the planning from the Value Proposition Canvas. Below is the screen sequence:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-1.png" alt="Prototype screen 1" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-2.png" alt="Prototype screen 2" loading="lazy" />&lt;/p>
&lt;p>Include the remaining service information once the form has been answered.&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-3.png" alt="Prototype screen 3" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-4.png" alt="Prototype screen 4" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-5.png" alt="Prototype screen 5" loading="lazy" />&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2025/abril/promover-a-inovacao-em-seu-ambiente-de-desenvolvimento-de-software/teste-prototipo-6.png" alt="Prototype screen 6" loading="lazy" />&lt;/p>
&lt;p>This initial prototype draft was developed to validate the owner&amp;rsquo;s needs for serving customers.&lt;/p>
&lt;p>Building the prototype helped identify relevant points and, above all, represented significant progress by turning ideas into a practical, visual version. The process was quick and functional, helping guide the next steps.&lt;/p>
&lt;p>The proposed continuation is to run more user tests and deploy the site in a real environment to assess whether the implemented features meet the previously mapped needs.&lt;/p>
&lt;p>&lt;strong>Canva prototype:&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>Form research for better analysis and understanding&lt;span class="hx:absolute hx:-mt-20" id="form-research-for-better-analysis-and-understanding">&lt;/span>
&lt;a href="#form-research-for-better-analysis-and-understanding" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;h2>2. Design thinking questionnaire&lt;span class="hx:absolute hx:-mt-20" id="2-design-thinking-questionnaire">&lt;/span>
&lt;a href="#2-design-thinking-questionnaire" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>For use in the &lt;strong>Empathize and Define&lt;/strong> stages with the client.&lt;/p>
&lt;h3>Questions about the business&lt;span class="hx:absolute hx:-mt-20" id="questions-about-the-business">&lt;/span>
&lt;a href="#questions-about-the-business" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>How would you describe your studio&amp;rsquo;s mission and values?&lt;/li>
&lt;li>What is the main difference between your studio and other gyms?&lt;/li>
&lt;li>Which services or advantages would you most like to highlight to new members?&lt;/li>
&lt;li>What feeling or impression would you like members to have when visiting the studio?&lt;/li>
&lt;/ol>
&lt;h3>Questions about customers&lt;span class="hx:absolute hx:-mt-20" id="questions-about-customers">&lt;/span>
&lt;a href="#questions-about-customers" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>Who are your main customers today? Consider age, profile, and goals.&lt;/li>
&lt;li>What do members praise most about your service?&lt;/li>
&lt;li>&lt;strong>What questions or concerns do prospective members most often express when contacting you?&lt;/strong>&lt;/li>
&lt;li>What positive or negative feedback have you received about the gym experience?&lt;/li>
&lt;/ol>
&lt;h3>Questions about communication&lt;span class="hx:absolute hx:-mt-20" id="questions-about-communication">&lt;/span>
&lt;a href="#questions-about-communication" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>Which channels do you currently use to promote the studio? Instagram, WhatsApp, referrals, or others?&lt;/li>
&lt;/ol>
&lt;h3>Questions about additional services&lt;span class="hx:absolute hx:-mt-20" id="questions-about-additional-services">&lt;/span>
&lt;a href="#questions-about-additional-services" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>How does the nutritionist partnership work? Consider prices, appointments, and distinguishing features.&lt;/li>
&lt;li>How does the supplement partnership work? Consider brands, discounts, and benefits.&lt;/li>
&lt;/ol>
&lt;h3>Questions about experience&lt;span class="hx:absolute hx:-mt-20" id="questions-about-experience">&lt;/span>
&lt;a href="#questions-about-experience" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>What benefits would you like to offer new members? Promotions, a trial class, or a first-month discount?&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2>Reference links&lt;span class="hx:absolute hx:-mt-20" id="reference-links">&lt;/span>
&lt;a href="#reference-links" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>&lt;strong>See the website prototype:&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>Website research for the fitness studio market — &lt;a href="https://ladydebug.com.br/en/docs/2025/abril/pesquisa-de-sites-mercado-foco-em-academias/">link&lt;/a>.&lt;/p>
&lt;p>&lt;strong>Study references:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Product quality, 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>Book: &lt;em>Don&amp;rsquo;t Make Me Think&lt;/em>, Steve Krug.&lt;/li>
&lt;li>Book: &lt;em>The Design of Everyday Things&lt;/em>, Donald A. Norman.&lt;/li>
&lt;li>Book: &lt;em>Value Proposition Design&lt;/em>, pages 142, 228, 232.&lt;/li>
&lt;li>Unisinos postgraduate course: Innovation and Entrepreneurship classes with &lt;a href="https://www.linkedin.com/in/rmaryf"target="_blank" rel="noopener">Professor Rosemary Francisco&lt;/a>.&lt;/li>
&lt;li>Tools: &lt;a href="https://www.canva.com/"target="_blank" rel="noopener">Canva&lt;/a> and Vercel App for site deployment.&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">How to identify and solve user pain points in UX design&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://psicologia.design/como-usar-storytelling-no-ux-design/"target="_blank" rel="noopener">How to use storytelling in UX design&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Website research for the fitness studio market</title><link>https://ladydebug.com.br/en/docs/2025/abril/pesquisa-de-sites-mercado-foco-em-academias/</link><pubDate>Thu, 17 Apr 2025 00:00:00 +0000</pubDate><guid>https://ladydebug.com.br/en/docs/2025/abril/pesquisa-de-sites-mercado-foco-em-academias/</guid><description>
&lt;h3>Studies and general analysis of gym websites&lt;span class="hx:absolute hx:-mt-20" id="studies-and-general-analysis-of-gym-websites">&lt;/span>
&lt;a href="#studies-and-general-analysis-of-gym-websites" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h3>&lt;p>This brief research was carried out for a website prototype in the fitness sector. Its goal was to promote a studio focused on personal goals, aimed at people who dislike crowded gyms and a lack of instructor attention, prioritizing a personal approach to service.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>1. Typical gym websites:&lt;/strong>&lt;/p>
&lt;p>Gym websites are generally built around three main pillars:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Presenting services:&lt;/strong> showing the types of training available, such as strength training, functional training, spinning, Pilates, and yoga.&lt;/li>
&lt;li>&lt;strong>Attracting new members:&lt;/strong> highlighting promotions, plans, trial classes, and quick contact forms.&lt;/li>
&lt;li>&lt;strong>Social proof:&lt;/strong> displaying real photos, member testimonials, and results.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. Common website structure:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>An eye-catching homepage:&lt;/strong> images of people training, motivational messages, and the gym&amp;rsquo;s distinguishing features, such as 24-hour opening, a free fitness assessment, and parking.&lt;/li>
&lt;li>&lt;strong>Plans and pricing:&lt;/strong> many people want to find the monthly price quickly. Some sites show it; others require users to fill out a form first, which can cause them to leave.&lt;/li>
&lt;li>&lt;strong>Group class schedule:&lt;/strong> some gyms publish their weekly schedule on the website.&lt;/li>
&lt;li>&lt;strong>Location:&lt;/strong> an embedded map, usually Google Maps, is almost essential because location is a deciding factor.&lt;/li>
&lt;li>&lt;strong>Member area:&lt;/strong> some newer sites offer member logins for tracking workouts, payments, and physical progress.&lt;/li>
&lt;li>&lt;strong>Blog or health tips:&lt;/strong> uncommon, but useful for SEO and attracting more visitors through Google.&lt;/li>
&lt;li>&lt;strong>Direct chat or WhatsApp:&lt;/strong> many sites have floating buttons for quick WhatsApp contact.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>3. How people search for gym websites:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Convenience:&lt;/strong> people want quick information. Slow sites or excessive forms lose users.&lt;/li>
&lt;li>&lt;strong>Comparison:&lt;/strong> users commonly open several nearby gym websites to compare prices, facilities, and distinguishing features.&lt;/li>
&lt;li>&lt;strong>Credibility:&lt;/strong> good photos, visible facilities, and real testimonials build trust.&lt;/li>
&lt;li>&lt;strong>Immediate benefits:&lt;/strong> free registration, a first-month discount, or a free trial class can be decisive.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>4. SEO and traffic:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Many searches use local keywords, such as &amp;ldquo;&lt;strong>gym in [city/neighborhood]&lt;/strong>&amp;rdquo; or &amp;ldquo;&lt;strong>gym near me&lt;/strong>&amp;rdquo;.&lt;/li>
&lt;li>Websites optimized for these searches are much more likely to be found organically, without paid advertising.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>5. Design and current trends:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>A clean, modern appearance without clutter.&lt;/li>
&lt;li>Short homepage videos showing the space.&lt;/li>
&lt;li>Integration with social media, especially Instagram.&lt;/li>
&lt;/ul></description></item><item><title>Cypress and automation best practices</title><link>https://ladydebug.com.br/en/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/</link><pubDate>Thu, 24 Oct 2024 13:07:00 -0300</pubDate><guid>https://ladydebug.com.br/en/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/</guid><description>
&lt;p>Avoiding &lt;em>false positives&lt;/em> with Cypress. Below is an example of some code and a commands file with a simple application login:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/exemplo-praticas-ruins.png" alt="Example of poor practices" loading="lazy" />&lt;/p>
&lt;p>This application was encountering an error during login. The following code was added to the automation to make login succeed:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/o_que_o_erro_faz.png" alt="What does this code do?" loading="lazy" />&lt;/p>
&lt;p>But what does that code mean? It suppresses errors that occur in the application while Cypress tests run.&lt;/p>
&lt;p>How? Using &lt;code>cy.on('uncaught:exception')&lt;/code> and returning false tells Cypress to ignore errors in your application. This allows the test to continue even if the page has not fully loaded, giving elements time to render before Cypress tries to interact with them.&lt;/p>
&lt;p>Why is removing &lt;code>cy.on('uncaught:exception')&lt;/code> important? In this case, manipulating the test to ignore the error by returning false introduces a false positive. See below:&lt;/p>
&lt;p>&lt;img src="https://ladydebug.com.br/docs/2024/outubro/cypress-e-boas-praticas-de-automacao/login_com_sucesso.png" alt="Login reported as successful" loading="lazy" />&lt;/p>
&lt;h2>Alternatives for handling loading time and avoiding false positives&lt;span class="hx:absolute hx:-mt-20" id="alternatives-for-handling-loading-time-and-avoiding-false-positives">&lt;/span>
&lt;a href="#alternatives-for-handling-loading-time-and-avoiding-false-positives" class="subheading-anchor" aria-label="Permalink for this section">&lt;/a>&lt;/h2>&lt;p>Instead of suppressing errors, use Cypress tools to ensure elements are present and ready for interaction before trying to access them. Some options include:&lt;/p>
&lt;p>&lt;code>cy.wait()&lt;/code>: wait for a specified time or for a particular element or condition before continuing the test.&lt;/p>
&lt;p>Note: watch out for poor practices when using &lt;code>cy.wait(number)&lt;/code>. Read the documentation on this 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&lt;/a>&lt;/p>
&lt;p>Instead, 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="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
>
&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> or&lt;/p>
&lt;p>&lt;code>cy.get(...).should('be.visible')&lt;/code>&lt;/p>
&lt;p>Make sure the element exists and is visible on the page before trying to interact with it.&lt;/p></description></item></channel></rss>