# Investigation: Pedidos — Valores incorretos e vinculação clientes × vendedor

## Hand-off Brief

1. **O que aconteceu.** Pedidos exibem valores/status errados e a vinculação cliente↔vendedor está inconsistente; suspeita confirmada de 5 bugs distintos, sendo o mais grave o mismatch de códigos `situa` entre ERP e SAR.
2. **Onde o caso está.** Cinco problemas confirmados ou fortemente deduzidos; `vw_pedidos_erp` (view central usada pelo service) **não está definida em nenhum arquivo de código** — sua definição existe apenas no banco.
3. **O que é necessário agora.** Verificar a DDL de `vw_pedidos_erp` diretamente no banco (`\d+ sarweb.vw_pedidos_erp`) e confirmar se ela normaliza `situa` — isso resolve ou agrava o Bug #1.

## Case Info

| Campo            | Valor                                                              |
| ---------------- | ------------------------------------------------------------------ |
| Ticket           | N/A                                                                |
| Data             | 2026-05-30                                                         |
| Status           | Active                                                             |
| Sistema          | Node 24 / NestJS 11 / Prisma 7 / PostgreSQL (SIG+GERENTE schemas) |
| Fontes           | orders.service.ts, clients.service.ts, sarweb_views.sql, schema.prisma, .env, jwt-auth.guard.ts |

## Problem Statement

Usuário relata: "pedidos com valores errados e vinculação clientes × vendedor"; complementou que a empresa usa `id_empresa = 9001` (schema SIG) e a empresa gerencial é a `1` (schema GERENTE), e que às vezes dados estão duplicando nas telas.

## Evidence Inventory

| Fonte                                   | Status     | Notas                                                    |
| --------------------------------------- | ---------- | -------------------------------------------------------- |
| `orders.service.ts`                     | Available  | Lido completo — queries brutas sem esquema qualificado   |
| `clients.service.ts`                    | Available  | Lido completo                                            |
| `sarweb_views.sql`                      | Available  | Define `vw_pedidos`, NÃO define `vw_pedidos_erp`         |
| `schema.prisma`                         | Available  | Schema `sar` no PG; tabela `pedidos` é SAR-only          |
| `jwt-auth.guard.ts`                     | Available  | Em dev usa `DEV_EMPRESA_ID` e `DEV_REP_CODE` do `.env`   |
| `.env`                                  | Available  | `DEV_EMPRESA_ID=1`, `DEV_REP_CODE=29`                    |
| DDL de `vw_pedidos_erp` no banco        | **Missing** | Não está no repo — requer `\d+` direto no PG             |
| Logs do PG / EXPLAIN com id_empresa=9001| **Missing** | Requer execução manual                                   |

## Confirmed Findings

### Finding 1: `DEV_EMPRESA_ID=1` mas a empresa real é SIG (id=9001)

**Evidência:** `.env:DEV_EMPRESA_ID=1` e `jwt-auth.guard.ts:56` — em dev, `idEmpresa` é forçado para `1` (GERENTE), ignorando o JWT.

**Detalhe:** Em desenvolvimento, todas as queries usam `WHERE id_empresa = 1` e buscam dados do schema GERENTE. A empresa real do usuário está no schema SIG com `id_empresa = 9001`. Portanto, os testes locais estão apontando para dados diferentes dos de produção.

**Fix imediato:** Alterar `.env`: `DEV_EMPRESA_ID=9001`.

---

### Finding 2: `vw_pedidos_erp` não existe em nenhum arquivo do repositório

**Evidência:**
- `orders.service.ts:77` — `FROM vw_pedidos_erp e`
- `sarweb_views.sql` — define `sarweb.vw_pedidos`, não `vw_pedidos_erp`
- `grep -rn "vw_pedidos_erp"` → apenas `orders.service.ts` e `dashboard.service.ts`; zero arquivos SQL

**Detalhe:** A view existe somente no banco (criada manualmente). Seu comportamento exato — especialmente se normaliza `situa` do ERP para valores SAR — é desconhecido sem inspecionar o banco.

---

### Finding 3: Mismatch de códigos `situa` entre ERP e SAR

**Evidência:** `sarweb_views.sql:367-378` (GERENTE) vs `sarweb_views.sql:411-418` (SIG) vs `order.contract.ts:13-18` (SAR).

