Files

12 KiB

Learnings — Padrões bem-sucedidos

Registro de padrões que funcionam, para replicar.


[LRN-20260520-003] gitea-api-autenticacao-completa

Logged: 2026-05-20T12:31:00-03:00 Priority: high Status: reference Area: devops | api

Summary

Gitea API suporta 5 métodos de autenticação — todos usam o mesmo API token

Details

Fontes estudadas: https://docs.gitea.com/development/api-usage

Métodos de autenticação (ordem de preferência):

  1. Authorization: token <hash> — mais comum, não usa username na URL
  2. token=<hash> query string — simples para curl/GETs
  3. access_token=<hash> query string — compat OAuth2 consumers
  4. HTTP Basic (username:password) — cria token, admin
  5. HTTP Basic + OTP — quando 2FA habilitado (X-Gitea-OTP: 123456)
  6. SSH HTTP Signature — chaves SSH registradas, draft-cavage-http-signatures

Token nunca é reexibido — apare | |:"name":"meu-token","sha1":"9fcb11..." — só sha1 na listagem /**/ Scopes: formato <read|write>:<permission>, ou all para tudo. Permissions: activitypub, admin, issue, misc, notification, organization, package, repository, user

Pagination: ?page=N&limit=N, header Link (rel=next/last), x-total-count

Sudo (admin): adicionar Sudo: username header ou param sudo=username

Suggested Action

Usar sempre scopes:["all"] para automação, guardar token em segredo, preferir header Authorization: token sobre query string.

Metadata

  • Source: documentation
  • Tags: gitea, api, auth, token, swagger, devops
  • Pattern-Key: gitea-api.authentication
  • Recurrence-Count: 1

[LRN-20260520-004] gitea-api-endpoints-reference

Logged: 2026-05-20T12:31:00-03:00 Priority: medium Status: reference Area: devops | api

Summary

Mapa dos endpoints Gitea API v1 por domínio

Details

  • Usuário: GET /api/v1/user, GET /api/v1/users/:username
  • Repos: GET/POST /api/v1/user/repos, GET /api/v1/repos/:owner/:repo
  • Issues: GET/POST /api/v1/repos/:owner/:repo/issues
  • Pulls: GET/POST /api/v1/repos/:owner/:repo/pulls
  • Webhooks: GET/POST /api/v1/repos/:owner/:repo/hooks
  • Admin users: GET/POST/PUT/DELETE /api/v1/admin/users
  • Swagger: https://host/api/swagger
  • OpenAPI JSON: https://host/swagger.v1.json

Suggested Action

Consultar SKILL.md skills/gitea-api/SKILL.md antes de usar a API.

Metadata

  • Source: documentation
  • Tags: gitea, api, endpoints, rest
  • Pattern-Key: gitea-api.endpoints
  • Recurrence-Count: 1

[LRN-20260519-001] clawhub.cli_path

Logged: 2026-05-19T20:39:00-03:00 Priority: high Status: pending Area: config

Summary

Instalar skills do Clawhub com /var/lib/openclaw/tools/node/npm/bin/clawhub

Details

O CLI clawhub não está no $PATH global, mas existe instalado em /var/lib/openclaw/tools/node/npm/bin/clawhub. Sempre usar o caminho completo.

Suggested Action

Adicionar symlink ou alias para clawhub no PATH do agente, ou sempre usar o caminho completo.

Metadata

  • Source: error
  • Tags: clawhub, cli, path, install
  • Pattern-Key: clawhub.cli_path

[LRN-20260519-002] clawhub-search-qc

Logged: 2026-05-19T20:42:00-03:00 Priority: medium Status: pending Area: config

Summary

clawhub search com termos muito específicos retorna vazio; usar termos genéricos primeiro

Details

Pesquisas com termos combinados como "programming developer full-stack" retornaram vazio. Termos simples como "autonomous agent" retornaram resultados. Melhor abordar a pesquisa em múltiplas queries curtas.

Suggested Action

Fazer múltiplas searches com termos curtos e depois filtrar manualmente.

Metadata

  • Source: error
  • Tags: clawhub, search, query
  • Pattern-Key: clawhub.search_strategy

[LRN-20260519-003] biblioteca-compartilhada-libs

Logged: 2026-05-19T21:30:00-03:00 Priority: medium Status: pending Area: config

Summary

Criar biblioteca inteligente compartilhada em libs/ para reuso entre projetos

Details

Toda skill instalada tem conhecimento valioso. Centralizar em libs/<dominio>/:

  • skills são extraídas e promovidas para arquivos .md limpos
  • novos projetos copiam libs/ como template
  • o agente consulta libs/ antes de implementar

Metadata

  • Source: best_practice
  • Tags: biblioteca, reuso, padroes
  • Pattern-Key: libs.shared_knowledge_base

[LRN-20260519-004] vitest-jsdom-global-mocks

Logged: 2026-05-19T23:10:00-03:00 Priority: high Status: applied Area: testing

Summary

Vitest jsdom — mocks globais obrigatórios antes de renderizar hooks que usam APIs do navegador

Details

localStorage, navigator.clipboard, window.matchMedia não existem no jsdom puro — mockar em beforeAll/beforeEach global.

Metadata

  • Source: best_practice
  • Tags: vitest, jsdom, mocks, testing
  • Pattern-Key: vitest.jsdom.mocks
  • Recurrence-Count: 3 → promoted

[LRN-20260519-005] react-testing-library-hooks-async

Logged: 2026-05-19T23:10:00-03:00 Priority: medium Status: pending Area: testing

Summary

React Testing Library — renderHook + act() para testar hooks assíncronos

Details

Sempre envolver awaits em act(async () => { ... }), nunca acessar result.current após await diretamente fora de act().

Metadata

  • Source: best_practice
  • Tags: react, testing-library, hooks, async, vitest
  • Pattern-Key: react.testing-library
  • Recurrence-Count: 3 → promoted

[LRN-20260520-001] vitest-pure-dom-matchers

Logged: 2026-05-20T00:52:00-03:00 Priority: high Status: applied Area: testing

Summary

Vitest jsdom puro — matchers nativos DOM funcionam sem @testing-library/jest-dom

Details

Usar .classList.contains(), .getAttribute(), .textContent, container.querySelector() ao invés de matchers RTL. 56/56 testes verdes, 0 dependências extras.

Metadata

  • Source: best_practice
  • Tags: vitest, jsdom, testing, matchers
  • Pattern-Key: vitest.pure-dom-matchers
  • Recurrence-Count: 1

[LRN-20260520-002] jsdom-fireEvent-writable-value

Logged: 2026-05-20T00:52:00-03:00 Priority: low Status: workaround Area: testing

Summary

No jsdom, Object.defineProperty(input, 'value', { writable: true }) permite fireEvent.change

Details

Workaround mínimo para testar onChange em inputs no jsdom puro, onde .value é readonly.

Metadata

  • Source: error
  • Tags: jsdom, fireEvent, input, value
  • Pattern-Key: jsdom.fireEvent-change-writable
  • Recurrence-Count: 1

[LRN-20260520-006] portainer-api-ptr-token-scope

Logged: 2026-05-20T17:38:00-03:00 Priority: high Status: reference Area: devops | infra | docker

Summary

Token Portainer com prefixo ptr_ é um access token — funciona em /api/status (200) mas retorna 401 em /api/endpoints, /api/stacks, /api/auth — escopo muito limitado.

Details

Para operações de mutação (criar/gerenciar stacks) pela API Portainer é necessário JWT admin válido obtido via POST /api/auth com username+senha. Senha admin do Portainer não estava documentada — usamos docker stack deploy via CLI Docker Swarm diretamente como workaround.

Suggested Action

Documentar senha admin do Portainer de forma segura (password manager), ou usar service token JWT com escopo admin completo.

Metadata

  • Source: error
  • Tags: portainer, api, token, docker-swarm, jwt
  • Pattern-Key: portainer.api-ptr-token-scope

[LRN-20260520-007] docker-compose-v3-swarm-labels-and-restart-policy

Logged: 2026-05-20T17:38:00-03:00 Priority: high Status: reference Area: devops | docker

Summary

docker stack deploy com compose v3.9 no Swarm mode — duas propriedades que não funcionam como esperado:

  1. restart_policy — não é propriedade válida no deploy spec; Docker Swarm gerencia restart nativamente (Always)
  2. deploy.labels — não se tornam container labels; labels só são aplicadas via docker service create --label-add ou --label-add em docker service update

Fix

  • Remover restart_policy do YAML
  • Aplicar labels necessárias (ex: caddy=) via CLI docker service update --label-add ou diretamente no docker service create

Metadata

  • Source: error
  • Tags: docker, swarm, compose, labels, restart-policy
  • Pattern-Key: docker.swarm-compose-v3-gotchas

[LRN-20260520-008] stack-migration-docker-swarm-createmigrate

Logged: 2026-05-20T17:38:00-03:00 Priority: medium Status: reference Area: devops | docker

Summary

Migração de stack Docker Swarm (trocar de nome/namespace):

  1. Criar novos serviços com o nome da stack destino + labels corretas (docker service create --label-add ...)
  2. Validar que os serviços estão saudáveis
  3. Remover a stack antiga (docker stack rm <antiga>)

Safety notes

  • Não usar docker stack deploy --prune em stack ativa em produção — apaga services não presentes no novo compose
  • Para imagens locais: usar --with-registry-auth ou tag com registry acessível
  • Sempre validar docker service ps <nome> antes de remover a stack antiga

Metadata

  • Source: best_practice
  • Tags: docker, swarm, migration, stack
  • Pattern-Key: docker.swarm-stack-migration

LRN-20260520-010 — Stack Portainer API Attachable=false bloqueia deploy

Categoria: knowledge_gap

Problema

  • Rede public tem Attachable: false
  • docker stack deploy CLI FUNCIONA mesmo assim (Daemon local ignora)
  • Portainer API BLOQUEIA (Docker Remote API respeita Attachable=false)
  • Erro: failed to set up container networking: Could not attach to network public: rpc error: code = PermissionDenied desc = network public not manually attachable

Decisão tomada

Stack project fica gerenciada por docker stack deploy CLI (Swarm nativo). Portainer controla apenas stacks 1,2,4,6,7,8,9 (com SwarmId preenchido). Stack project não é controlável pelo Portainer enquanto Attachable=false.

Para resolver completamente

Recriar rede public com --attachable impactando 19 containers — NÃO recomendado agora.

[LRN-20260520-011] atomic-design-3d-threejs-landing-page

Logged: 2026-05-20T20:00:00-03:00 Priority: high Status: reference Area: frontend | web3d | design-system

Summary

Landing page 3D completa usando Atomic Design + Three.js + React Three Fiber + Framer Motion — código funcional com build OK.

Padrão aplicado

Átomos (11) → Moléculas (3) → Organismos (2) → Templates (2) → Pages (1)

Tokens 8 domínios: space / font / color / shadow / radius / material3d / camera3d / animation

Stack

  • Vite + React 18 + TS
  • @react-three/fiber + drei
  • framer-motion
  • Build: npm install && npm run build

Decisões

  • Canvas fullscreen com overlay 2D (SceneCanvas + ThreePage template)
  • ScrollControls → scroll move câmera 3D
  • Material tokens: roughness 0.08 + metalness 0.75 = super-reflexivo
  • PointLights accent + secondary por cena
  • CSS vars para dark/light mode + A11y

Hot Reload (future)

  • npm run dev → Vite HMR
  • Adicionar ao stack Swarm dev (volume bind mount + dnsrr)

[LRN-20260520-012] proxy-test-octal-deploy-zero-downtime

Logged: 2026-05-20T20:15:00-03:00 Priority: high Status: reference Area: devops | docker | caddy

Problema

test.octal.tec.br estava com HTML estático antigo (Octal Technology landing page). Precisou atualizar para o Pulse 3D.

Solução aplicada

  1. Extrair HTML atual da imagem test-octal:latest via docker cp
  2. Substituir pelo HTML novo (Pulse 3D — CSS completo)
  3. Build: docker build -t test-octal:latest . no diretório com HTML + Dockerfile
  4. Deploy: docker service update --image test-octal:latest proxy_test-octal
  5. Resultado: zero-downtime, serviço convergiu com imagem nova

Padrão

# Extrair atual
mkdir /tmp/site-src && docker cp container:/usr/share/nginx/html . /tmp/site-src/
# Atualizar index.html
cp novo.html /tmp/site-src/index.html
# Reconstruir
cd /tmp/site-src && cat > Dockerfile << 'D'
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
D
docker build -t test-octal:latest . && docker push registry.octal.tec.br/pulse/test-octal:latest
# Atualizar service
docker service update --image test-octal:latest proxy_test-octal

Resultado

  • https://test.octal.tec.br agora mostra Pulse 3D Landing
  • Registry push pode falhar com SSL (registry local com cert autoassinado) — usar imagem local diretamente no docker service update funciona