Skip to content

fix(dre): a transação do dia 1 parou de sumir do mês (fuso) - #40

Merged
BarryBits merged 1 commit into
mainfrom
fix/fuso-data-banco
Jul 31, 2026
Merged

fix(dre): a transação do dia 1 parou de sumir do mês (fuso)#40
BarryBits merged 1 commit into
mainfrom
fix/fuso-data-banco

Conversation

@BarryBits

Copy link
Copy Markdown
Owner

Onda 2 da auditoria da DRE. Sequência da Onda 1 (#39).

O bug

transactions.data é coluna date, então o supabase-js devolve a string crua "2026-06-01" — e new Date("2026-06-01") é parseado como UTC pelo ECMAScript. No fuso de Brasília:

new Date("2026-06-01").getDate()   // 31
new Date("2026-06-01").getMonth()  // 4 = maio

Como fatiaDoMes filtra por chave "YYYY-MM", a transação do dia 1 não era encontrada em junho (virou "2026-05") nem aparecia em maio (fora do recorte): sumia da DRE inteira. A visão DIA mostrava tudo um dia antes; a visão SEMANA jogava segunda-feira na semana ISO anterior.

O caminho do servidor não sofria (runtime em UTC) — mais uma divergência entre mês fechado e mês aberto, mesma família do bug da folha.

A correção

A ingestão já estava certa: parseFlexibleDate constrói local. O defeito morava só na leitura. Agora existe o par explícito ao lado dela, em src/lib/parsers/utils.ts:

parseDataBanco string de coluna date → meia-noite local
formatDataBanco Date"YYYY-MM-DD" pelos campos locais

toISOString() passa por UTC e, em fuso positivo, grava o dia anterior — por isso o caminho de escrita também entrou.

Repointadas 5 fronteiras de leitura (useDreController, dreService, financial-snapshot-service, visao-service, rota fechar-mes) e 3 pontos de escrita.

O fechar-mes acertava por acidente (runtime em UTC); agora é determinístico — servidor e browser leem a mesma data independente do fuso da máquina.

Por que nenhum teste pegava

A suíte ancorava as datas ao meio-dia (new Date(iso + "T12:00:00")), que mascara o deslocamento. Os testes novos usam a string crua do banco, com TZ=America/Sao_Paulo:

  • parseDataBanco — 11 casos (dia 1, round-trip dos 30 dias, virada de ano, DIA/SEMANA, idempotência, timestamp completo)
  • montarDrePorPeriodo.fuso — 5 casos de regressão end-to-end

Um deles pegou um defeito no próprio helper durante o desenvolvimento: sem âncora $ na regex, o prefixo de um timestamp completo casava e o horário era descartado.

Verificação

  • 1434 testes / 155 arquivos verdes (+16 novos)
  • tsc limpo em src/
  • eslint: zero erros novos — os 2 de dreService.ts são idênticos em HEAD (baseline: 6 problems, 2 errors, 4 warnings)
  • zero migration · nenhum dado no banco precisa ser corrigido (a ingestão sempre gravou a data certa)

🤖 Generated with Claude Code

`transactions.data` é coluna `date`, então o supabase-js devolve a string
crua "2026-06-01" — e `new Date("2026-06-01")` é parseado como UTC pelo
ECMAScript. No fuso de Brasília isso vira 31/05 21:00:

    new Date("2026-06-01").getDate()   // 31
    new Date("2026-06-01").getMonth()  // 4 = maio

Como `fatiaDoMes` filtra por chave "YYYY-MM", a transação do dia 1 não era
encontrada em junho (virou "2026-05") nem aparecia em maio (fora do
recorte): sumia da DRE inteira. A visão DIA mostrava tudo um dia antes e a
visão SEMANA jogava segunda-feira na semana ISO anterior.

O caminho do servidor não sofria (runtime em UTC), o que criava mais uma
divergência entre mês fechado e mês aberto — a mesma família do bug da
folha.

A ingestão já estava certa: `parseFlexibleDate` constrói local. O defeito
morava só na LEITURA. Agora existe o par explícito ao lado dela:

  - parseDataBanco  — string de coluna `date` → meia-noite LOCAL
  - formatDataBanco — Date → "YYYY-MM-DD" pelos campos locais
    (`toISOString()` passa por UTC e, em fuso positivo, grava o dia anterior)

Repointadas as 5 fronteiras de leitura (useDreController, dreService,
financial-snapshot-service, visao-service, rota fechar-mes) e os 3 pontos
de escrita que passavam por `toISOString()`.

Por que nenhum teste pegava isso: a suíte ancorava as datas ao meio-dia
(`new Date(iso + "T12:00:00")`), que mascara o deslocamento. Os testes
novos usam a string CRUA do banco, com TZ=America/Sao_Paulo.

Um deles pegou um defeito no próprio helper durante o desenvolvimento: sem
âncora `$` na regex, o prefixo de um timestamp completo casava e o horário
era descartado.

Validação: 1434/1434 (155 arquivos, +16 novos) · tsc limpo em src/ ·
eslint 0 erros novos (os 2 de dreService.ts são idênticos em HEAD) ·
zero migration.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@supabase

supabase Bot commented Jul 31, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project tdlxqqgechxhkygdmsxq because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
atr-os Ready Ready Preview Jul 31, 2026 9:17pm

@BarryBits
BarryBits merged commit 4d4b3dd into main Jul 31, 2026
4 checks passed
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