Skip to content

refactor(repositories): honest reads in the eight files the ruler could not see (#1087 passo 4) - #1092

Merged
rpgmem merged 3 commits into
developfrom
claude/row-shapes-repositories-4vvuer
Sep 7, 2026
Merged

refactor(repositories): honest reads in the eight files the ruler could not see (#1087 passo 4)#1092
rpgmem merged 3 commits into
developfrom
claude/row-shapes-repositories-4vvuer

Conversation

@rpgmem

@rpgmem rpgmem commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Passo 4 da #1087: os 30 erros que a régua corrigida (#1090) passou a acusar, e a folga do gate de volta a 0.

Nenhum dos 30 era novo. A varredura exigia a substring literal $wpdb-> e nunca olhou os repositórios que ligam wpdb como propriedade — oito arquivos, o AbstractRepository entre eles.

O que os 30 eram de verdade

Lendo-os, não eram majoritariamente "shape de coluna faltando". Eram quatro origens, e a dominante não tem nada a ver com o $wpdb:

Origem Sites O que é
Cache de objetos 6 métodos, 5 arquivos wp_cache_get() devolve mixed, então um cache hit jogava o tipo fora enquanto a leitura do banco logo abaixo estava tipada
Projeções agregadas 3 SELECT user_id, COUNT(*) não é linha; e COUNT()/SUM() voltam como string numérica, ou NULL em tabela vazia
json_decode sobre coluna 3 colunas JSON escritas pelo próprio plugin, lidas de um array<string, mixed>
Projeção de 5 colunas 6 o SELECT id, user_id, email_hash, cpf_hash, rf_hash do writer, agora um @phpstan-type

O caso do cache é o achado que importa. É literalmente o do #1072"a shape estava certa; o furo era o wp_cache_get()" — e ele nunca chegou a estes arquivos porque a régua não os enxergava. A cegueira do passo 3 não escondia só uma contagem: escondeu a aplicação de uma correção que o épico já havia feito em outro módulo. Seis métodos ficaram com um defeito conhecido e documentado porque o gate que deveria acusá-los nunca os olhou.

A asserção de cache vai sempre na chave, nunca no get_cache() do trait — o cache é heterogêneo por chave, e só o método sabe o que guardou sob a dele. Foi assim que o #1072 resolveu, e a razão continua valendo.

Duas decisões

AbstractRepository não ganha shape. É base de várias tabelas, então não existe uma forma só. Ali o honesto é declarar o que ele de fato sabe — que o $wpdb devolve chaves string — e ler o id pelo ArrayValue em vez de castar mixed. Inventar um @phpstan-type genérico ali seria a shape desonesta que o #1060 alerta.

Não declarei um SubmissionRow completo. A consolidação da #1091 agora permitiria, porque as 25 colunas viraram obrigatórias — mas isso é melhoria separada, não é o que os 30 pedem, e o CLAUDE.md manda manter cada correção mínima. Fica registrado como possível, não feito.

Três rodadas de medição, não uma

30 → 10 → 1 → 0. E o que sobrou nas duas primeiras foi sempre aquilo que eu já afirmava ter tratado: o furo de cache do url-shortener (rodada 2) e o ramo de cache hit do findByIds(), um método ao lado do findById() que eu havia anotado no mesmo arquivo (rodada 3). Só a medição disse isso — a leitura não disse.

A folga volta a 0, por encolhimento

Que era a única forma que o comentário do ci.yml admitia quando ela subiu. O comentário foi reescrito para registrar por que subiu (denominador errado, não dívida nova), por quanto tempo ficou em 30, e que uma próxima subida precisa passar pela mesma barra.

Row-reading classes: 53
Level-9 errors in them: 0 (allowed: 0)
None. Every class that reads a row declares what the row holds.
PASS

Essa frase agora é verdadeira. Antes do passo 3 ela era impressa com 30 erros de pé.

Validação

  • Régua: 53 classes, 0 erros, folga 0 — PASS
  • PHPStan nível 8: limpo no repositório inteiro, sem supressão nova
  • WPCS e phpcs-tests.xml.dist: limpos — o @param do hasConflictInForm() foi partido em @param array<string, mixed> mais @phpstan-param IdentifierProjection, porque o WPCS exige que o type hint nativo case com o docblock e um alias do PHPStan não existe para ele. É o idioma que outros 45 arquivos do repositório já usam.
  • Suíte completa: 7657 testes, 21965 asserções, verde (11m25s)
  • Nível 9 do repositório: 2535 → 2505

Refs #1087, #1072, #1090, #1091, #1060

🤖 Generated with Claude Code

https://claude.ai/code/session_012XWx9qJdjZdAq8crxM9GCU


Generated by Claude Code

…ld not see (#1087 passo 4)

Os 30 erros que a regua corrigida (#1090) passou a acusar. Nenhum era novo — a
varredura exigia a substring literal '$wpdb->' e nunca olhou os repositorios que
ligam wpdb como propriedade.

Lendo os 30, eles nao eram majoritariamente "shape de coluna faltando". Eram
quatro origens, e a mais significativa nao tem nada a ver com o $wpdb:

- CACHE DE OBJETOS, em seis metodos de cinco arquivos. wp_cache_get() devolve
  mixed, entao um cache HIT jogava o tipo fora enquanto a leitura do banco
  logo abaixo estava tipada. E literalmente o achado do #1072 — "a shape estava
  certa; o furo era o cache" — que nunca chegou a estes arquivos porque a regua
  nao os enxergava. A cegueira do passo 3 nao escondia so uma contagem: escondeu
  a aplicacao de uma correcao que o epico ja tinha feito em outro modulo.
- PROJECOES AGREGADAS. 'SELECT user_id, COUNT(*)' nao e linha, e projecao — e
  COUNT()/SUM() voltam como string numerica, ou NULL em tabela vazia.
- json_decode SOBRE COLUNA. Colunas JSON escritas pelo proprio plugin, mas lidas
  de um array<string, mixed>, entao chegando como mixed ao parser.
- PROJECAO DE CINCO COLUNAS no writer, que virou @phpstan-type.

A assercao de cache vai sempre na CHAVE, nunca no get_cache() do trait: o cache
e heterogeneo por chave, e so o metodo sabe o que guardou sob a dele. Foi assim
que o #1072 resolveu, e a razao continua valendo.

O AbstractRepository e caso a parte e NAO ganha shape: e base de varias tabelas,
entao nao existe uma forma so. Ali o honesto e dizer o que ele de fato sabe —
que o $wpdb devolve chaves string — e ler o 'id' pelo ArrayValue em vez de
castar mixed.

Uma decisao registrada: NAO declarei um SubmissionRow completo. A consolidacao
da #1091 agora permitiria, porque as 25 colunas viraram obrigatorias, mas isso e
melhoria separada e nao e o que os 30 pedem.

Uma correcao ao meu proprio processo: a primeira rodada cobriu 20 dos 30. Os 10
que sobraram incluiam justamente o furo de cache do url-shortener, que eu havia
descrito como padrao aplicado sem ter aplicado ali. So a medicao disse isso.

Refs #1087, #1072, #1090, #1091, #1060

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XWx9qJdjZdAq8crxM9GCU
…so 4)

O ultimo dos 30, mais a folga de volta a zero.

O erro que restava era o mesmo furo de cache pela terceira vez: o ramo de cache
hit do findByIds(), um metodo ao lado do findById() que eu ja tinha anotado no
mesmo arquivo. Precisei de tres rodadas de medicao (30 -> 10 -> 1 -> 0), e o que
sobrou nas duas primeiras foi sempre aquilo que eu ja afirmava ter tratado.

Isso reforca o achado do passo 3 de um jeito que eu nao tinha percebido: a
cegueira da regua nao escondia so uma contagem. Escondeu a aplicacao de uma
correcao que o #1072 ja tinha feito em outro modulo — seis metodos em cinco
arquivos ficaram com o mesmo defeito conhecido porque o gate que deveria
acusa-los nunca os olhou.

A folga volta a 0 por ENCOLHIMENTO, que era a unica forma que o proprio
comentario admitia. O comentario foi reescrito para registrar por que ela subiu
(denominador errado, nao divida nova), por quanto tempo ficou em 30, e que uma
proxima subida precisa passar pela mesma barra.

O @PARAM do hasConflictInForm() foi partido em @PARAM array<string, mixed> mais
@phpstan-param IdentifierProjection: o WPCS exige que o type hint nativo case
com o docblock, e um alias do phpstan nao existe para ele. E o idioma que outros
45 arquivos do repositorio ja usam.

Refs #1087, #1072, #1090

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XWx9qJdjZdAq8crxM9GCU
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XWx9qJdjZdAq8crxM9GCU
@rpgmem
rpgmem enabled auto-merge (squash) September 7, 2026 00:53
@rpgmem
rpgmem merged commit 7cddac1 into develop Sep 7, 2026
20 checks passed
@rpgmem
rpgmem deleted the claude/row-shapes-repositories-4vvuer branch September 7, 2026 01:06
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 34071209357

Warning

No base build found for commit 0ad8ef1 on develop.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 89.967%

Details

  • Patch coverage: 16 of 16 lines across 6 files are fully covered (100%).

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 53944
Covered Lines: 48532
Line Coverage: 89.97%
Coverage Strength: 4.87 hits per line

💛 - Coveralls

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.

3 participants