| Situa | GERENTE ERP  | SIG ERP      | SAR (app)       |
|-------|-------------|-------------|-----------------|
| 1     | Pendente    | Pendente    | Ag. Aprovação   |
| 2     | Liberado    | Liberado    | Aprovado        |
| 3     | **Faturado**| Liberado    | **Cancelado**   |
| 4     | **Cancelado**| **Faturado**| **Faturado**  |
| 5     | —           | **Cancelado**| —              |

**Efeito confirmado (GERENTE):** Um pedido FATURADO no ERP (`situa=3`) exibe cor **vermelha** (Cancelado) no SAR — porque `OrderStatusBadge` usa o número cru para definir `tagColor`. O texto pode estar correto (via `statusDescr`) mas a cor é errada.

**Efeito no filtro de status:** `situaFilter = situa != null ? 'AND e.situa = ${situa}' : ''` — se o usuário filtra `situa=3` (SAR=Cancelado), recebe pedidos FATURADOS do GERENTE.

---

### Finding 4: `dt_ultima_compra` ignorando histórico ERP — `activityStatus` sempre errado

**Evidência:** `clients.service.ts:100` —
```sql
LEFT JOIN pedidos p ON p.id_cliente = c.id_cliente
  AND p.id_empresa = c.id_empresa
  AND p.situa != 3
```
`pedidos` aqui é a tabela SAR (`sar.pedidos`, Prisma), não os pedidos históricos do ERP.

**Detalhe:** Clientes que têm anos de histórico no ERP mas nunca fizeram pedido pelo SAR ficam com `dt_ultima_compra = NULL` → `activityStatus = 'inactive'`. Portanto, a carteira inteira aparece como **"Inativo"** na tela de Clientes.

**Fix necessário:** O JOIN deve usar `vw_pedidos_erp` (ou equivalente) em vez da tabela SAR.

---

### Finding 5: Filtro por `status` de clientes aplicado DEPOIS da paginação SQL

**Evidência:** `clients.service.ts:138` —
```typescript
if (status) mapped = mapped.filter((c) => c.activityStatus === status);
```
O `total` vem de `SELECT COUNT(*)` sem o filtro de status (`clients.service.ts:114-122`).

**Efeito:** Ao filtrar por `status=active`, a API retorna menos itens que `limit` (ex.: 8 de 50), mas `total` ainda diz 2606. A paginação fica quebrada e a portfólio card mostra totais incorretos quando usa `useClientList({ limit:1, status:X })`.

---

## Hypothesized Paths

### Hypothesis 1: `vw_pedidos_erp` causa duplicação via UNION sem filtro por empresa

**Status:** Open

**Teoria:** `vw_pedidos_erp` faz UNION ALL de GERENTE + SIG sem filtrar por `id_empresa`, e para uma empresa que existe nos dois schemas (id=1 e id=9001), as mesmas ordens aparecem duas vezes.

**Confirmaria:** `\d+ sarweb.vw_pedidos_erp` mostrando UNION ALL sem cláusula WHERE por empresa, + query retornando duplicatas com `id_empresa` distintos.

**Refutaria:** View com UNION ALL onde cada SELECT tem `AND id_empresa = X` fixo.

---

### Hypothesis 2: SAR-created orders nunca aparecem na listagem

**Status:** Open

**Teoria:** `orders.service.ts list()` só consulta `vw_pedidos_erp` (ERP), nunca `sar.pedidos` (Prisma). Pedidos criados pelo SAR somem da lista após criação.

**Confirmaria:** Criar pedido via SAR → abrir `/pedidos` → pedido não aparece na lista.

**Refutaria:** `vw_pedidos_erp` inclui `sar.pedidos` via UNION ALL.

---

## Missing Evidence

| Gap                              | Impacto                                      | Como obter                                    |
| -------------------------------- | -------------------------------------------- | --------------------------------------------- |
| DDL de `vw_pedidos_erp`          | Confirma/refuta H1, H2 e Bug #3 (situa)      | `\d+ sarweb.vw_pedidos_erp` no psql           |
| Query real com id_empresa=9001   | Confirma duplicação e valores                | Rodar GET /orders com JWT prod ou DEV_ID=9001  |
| Confirmar se `sar.pedidos` aparece na lista | Confirma H2                        | Criar pedido SAR → verificar lista /orders     |

