Skip to content

chore: aislop quality pass + hallmark a11y/responsive fixes - #19

Merged
Gaalbu merged 2 commits into
mainfrom
refactor/quality-design-pass
Aug 16, 2026
Merged

chore: aislop quality pass + hallmark a11y/responsive fixes#19
Gaalbu merged 2 commits into
mainfrom
refactor/quality-design-pass

Conversation

@Gaalbu

@Gaalbu Gaalbu commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Atenção antes de mergear

O bump do vite (5.4.21 → 8.2.1, junto com @vitejs/plugin-react 4 → 6) cruza a regra explícita do dependabot.yml que ignora major bumps para vite/@vitejs/plugin-react. Fiz o bump mesmo assim porque não existe patch dentro da linha 5.x para a vulnerabilidade high (GHSA-fx2h-pf6j-xcff, corrigida só a partir da 6.4.3) e o aislop marcou isso como error (bloqueante). Validei build/typecheck/lint com a versão nova, tudo passa. Se preferir manter 5.x e aceitar o risco (é vulnerabilidade só do dev server, não afeta o build de produção), reverta só o package.json/package-lock.json.

O que mudou

aislop (score 48 → 74):

  • security/vulnerable-dependency (error, high): vite ≤6.4.2 tinha bypass de server.fs.deny (GHSA-fx2h-pf6j-xcff). npm audit foi de 1 moderate + 1 high para 0 vulnerabilidades.
  • ResultModal.tsx/LegendModal.tsx: troquei <div role="dialog"> por <dialog> nativo (showModal()/close() via ref) — ganha focus trap real e Escape nativo. O backdrop foi movido para ::backdrop no CSS.
  • 5x react-hooks/exhaustive-deps em CanvasBasicoScreen/FactorScreen/SolveScreen/WorkspaceScreen: memoizei os helpers de atualização de tiles e handleRotateSelected com useCallback para o listener de teclado (R de rotacionar) sempre ver o estado atual. Em SolveScreen, updatePairTiles lia leftTiles/rightTiles direto do closure (não via updater funcional) — o lint pegou um stale-closure real, não só estilo.
  • HomeScreen.tsx: 4 blocos de card duplicados viraram um .map() sobre um array de dados.
  • utils/factorization.ts: detectFactorization (96 linhas) dividida em computeCoverage/findGaps/findFactors.

Ficaram documentados como falso positivo ou pendência de decisão (não silenciados):

  • LegendModal.tsx control-has-associated-label aponta pra um <td>, que não é um controle — falso positivo do scanner.
  • duplicate-block x5 em data/expressionTypes.ts — é uma tabela de dados estática (mesmo formato de registro por design), não lógica duplicada.
  • function-too-long x4 nos 4 componentes de tela principais (300-450 linhas, com drag-and-drop/atalhos de teclado/undo-redo). Uma decomposição real desses componentes exige QA manual que este projeto não tem como validar automaticamente (não há suíte de testes nem specs) — decidi não arriscar um refactor estrutural às cegas nas telas centrais do app.

hallmark audit (só correções pontuais, sem redesign):

  • src/index.css não tinha nenhuma regra :focus-visible — adicionada uma.
  • overflow-x: clip em :root/body como rede de segurança contra scroll horizontal mobile.
  • .header/.nav não tinham estratégia de quebra: título + 5 links de navegação + botões de idioma numa única linha flex sem wrap estourava em 320-375px. Adicionado flex-wrap.
  • Sem cabeçalhos em itálico, sem métricas inventadas, sem nenhuma animação no app (nada para condicionar a prefers-reduced-motion).

stop-slop: README.md auditado (não há pasta docs/), nenhum maneirismo de IA encontrado, nada alterado.

Test plan

  • npx tsc --noEmit limpo
  • npx eslint --ext .js,.jsx,.ts,.tsx src limpo (só 1 warning pré-existente não relacionado, react-refresh/only-export-components em appStore.tsx)
  • npx vite build ok
  • npm audit — 0 vulnerabilidades
  • Sem suíte de testes automatizados neste projeto (confirmado no package.json e no próprio README)

aislop (score 48 -> 74):
- security/vulnerable-dependency (error, high): vite <=6.4.2 had a high-severity
  server.fs.deny bypass (GHSA-fx2h-pf6j-xcff). No 5.x patch exists for it, so
  fixing it required crossing a major version (vite 5.4.21 -> 8.2.1,
  @vitejs/plugin-react 4 -> 6 for the peer dep). NOTE: dependabot.yml explicitly
  ignores semver-major updates for both packages -- this commit crosses that
  fence deliberately to close a real vulnerability; flagged here for review,
  revert this piece if you'd rather stay on vite 5.x and accept the dev-only risk.
  npm audit: 0 vulnerabilities after the bump (was 1 moderate + 1 high).
- ResultModal.tsx / LegendModal.tsx: replaced div role="dialog" with native
  <dialog> (showModal/close via ref), gaining real focus trapping + native
  Escape handling. CSS backdrop moved to ::backdrop.
- 5x react-hooks/exhaustive-deps across CanvasBasicoScreen/FactorScreen/
  SolveScreen/WorkspaceScreen: memoized the tile-update helpers and
  handleRotateSelected with useCallback so the keyboard-rotate effect always
  sees fresh state (SolveScreen's updatePairTiles read leftTiles/rightTiles
  directly, a real stale-closure risk the lint rule caught correctly).
- HomeScreen.tsx: 4 duplicated card blocks collapsed into a data-driven map.
- utils/factorization.ts: detectFactorization (96 lines) split into
  computeCoverage/findGaps/findFactors.

Left as documented false positives / deferred (fixable:false, judged, not
silenced):
- LegendModal.tsx control-has-associated-label on a <td> -- not a control,
  scanner false positive.
- code-quality/duplicate-block x5 on data/expressionTypes.ts -- it's a static
  curriculum data table (same record shape by design), not duplicated logic.
- complexity/function-too-long x4 on the CanvasBasicoScreen/FactorScreen/
  SolveScreen/WorkspaceScreen top-level components (300-450 lines each,
  drag/keyboard/undo-redo interactions). A real componentization split needs
  manual QA this project has no test suite to back up (no test script, no
  spec files) -- deferred rather than risking a blind structural refactor of
  the core interactive canvases.

hallmark audit (mechanical fixes only, no redesign):
- src/index.css had zero :focus-visible styling anywhere -- added one.
- added overflow-x: clip on :root/body (mobile scroll safety net).
- .header/.nav had no wrap strategy: 5 nav links + title + language buttons
  in one nowrap flex row would overflow at 320-375px. Added flex-wrap.
- no italic headers, no invented metrics, no motion at all in this app
  (nothing to gate behind prefers-reduced-motion).

stop-slop: audited README.md (no docs/ dir), no AI writing patterns found,
left untouched.
@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
algebra-tiles Ready Ready Preview Aug 16, 2026 3:32pm

…ync lockfile

The aislop pass in this branch already bumped vite to 8.2.1 to close a
high-severity vuln with no patch on the 5.x line; the dependabot ignore
rule for major bumps on vite/@vitejs/plugin-react predates that and now
just blocks catching up on the next one, so drop it.

Lockfile was regenerated against Node 20 (matches CI) -- the previous
lockfile was generated on Node 22 locally and drifted, which is what
made 'npm ci' fail in CI with a missing @types/react entry.
@Gaalbu
Gaalbu merged commit 2c2ba25 into main Aug 16, 2026
6 checks passed
@Gaalbu
Gaalbu deleted the refactor/quality-design-pass branch August 16, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant