Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 79 additions & 21 deletions docs/atros-v3/handoff-2026-08-13-capital-de-giro.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
# Handoff 2026-08-13 — Capital de Giro: da spec ao G2 em produção

**Estado (2026-08-17):** **G1, G2 e G3 entregues.** Núcleo puro + série mensal no banco
(backfill de 34 meses, check ao vivo feito) + a tela do Nível 0 no ar. Falta o smoke
visual — a rota é autenticada e ninguém abriu ainda.
# Handoff 2026-08-13 — Capital de Giro: da spec ao G3 em produção

> ## ▶ A PRÓXIMA SESSÃO COMEÇA AQUI
>
> **G1, G2 e G3 estão em `main`** — PR [#57](https://github.com/BarryBits/ATR-OS/pull/57),
> merge `ca56603`, CI verde (incluindo `next build`). Migration aplicada, re-dump feito,
> backfill de 34 meses, smoke visual feito pelo Lucas.
>
> **Duas frentes abertas, nesta ordem de prioridade:**
>
> **1. O VISUAL — e ele é do Lucas, não da IA.** Decisão dele em 2026-08-17: *"você
> desenha, eu aplico"*. **Não redesenhar por conta própria.** Ele manda print anotado ou
> ajusta `_local/mockups/capital-de-giro-mockup.html`, e a sessão implementa o que vier.
> Três fatos já levantados que a decisão precisa considerar:
> - a casa usa `font-mono` para números **só até `text-xl`**; em `clamp(30–42px)` ele
> vira fonte de terminal (foi o que o Lucas viu);
> - o mockup usa **Rajdhani**, que o app não carrega — trazer significa mais uma fonte e
> divergir do resto do sistema;
> - a composição do mockup foi desenhada para **`max-width: 1000px`**; na largura real da
> tela ela arrebenta (o gráfico gigante era sintoma disso).
>
> **2. G4 — os 3 saldos no fechamento** (§6). É o que destrava o Nível 1 e faz a espinha
> (o gráfico de barras empilhadas) finalmente existir. Nada dele começou.
>
> **O que NÃO fazer:** dropar `cash_cycle_analyses` ou `cash_flow_params` — isso é o
> **G7**, em sessão própria, com grep-de-prova na hora e re-dump. `PainelAnaliseSections`
> e `EstoqueSection` estão órfãs **de propósito**, com comentário explicando.

**Estado (2026-08-17):** **G1, G2 e G3 em produção.** Núcleo puro + série mensal no banco
+ a tela do Nível 0 no ar, com os 5 bugs do smoke visual corrigidos.
**Canônico:** [`capital-de-giro-spec.md`](./capital-de-giro-spec.md) — tudo verificado
no código vivo (`arquivo:linha`) e na baseline, não em afirmação de doc.
**Mockup:** `_local/mockups/capital-de-giro-mockup.html` (gitignored) — v5, régua em
Expand All @@ -14,17 +39,20 @@ dias, bloco da conta do crescimento, 3 níveis alternáveis. Gerado por
> a spec foi atualizada em 11 seções (§2.1). Na mesma data entraram o **G1** (§4.2) e o
> **G2** (§4.3).

**G1** (§4.2) · **G2** (§4.3) · **G3** (§4.4). Dois bugs achados pelo dado real, não
pelos testes: o custo do giro saindo pela metade (§4.3) e um descasamento fabricado
(§4.4). Próximo passo: **smoke visual do G3**, depois **G4** — os 3 números no
fechamento.
**G1** (§4.2) · **G2** (§4.3) · **G3** (§4.4) · **fechamento da sessão** (§4.5).
Quatro bugs que os testes não pegaram e o dado real pegou: o custo do giro saindo pela
metade (§4.3), um descasamento fabricado, o bloco 4 invisível para o ICP e a
anualização por multiplicação (§4.4).

---

## 1. O diagnóstico que originou tudo

`/financeiro/giro` é uma tela morta: três cards vazios e *"Ainda não calculado — abra
o Ciclo de caixa para gerar"*.
> Histórico — resolvido no G3. Fica registrado porque explica POR QUE a tela mudou de
> pergunta, e é a parte que não se deduz lendo o código novo.

`/financeiro/giro` **era** uma tela morta: três cards vazios e *"Ainda não calculado —
abra o Ciclo de caixa para gerar"*.

**A causa não é preguiça.** A tela foi construída para calcular um índice de **balanço**
(contas a receber + estoque − fornecedores) a partir de uma fonte de **fluxo** (extrato).
Expand Down Expand Up @@ -57,7 +85,7 @@ casaram o regex, não acerto.
| D8 | Giro não vira 5ª métrica com meta — entra como **restrição de caixa da meta** que já existe | §10.2 |
| D9 | **A barra empilhada é a espinha da tela**; composição, variação, meta e simulação são leituras dela | §13.2 |
| D10 | A simulação **desenha uma coluna a mais no gráfico**. Fato é preenchido, cenário é contorno | §13.3 |
| D11 | Normalização em **R$ a cada R$ 100 mil faturados**, não em centavos por real | §13.3.1 |
| ~~D11~~ | ~~Normalização em R$ a cada R$ 100 mil faturados~~ — **SUPERADA pela D15** (régua em dias) | §13.3.1 |
| D12 | A carteira do gate é **piso, nunca razão** — dois cegos estruturais | §19 |
| D13 | **O total é do dono; o detalhe é do sistema.** Confronto explícito em 4 faixas | §20 |
| D14 | Procedência **dentro do gráfico**: rastreado sólido, informado hachurado | §20.4 |
Expand Down Expand Up @@ -130,7 +158,7 @@ nomeados pelo que medem (*"seu estoque dura 47 dias de venda"*).

---

## 4. O que precisa ser criado
## 4. O que precisou ser criado (✅ tudo feito no G2)

| Objeto | Ação |
|---|---|
Expand Down Expand Up @@ -214,7 +242,7 @@ conversão, mas sem acoplar o núcleo àquele módulo.
- `decompor` joga o **termo cruzado na eficiência** — erra pro lado que o dono precisa
ver.

## 4.3 G2 — SNAPSHOT MENSAL: CÓDIGO PRONTO, **MIGRATION NÃO APLICADA** (2026-08-17)
## 4.3 G2 — SNAPSHOT MENSAL ENTREGUE (2026-08-17)

| Artefato | O quê |
|---|---|
Expand Down Expand Up @@ -420,19 +448,49 @@ Lucas vai desenhar e eu aplico. O que se sabe hoje: a casa usa `font-mono` só a
que o app não carrega; e a composição do mockup foi desenhada para `max-width: 1000px`,
não para a largura real da tela.

### O que este bloco AINDA NÃO verificou
### Ainda sem verificação

1. **O bloco 4 (crescimento) não foi conferido contra dado real.** Ele depende de
`montarProjecaoAnualParaProjeto`, que chama `cookies()` e só roda dentro de um
request — o script de check não alcança. A lógica tem 23 testes, mas a integração é
fé até alguém abrir a tela.
2. **Nenhum screenshot.** A rota é autenticada e não há credencial de teste aqui.
Fidelidade de UI exige olhar, e ninguém olhou.
**O bloco 4 no modo `plano` nunca renderizou contra dado real.** A Vertímetal cai no
modo `teto` (não tem meta com crescimento nem tendência positiva), então a cadeia
completa — os 3 degraus + a curva de folga divergente — só será exercitada quando algum
projeto tiver meta travada com crescimento > 0. A lógica tem 23 testes; a integração é
fé até lá.

Fica um `seguro()` em volta das duas chamadas do bloco 4: `.catch()` na promise **não
basta**, porque `cookies()` estoura de forma síncrona e o throw passa por cima — §24.3,
um bloco quebrado degrada sozinho e nunca leva a tela junto.

## 4.5 Fechamento da sessão de 2026-08-17

**Mergeado:** PR [#57](https://github.com/BarryBits/ATR-OS/pull/57) → `main` `ca56603`,
28 arquivos, branch remota deletada.

**O CI pegou um erro de sequência meu.** O gate `gerar-estrutura.ts --check` reprovou em
37s: rodei o gerador do mapa logo depois da migration e tratei aquele gate como "coisa
de banco". Ele é **dump × código** — conta os `.from()` do `src/`, e o
`giro-view-service.ts`, escrito depois, somou três (`projects` 110→111,
`dre_monthly_snapshots` 59→60, `giro_monthly_snapshots` 3→4). **Regra: o gerador é o
último passo antes do commit, não o passo seguinte ao dump.** Conserto em `238c018`.

**Fora do PR de propósito:** `.claude/settings.local.json` segue modificado — é o
allowlist de permissões acumulado de várias sessões (tem entrada de `fin-fase2`, bem
anterior a esta). Commite separado; misturar com feature é ruído.

**Dois tropeços operacionais registrados em memória:**

1. **Zerei o `db/snapshot/seed.sql`.** Dumpei para temporário (a metade fácil de
lembrar) e copiei por cima **sem conferir o tamanho** — o Docker auto-pausou, o dump
saiu vazio. É gitignored, o git não desfaz. Recuperado de um temporário anterior. A
guarda que faltava é o `if [ "$L" -gt N ]` antes do `cp`, nunca o "dumpe para
temporário" sozinho.
2. **O carregador de `.env.local` falhava calado:** `split("\n")` deixa o `\r`, e em
regex JS o `\r` é terminador de linha — `(.*)$` não casa em CRLF e **nenhuma**
variável era lida, sem erro. Split por `/\r?\n/`.

**Estado de verificação ao fim:** `tsc` limpo · `eslint src/lib/giro src/components/giro`
exit 0 · `PainelCasaTab` com os mesmos 2 erros de token do HEAD (débito pré-existente) ·
**1863/1863** testes · CI verde ponta a ponta.

## 5. Pendências conhecidas

1. **Sliders do mockup são estáticos** — mexer não redesenha a coluna simulada. Ligar o
Expand Down
Loading