## Source Code Trace

| Elemento       | Detalhe                                                       |
| -------------- | ------------------------------------------------------------- |
| Bug #1 origem  | `jwt-auth.guard.ts:56` — `DEV_EMPRESA_ID` sobrescreve JWT     |
| Bug #2 origem  | Banco de dados (DDL não versionada)                          |
| Bug #3 origem  | `orders.service.ts:43,45,98-99` — `situa` cru do ERP         |
| Bug #4 origem  | `clients.service.ts:100` — JOIN com `sar.pedidos` (não ERP)  |
| Bug #5 origem  | `clients.service.ts:138` — filter JS pós-paginação SQL        |

## Conclusion

**Confidence:** Medium (root causes identificadas; DDL de `vw_pedidos_erp` é peça faltante)

Cinco bugs confirmados ou fortemente deduzidos explicam os sintomas:

1. **DEV aponta para empresa errada** (`DEV_EMPRESA_ID=1` vs real=9001) — dados diferentes entre dev e prod.
2. **`situa` ERP ≠ SAR** — cores/filtros de status errados para pedidos históricos.
3. **`dt_ultima_compra` ignora ERP** — carteira toda aparece inativa.
4. **`status` filter pós-paginação** — totais e paginação quebrados.
5. **`vw_pedidos_erp` não versionada** — comportamento opaco, possível fonte de duplicação.

## Recommended Next Steps

### Fix imediato (sem risco)
Alterar `.env`: `DEV_EMPRESA_ID=9001` para que dev espelhe produção.

### Antes de qualquer outro fix: verificar `vw_pedidos_erp` no banco
```sql
-- Rodar diretamente no psql:
\d+ sarweb.vw_pedidos_erp
-- ou
SELECT pg_get_viewdef('sarweb.vw_pedidos_erp', true);
```
O resultado define o caminho dos próximos fixes.

### Fix #3 — `situa` — normalizar na `vw_pedidos_erp` (ou no service)
Adicionar CASE na view (ou no service) mapeando ERP situa → SAR situa:
```sql
-- GERENTE: 2→2, 3→4(Faturado), 4→3(Cancelado)
-- SIG:     2→2, 4→4(Faturado), 5→3(Cancelado)
```

### Fix #4 — `dt_ultima_compra` — usar ERP orders
Em `clients.service.ts:100`, substituir `pedidos` por `vw_pedidos_erp` (ou a view equivalente):
```sql
LEFT JOIN vw_pedidos_erp p
  ON p.id_cliente = c.id_cliente
  AND p.id_empresa = c.id_empresa
  AND p.situa NOT IN (3, 4, 5)  -- situa=cancelado nos dois sistemas
```

### Fix #5 — `status` filter — mover para SQL
Em `clients.service.ts`, incluir o filtro de `activityStatus` na query SQL via subquery ou CTE com `dt_ultima_compra`, eliminando o filter JS pós-paginação.

## Reproduction Plan

1. Alterar `DEV_EMPRESA_ID=9001` no `.env`
2. Reiniciar a API
3. Abrir `/clientes` → verificar se clientes aparecem e se `activityStatus` faz sentido
4. Abrir `/pedidos` → verificar se pedidos aparecem e se status está correto
5. Rodar `\d+ sarweb.vw_pedidos_erp` no banco e trazer o resultado para continuar a investigação

## Side Findings

- `ALERT_DAYS=30` e `INACTIVE_DAYS=60` estão hardcoded em `clients.service.ts:11-12`. O comentário diz "Configuráveis por empresa futuramente" — tarefa pendente.
- `orders.service.ts:46` usa interpolação de string direta para `numPedSar` (ILIKE). O `escSql()` de `clients.service.ts:24` não é reutilizado aqui — potencial SQL injection menor para campo de busca.
- `vw_pedidos` em `sarweb_views.sql` não é usada em lugar nenhum do código fonte — `vw_pedidos_erp` é usada em seu lugar. Possível que `vw_pedidos_erp` seja um rename ou extensão da `vw_pedidos`.
