diff --git a/CHANGELOG.md b/CHANGELOG.md index 22218b5..f6fd3bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,4 +29,3 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR - Caminho da page principal ([9f5b8a0](https://github.com/kellen-xavier/ladydebug.github.io/commit/9f5b8a0552465794c211bf5fea064f2015440d14)) - Janelas da doca coladas na navbar, botão fechar, e limpa rodapé duplicado ([38e09eb](https://github.com/kellen-xavier/ladydebug.github.io/commit/38e09eb067e06f43b0502571c1990cada91ab555)) - diff --git a/README.md b/README.md index ac73740..4acf62a 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,9 @@ Pra trocar o link do Spotify ou adicionar um evento, é só editar os `.yaml` acima — não precisa mexer nos templates. Ícones: [Pixelarticons](https://github.com/halfmage/pixelarticons) (MIT). + +Fonte: [Pixelify Sans](https://fonts.google.com/specimen/Pixelify+Sans) (OFL, +licença em `assets/font/pixelify-sans/OFL.txt`), self-hosted como WOFF2 — +usada só dentro da doca e das janelas, não no resto do site. Emitida via +`layouts/partials/custom/head-end.html` (não dá pra usar `url()` relativo +direto no `desktop-dock.css`, que é um CSS puro, sem processamento de Hugo). diff --git a/assets/css/custom.css b/assets/css/custom.css index ef327b4..1eee12f 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -10,7 +10,9 @@ --ld-fg: #2b2622; --ld-muted: #8a7f6d; --ld-border: #e6dcc6; - --ld-accent: hsl(var(--primary-hue) var(--primary-saturation) var(--primary-lightness)); + + /* Cor de destaque, usada em links, marcadores e nos "Destaques" da home. */ + --ld-accent: #d468a5; } .dark { @@ -49,6 +51,7 @@ body, /* Destaques (recolhível, sem JS) */ .ld-highlights { border: 1px solid var(--ld-border); + border-left: 3px solid var(--ld-accent); border-radius: 0.75rem; background: var(--ld-bg-soft); margin: 0 0 2.5rem; @@ -105,47 +108,11 @@ body, text-decoration: underline; } -/* Alternância Lista / Grade */ -.ld-controls { - display: flex; - justify-content: flex-end; - margin: 0 0 1.5rem; -} - -.ld-view-toggle { - display: inline-flex; - gap: 0.25rem; - padding: 0.25rem; - border: 1px solid var(--ld-border); - border-radius: 999px; - background: var(--ld-bg-soft); -} - -.ld-view-toggle__btn { - border: none; - background: transparent; - padding: 0.35rem 0.9rem; - border-radius: 999px; - font-size: 0.85rem; - cursor: pointer; - color: var(--ld-muted); - transition: - background-color 0.15s ease, - color 0.15s ease; -} - -.ld-view-toggle__btn[aria-pressed="true"] { - background: var(--ld-bg); - color: var(--ld-fg); - font-weight: 600; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); -} - -.ld-view-toggle__btn:hover { - color: var(--ld-fg); +/* Lista de posts agrupada por mês */ +.ld-post-list { + margin-top: 1rem; } -/* Lista de posts agrupada por mês */ .ld-group { margin-bottom: 2.5rem; } @@ -190,28 +157,6 @@ body, font-size: 0.8rem; } -/* Modo grade */ -.ld-post-list[data-view="grid"] .ld-group__items { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); - gap: 0.75rem; - list-style: none; - padding-left: 0; -} - -.ld-post-list[data-view="grid"] .ld-post { - border: 1px solid var(--ld-border); - border-radius: 0.6rem; - padding: 0.85rem 1rem; - background: var(--ld-bg-soft); - transition: transform 0.15s ease, box-shadow 0.15s ease; -} - -.ld-post-list[data-view="grid"] .ld-post:hover { - transform: translateY(-2px); - box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08); -} - /* Navegação "Nesta página" */ .ld-aside__inner { position: sticky; diff --git a/assets/css/desktop-dock.css b/assets/css/desktop-dock.css index c69e6d5..2af4483 100644 --- a/assets/css/desktop-dock.css +++ b/assets/css/desktop-dock.css @@ -7,12 +7,20 @@ --dock-height: 4rem; --bevel-light: rgba(255, 255, 255, 0.75); --bevel-dark: rgba(0, 0, 0, 0.35); + --dock-font: "Pixelify Sans", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; } body { padding-bottom: var(--dock-height); } +/* Fonte pixelada só nos blocos da doca (rodapé) e nas janelas + Música/Calendário/Rascunhos — não afeta o resto do site. */ +.dock, +.dock-window { + font-family: var(--dock-font); +} + .dock { position: fixed; left: 0; @@ -129,7 +137,6 @@ body { background: var(--ld-accent); color: var(--ld-bg); border-bottom: 2px solid var(--bevel-dark); - font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; diff --git a/assets/font/pixelify-sans/OFL.txt b/assets/font/pixelify-sans/OFL.txt new file mode 100644 index 0000000..e2a7e09 --- /dev/null +++ b/assets/font/pixelify-sans/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2021 The Pixelify Sans Project Authors (https://github.com/eifetx/Pixelify-Sans) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/assets/font/pixelify-sans/PixelifySans-Bold.woff2 b/assets/font/pixelify-sans/PixelifySans-Bold.woff2 new file mode 100644 index 0000000..c9c9a49 Binary files /dev/null and b/assets/font/pixelify-sans/PixelifySans-Bold.woff2 differ diff --git a/assets/font/pixelify-sans/PixelifySans-Regular.woff2 b/assets/font/pixelify-sans/PixelifySans-Regular.woff2 new file mode 100644 index 0000000..8c7528e Binary files /dev/null and b/assets/font/pixelify-sans/PixelifySans-Regular.woff2 differ diff --git a/assets/image/icons/cat-icon.jpg b/assets/image/icons/cat-icon.jpg new file mode 100644 index 0000000..4af16d0 Binary files /dev/null and b/assets/image/icons/cat-icon.jpg differ diff --git a/assets/image/icons/hello.jpg b/assets/image/icons/hello.jpg new file mode 100644 index 0000000..20a7461 Binary files /dev/null and b/assets/image/icons/hello.jpg differ diff --git a/assets/js/home.js b/assets/js/home.js deleted file mode 100644 index f2cc695..0000000 --- a/assets/js/home.js +++ /dev/null @@ -1,29 +0,0 @@ -(function () { - var STORAGE_KEY = "ladydebug:view"; - var list = document.getElementById("ld-post-list"); - var buttons = document.querySelectorAll("[data-view-btn]"); - if (!list || !buttons.length) return; - - function setView(view) { - list.setAttribute("data-view", view); - buttons.forEach(function (btn) { - var active = btn.getAttribute("data-view-btn") === view; - btn.setAttribute("aria-pressed", active ? "true" : "false"); - }); - try { - localStorage.setItem(STORAGE_KEY, view); - } catch (e) {} - } - - buttons.forEach(function (btn) { - btn.addEventListener("click", function () { - setView(btn.getAttribute("data-view-btn")); - }); - }); - - var saved; - try { - saved = localStorage.getItem(STORAGE_KEY); - } catch (e) {} - if (saved === "grid" || saved === "list") setView(saved); -})(); diff --git a/assets/image/2024/exemplo-praticas-ruins.png b/content/docs/2024/outubro/cypress-boas-praticas/exemplo-praticas-ruins.png similarity index 100% rename from assets/image/2024/exemplo-praticas-ruins.png rename to content/docs/2024/outubro/cypress-boas-praticas/exemplo-praticas-ruins.png diff --git a/content/docs/2024/outubro/cypress-boas-praticas.md b/content/docs/2024/outubro/cypress-boas-praticas/index.md similarity index 92% rename from content/docs/2024/outubro/cypress-boas-praticas.md rename to content/docs/2024/outubro/cypress-boas-praticas/index.md index 0120e19..488604d 100644 --- a/content/docs/2024/outubro/cypress-boas-praticas.md +++ b/content/docs/2024/outubro/cypress-boas-praticas/index.md @@ -9,11 +9,11 @@ featured: true Evitando o uso de *Falsos Positivos* com Cypress. Segue abaixo um exemplo de um código, e um arquivo commands com um simples login na aplicação: -![exemplo-praticas-ruins](/assets/image/2024/exemplo-praticas-ruins.png) +![exemplo-praticas-ruins](exemplo-praticas-ruins.png) Essa aplicação estava ocorrendo um certo erro ao realizar o login, e foi adicionado o seguinte trecho de código na automação para poder realizar o login com sucesso: -![o que o erro faz?](./assets/image/2024/o_que_o_erro_faz.png) +![o que o erro faz?](o_que_o_erro_faz.png) Mas o que esse trecho diz? Serve para suprimir os erros que ocorrem na aplicação durante a execução dos testes do Cypress. @@ -21,7 +21,7 @@ Como assim? Ao usar ```cy.on('uncaught:exception')``` e retornar false, está in Por que remover ```cy.on('uncaught:exception')``` é importante? Nesse caso, como está sendo manipulado o teste, forçando a “ignorar esse erro retornando que ele seja falso” é adicionado um falso positivo no nosso teste. Segue abaixo: -![alt text](./assets/image/2024/login_com_sucesso.png) +![alt text](login_com_sucesso.png) ## Alternativas e soluções para lidar com o tempo de carregamento e evitar adicionar “falso positivo” diff --git a/assets/image/2024/login_com_sucesso.png b/content/docs/2024/outubro/cypress-boas-praticas/login_com_sucesso.png similarity index 100% rename from assets/image/2024/login_com_sucesso.png rename to content/docs/2024/outubro/cypress-boas-praticas/login_com_sucesso.png diff --git a/assets/image/2024/o_que_o_erro_faz.png b/content/docs/2024/outubro/cypress-boas-praticas/o_que_o_erro_faz.png similarity index 100% rename from assets/image/2024/o_que_o_erro_faz.png rename to content/docs/2024/outubro/cypress-boas-praticas/o_que_o_erro_faz.png diff --git a/content/docs/2025/setembro/20/img/EXECTUADO_2025-09-20_09-32.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/executado-2025-09-20-09-32.png similarity index 100% rename from content/docs/2025/setembro/20/img/EXECTUADO_2025-09-20_09-32.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/executado-2025-09-20-09-32.png diff --git a/content/docs/2025/setembro/20/img/image1.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image1.png similarity index 100% rename from content/docs/2025/setembro/20/img/image1.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image1.png diff --git a/content/docs/2025/setembro/20/img/image2.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image2.png similarity index 100% rename from content/docs/2025/setembro/20/img/image2.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image2.png diff --git a/content/docs/2025/setembro/20/img/image3.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image3.png similarity index 100% rename from content/docs/2025/setembro/20/img/image3.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image3.png diff --git a/content/docs/2025/setembro/20/img/image.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image4.png similarity index 100% rename from content/docs/2025/setembro/20/img/image.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/image4.png diff --git a/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente.md b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/index.md similarity index 87% rename from content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente.md rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/index.md index 75484cd..8f878ea 100644 --- a/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente.md +++ b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/index.md @@ -16,7 +16,7 @@ Para um trabalho de Pós-graduação eu tinha configurado para um projeto de est `docker rm sonarqube` -![image1.png](content/docs/2025/setembro/20/img/image1.png) +![image1.png](image1.png) Agora posso executar o comando para subir um novo container: @@ -25,7 +25,7 @@ Agora posso executar o comando para subir um novo container: > Sim, a versão é gratuíta, para aprendizado antes de sair pagando algo que não sabe usar. > -![image2.png](content/docs/2025/setembro/20/img/image2.png) +![image2.png](image2.png) ### **Opção 2: Substituir o container automaticamente** @@ -60,11 +60,11 @@ Aqui a primeira parte de ajustar o docker então precisa se atentar a deixar ele Pronto! SonarQube rodando localmente. -![image3.png](content/docs/2025/setembro/20/img/image3.png) +![image3.png](image3.png) Ajuste as configurações de senha e segue para a página: -![image.png](Configurando%20o%20SonarQube%20Localmente/image%203.png) +![image4.png](image4.png) ### **Configuração do SonarQube** @@ -110,7 +110,7 @@ sonar.login=SEU_TOKEN_AQUI ## **Problemas encontrados** -![problema encontrado ao rodar o escaneamento 2025-09-20_09-24.png](Configurando%20o%20SonarQube%20Localmente/problema_encontrado_ao_rodar_o_escaneamento_2025-09-20_09-24.png) +![problema encontrado ao rodar o escaneamento](problema-encontrado-ao-rodar-o-escaneamento-2025-09-20-09-24.png) ERROR: You're not authorized to run analysis. Please contact the project administrator. @@ -122,6 +122,6 @@ O SonarScanner está tentando enviar os resultados da análise para o SonarQube, Agora pronto: quando executar o comando `sonar-scanner` vai executar o escaneamento no projeto e seguida mostrar em tela os resultados. -![TERMINAL_SUCESS_2025-09-20_09-33.png](content/docs/2025/setembro/20/img/TERMINAL_SUCESS_2025-09-20_09-33.png) +![terminal com sucesso](terminal-sucesso-2025-09-20-09-33.png) -![EXECTUADO 2025-09-20_09-32.png](content/docs/2025/setembro/20/img/EXECTUADO_2025-09-20_09-32.png) +![executado](executado-2025-09-20-09-32.png) diff --git a/content/docs/2025/setembro/20/img/problema_encontrado_ao_rodar_o_escaneamento_2025-09-20_09-24.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/problema-encontrado-ao-rodar-o-escaneamento-2025-09-20-09-24.png similarity index 100% rename from content/docs/2025/setembro/20/img/problema_encontrado_ao_rodar_o_escaneamento_2025-09-20_09-24.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/problema-encontrado-ao-rodar-o-escaneamento-2025-09-20-09-24.png diff --git a/content/docs/2025/setembro/20/img/TERMINAL_SUCESS_2025-09-20_09-33.png b/content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/terminal-sucesso-2025-09-20-09-33.png similarity index 100% rename from content/docs/2025/setembro/20/img/TERMINAL_SUCESS_2025-09-20_09-33.png rename to content/docs/2025/setembro/20/configurando-o-sonar-qube-localmente/terminal-sucesso-2025-09-20-09-33.png diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-1.png b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-1.png new file mode 100644 index 0000000..324cd54 Binary files /dev/null and b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-1.png differ diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-2.png b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-2.png new file mode 100644 index 0000000..78f5e15 Binary files /dev/null and b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-2.png differ diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-3.png b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-3.png new file mode 100644 index 0000000..7d7ada2 Binary files /dev/null and b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-3.png differ diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-4.png b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-4.png new file mode 100644 index 0000000..7418b3d Binary files /dev/null and b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-4.png differ diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-5.png b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-5.png new file mode 100644 index 0000000..f85e817 Binary files /dev/null and b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image-5.png differ diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image.png b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image.png new file mode 100644 index 0000000..0ae5136 Binary files /dev/null and b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/image.png differ diff --git a/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/index.md b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/index.md new file mode 100644 index 0000000..157dfde --- /dev/null +++ b/content/docs/2026/julho/bot-planner-projeto-para-acompanhamento-do-desenvolvimento/index.md @@ -0,0 +1,276 @@ +--- +title: "Bot Planner - Projeto para acompanhamento do desenvolvimento pessoal" +date: 2026-07-06 +slug: bot-planner-projeto-para-acompanhamento-do-desenvolvimento-pessoal +--- + +Recentemente estive a desenvolver alguns projetos de estudos com IA, e estava precisando me organizar, de, quanto tempo estive a desenvolver — tempo corrido — + +também ao esta desenvolvendo algo geralmente eu costumo ler a documentação da lingagem para leitura de algumas práticas, links de documentos, docs que eu estou escrevendo para determinada característica do projeto. Criar tarefas que me lembrei no ato que estava a desenvolver, e verifiquei que pode ser terminada logo após a tarefa que estou a fazer. Além de comentários do que foi realizado, esse acompanhamento de forma geral. + +Com base nesse problema, pensei em algo prático que eu possa fazer enquanto estou desenvolvendo. Ou seja comando `/inicio` quando inicio a atividade, `/link` para adicionar documentações entre outros importantes. `/nota` quando eu quiser adicionar notas comentários, `task` para quando quiser criar uma tarefas, `fim` quando finalizar tudo. Após isso gere um `Release notes` com o que foi feito e quais as tarefas ficaram pendentes. + +Então lendo uma [postagem em um blog](https://akitaonrails.com/2026/02/16/vibe-code-do-zero-a-producao-em-6-dias-the-m-akita-chronicles/#spoiler-do-processo) e pensei em criar o bot com gestão pessoal para auxiliar no ciclo de desenvolvimento pessoal sem fricção e que gere um report notes no fim do trabalho. + +Podendo também aplicar para compartilhar caso queira com alguém do time (desenvolvimento orientado com metodologia XP). + +--- + +Criei o repositório no github ~~inicialmente privado mas irei liberar em seguida~~, open-source — estou a corrigir algumas questões de segurança — e primeiro criar o bot, inicialmente interação é via Discord, mas vai abranger multicanal de comunicação (pensei em slack e dicord principal) as demais particularmente não me interessei muito. + +## Primeira Fase do desenvolvimento + +![image.png](image.png) + +![image.png](image-1.png) + +Nos testes iniciais, ficou bem poluído os comandos no chat unificado, então pensei em criar um segundo “canal de texto”, para que o release-notes separado para acompanhar no dia seguinte, tendo essa visão limpa entre “comandos” e “release notes”. + +![image.png](image-2.png) + +--- + +### **Organização do Bot** + +Para configurar o bot é simples, deve-se seguir a documentação oficial neste link: [**Building your first Discord Bot**](https://docs.discord.com/developers/quick-start/getting-started) + +![image.png](image-3.png) + +**Para estes estudo de caso | Como configurar o Bot:** + +1. Vá no Developer Portal do Discord. +2. Abrir o app ladydebug-bot-planner. +3. Vá em Bot. +4. Clique em Reset Token. +5. Copie o token novo. +6. Atualize DISCORD_TOKEN no .env. +7. Rode de novo: + + ```bash + set -a; source .env; set +a + python -m daily.main + ``` + +8. Configuração Mínima Local + +Seu .env local deve ter pelo menos: + +`DISCORD_TOKEN=token_do_bot +DISCORD_GUILD_ID=807481361916100628 +DB_PATH=daily.db` + +--- + +### Plano de Testes Bot Planner + +Visão geral + +**Checklist**: + +#### Todos + +[•] Mapear módulos e funcionalidades existentes em src/daily +[ ] Mapear testes existentes por funcionalidade +[ ] Executar testes/cobertura disponível +[ ] Consolidar lacunas de cobertura e recomendações + +### Funcionalidades Com Testes + +Criei o report em docs/TEST_COVERAGE_REPORT.md aqui ele documenta o seguinte: + +- Estado atual da suíte: 79 passed. +- Diretrizes para evitar testes enviesados/falso positivo. +- Lacunas restantes por prioridade. +- Cenários exatos que precisam ser implementados. +- Critérios de aceite para novas rodadas. +- Recomendação para adicionar pytest-cov. +- Ordem sugerida de execução. + +**Principais áreas priorizadas no report:** + +1. CommandRouter +2. SqliteStorage +3. SimpleFetcher +4. VCS adapters +5. Report de fim de dia +6. Discord adapter callbacks +7. Models/DTOs +8. Métrica objetiva com coverage + +--- + +**Erros encontrado:** + +```jsx +python -m daily.main +2026-07-09 09:32:45 INFO discord.client logging in using static token +2026-07-09 09:32:47 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: b25a5b78274ede64c286f2fc11e8c2e3). +Bot online como ladydebug-bot-planner#3088 +2026-07-09 09:51:05 ERROR discord.app_commands.tree Ignoring exception in command 'inicio' +Traceback (most recent call last): + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/commands.py", line 859, in _do_call + return await self._callback(interaction, **params) # type: ignore + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/src/daily/adapters/discord_bot.py", line 90, in inicio + msg = router.inicio(str(interaction.user.id), str(interaction.channel_id)) + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/src/daily/command_router.py", line 32, in inicio + s = self._day.start_day(user_id, channel_id) + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/src/daily/core/day_service.py", line 32, in start_day + raise DayAlreadyOpen("Já existe um dia aberto para este usuário.") +daily.core.day_service.DayAlreadyOpen: Já existe um dia aberto para este usuário. + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/tree.py", line 1302, in _call + await command._invoke_with_namespace(interaction, namespace) + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/commands.py", line 884, in _invoke_with_namespace + return await self._do_call(interaction, transformed_values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/home/kellen/Documents/Projetos github/ladydebug-bot-planner/.venv/lib/python3.14/site-packages/discord/app_commands/commands.py", line 877, in _do_call + raise CommandInvokeError(self, e) from e +discord.app_commands.errors.CommandInvokeError: Command 'inicio' raised an exception: DayAlreadyOpen: Já existe um dia aberto para este usuário. +``` + +**Motivo**: + +DayAlreadyOpen: Já existe um dia aberto para este usuário. +Isso acontece porque você executou /inicio, o bot abriu uma sessão no daily.db, e depois você chamou /inicio de novo sem antes fechar com /fim. + +**Explicação**: + +Causa Técnica +O core está correto em impedir dois dias abertos: +if self._storage.get_open_session(user_id) is not None: +raise DayAlreadyOpen("Já existe um dia aberto para este usuário.") +O problema é que essa exceção está vazando até o Discord, gerando stack trace. O bot deveria responder algo amigável, como: +Já existe um dia aberto para você. Use /fim para fechar antes de iniciar outro. + +**Correções:** + +Plano De Ajustes +Ainda em modo planejamento, então não vou editar arquivos agora. O ajuste recomendado é: + +1. Tratar DayAlreadyOpen no CommandRouter.inicio. +2. Tratar NoOpenDay em /nota, /link e /fim. +3. Evitar que exceções esperadas do core virem erro no Discord. +4. Melhorar diagnóstico de ambiente Discord com DISCORD_CLIENT_ID. +5. Documentar configuração local e produção no README. +6. Adicionar testes para esses casos. + +## Comportamento Esperado Após Ajustes + +Validar `/inicio` com dia já aberto mas sem terminar atividades: +Deve retornar: +Mensagem: +🟡 Já existe um dia aberto para você. Use `/continuar` para seguir o seu dia. +Comportamento: ao enviar comando `/continue` deve seguir inserindo as atividades, do dia. Ou seja; + +**Cenário**: +Dado que usuário envia o comando /iniciar no dia 1 +E no dia 1 usuário envia o comando /iniciar +Quando retornar a mensagem: 🟡 Já existe um dia aberto para você. Use `/continuar` para seguir o seu dia. +Então usuário deve inserir comando /continuar +E deve seguir até finalizar o dia + +Validar `/nota` sem dia aberto: +Deve retornar: +Mensagem: ⚠️ Nenhum dia aberto. Use /inicio primeiro. + +Validar `/fim` sem dia aberto: +Deve retornar: +Mensagem: ⚠️ Nenhum dia aberto para fechar. Use /inicio para começar. + +Validar `/link` sem dia aberto: +Deve retornar: +Mensagem: +⚠️ Nenhum dia aberto. Use /inicio primeiro. + +1. Arquivos Que Devem Mudar + +- src/daily/command_router.py +- src/daily/adapters/discord_bot.py +- src/daily/main.py +- .env.example +- [README.md](http://readme.md/) +- tests/test_ingest_and_report.py +- tests/test_discord_bot.py +- tests/test_main_config.py + +**O Que Mudou:** + +- src/daily/command_router.py +- /inicio com dia já aberto agora retorna: + 🟡 Já existe um dia aberto para você. Use /continuar para seguir o seu dia. +- Novo método continuar. +- /nota, /link e /fim agora tratam NoOpenDay com mensagens amigáveis. +- /link agora verifica dia aberto antes de buscar/resumir URL. +- src/daily/adapters/discord_bot.py +- Adicionado comando Discord /continuar. +- Melhorado diagnóstico quando o bot não vê o servidor. +- Se DISCORD_CLIENT_ID estiver configurado, o erro imprime URL de convite correta. +- src/daily/main.py +- Adicionada validação de ambiente: + DISCORD_TOKEN obrigatório. + DISCORD_GUILD_ID numérico se informado. + DISCORD_CLIENT_ID numérico se informado. +- .env.example +- Adicionado DISCORD_CLIENT_ID. +- [README.md](http://readme.md/) +- Documentado /continuar. +- Documentado ambiente local e produção. +- Adicionado troubleshooting do Discord. +- Testes adicionados para: +- /inicio com dia aberto. +- /continuar com e sem dia aberto. +- /nota, /link, /fim sem dia aberto. +- validação de DISCORD_CLIENT_ID e DISCORD_GUILD_ID. +- URL de convite no diagnóstico. + +--- + +### Visão Geral de Testes com Discord + +![image.png](image-4.png) + +--- + +### **Updates e Melhorias** + +Foi colocado um segundo canal de texto onde que, com o comando `/fim` finaliza o report e adiciona no canal que fez a chamada, o release-notes do dia. + +Agora foi visto que precisa ser finalizada as atividades criadas no dia. Para isso segue a nova funcionalidade. + +**Funcionalidade**: Dado que o usuário conclua e foi finalizada a “Tarefa” criada, Então deve adicionar o comando `/fim-task` com a seguinte ação: + +**Comportamento esperado:** + +URL: para adicionar o link de uma atividade concluida +Titulo Tarefa: Nome da Minha task aqui +Tempo da atividade aberta: xx minutos / xx horas / xx dias + +Dado que a atividade contém comentário, +Quando concluir ação +Então release notes deve mostrar comentários adicionada a ação + +![image.png](image-5.png) + +--- + +### Fluxo De Produção + +1. Criar canal #release-notes. +2. Copiar o ID do canal. +3. Criar app/bot no Discord. +4. Convidar o bot com bot applications.commands. +5. Criar projeto Railway conectado ao GitHub. +6. Configurar secrets no Railway. +7. Configurar volume persistente. +8. Start command: python -m daily.main. +9. Fazer deploy. +10. Testar no Discord: + +- /inicio +- /nota +- /pr url:[https://github.com/.../pull/](https://github.com/.../pull/)... +- /fim diff --git a/data/dock.yaml b/data/dock.yaml index f01f6b7..cafe9f9 100644 --- a/data/dock.yaml +++ b/data/dock.yaml @@ -8,7 +8,7 @@ icon: music panel: spotify # Troque pelo link de um perfil, playlist ou álbum seu no Spotify. - spotify_url: "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M" + spotify_url: "https://open.spotify.com/playlist/1hzBaroEetOyVIbalKSDwg?si=17083f6a7ca94c55" - id: calendar label: "Calendário" diff --git a/go.mod b/go.mod index 6d21629..b2803c4 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/imfing/hextra-starter-template go 1.21 -require github.com/imfing/hextra v0.11.1 // indirect +require github.com/imfing/hextra v0.12.3 // indirect diff --git a/go.sum b/go.sum index efb638f..afa8680 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI= -github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI= +github.com/imfing/hextra v0.12.3 h1:DZHY2rUWYteyzjlHi9r4n7Bb5e2Q+6LXe4C1Dqn0ZjM= +github.com/imfing/hextra v0.12.3/go.mod h1:vi+yhpq8YPp/aghvJlNKVnJKcPJ/VyAEcfC1BSV9ARo= diff --git a/layouts/home.html b/layouts/home.html index 2af02cc..369cda7 100644 --- a/layouts/home.html +++ b/layouts/home.html @@ -32,14 +32,7 @@ {{ end }} -
-
- - -
-
- -
+
{{ range $groups }} {{ $first := index .Pages 0 }} {{ $gid := printf "%d-%02d" $first.Date.Year (int $first.Date.Month) }} @@ -80,8 +73,4 @@

{{ $label }}

- - {{ with resources.Get "js/home.js" }} - - {{ end }} {{ end }} diff --git a/layouts/partials/custom/head-end.html b/layouts/partials/custom/head-end.html index 37c71b4..5dcdf38 100644 --- a/layouts/partials/custom/head-end.html +++ b/layouts/partials/custom/head-end.html @@ -1,3 +1,30 @@ +{{/* Fonte "Pixelify Sans" (self-hosted, ver assets/font/pixelify-sans/) usada + só na doca (rodapé) e nas janelas Música/Calendário/Rascunhos. */}} +{{ $regular := resources.Get "font/pixelify-sans/PixelifySans-Regular.woff2" }} +{{ $bold := resources.Get "font/pixelify-sans/PixelifySans-Bold.woff2" }} +{{ with $regular }} + {{ $regular = . | fingerprint }} + {{ $bold = $bold | fingerprint }} + + + +{{ end }} + {{ with resources.Get "css/desktop-dock.css" }} {{ $css := . | minify | fingerprint }}