# 📚 Guia de Manutenção - Módulo GT_DoctoTransporte

**Versão:** 2.0 (Refatorado)  
**Data:** Fevereiro 2026  
**Status:** Produção  
**Última Atualização:** Migração completa de JavaScript para arquivos separados

---

## 📑 Índice

1. [Visão Geral da Arquitetura](#visão-geral)
2. [Estrutura de Arquivos](#estrutura-de-arquivos)
3. [Fluxos de Dados](#fluxos-de-dados)
4. [Descrição de Componentes](#descrição-de-componentes)
5. [Guias de Manutenção](#guias-de-manutenção)
6. [Troubleshooting](#troubleshooting)
7. [Padrões e Convenções](#padrões-e-convenções)

---

## <a name="visão-geral"></a>🏗️ Visão Geral da Arquitetura

### Conceito
O módulo GT_DoctoTransporte gerencia documentos de transporte (CTe, CTe-OS, NFS, OT) com suporte a:
- ✅ Cadastro/Edição de documentos
- ✅ Composição de valores (múltiplos itens)
- ✅ Sincronização com banco de dados PostgreSQL
- ✅ Integração com SEFAZ (em desenvolvimento)
- ✅ Interface responsiva com abas

### Stack Tecnológico
- **Backend:** PHP 7.4+
- **Database:** PostgreSQL
- **Frontend:** JavaScript (Vanilla) + Bootstrap 5
- **Estilos:** CSS customizado + Material Icons
- **Arquitetura:** Modular (separação HTML/JS/PHP)

### Padrão Adotado: MVC Leve
```
┌─────────────────────────────────────────────┐
│  Views (HTML/PHP)                           │
│  ├─ cad.php (formulário principal)          │
│  ├─ composicao_form.php (tabela composição) │
│  └─ index.php (lista documentos)            │
├─────────────────────────────────────────────┤
│  Controllers (PHP handlers)                 │
│  ├─ insert.php (CRUD principal)             │
│  ├─ composicao_salvar.php (INSERT item)     │
│  ├─ composicao_atualizar.php (UPDATE item)  │
│  └─ composicao_deletar.php (DELETE item)    │
├─────────────────────────────────────────────┤
│  Models (BD + API)                          │
│  └─ gt_doctotransporte (tabelas)            │
├─────────────────────────────────────────────┤
│  Views - JavaScript (Lógica frontend)       │
│  ├─ js/formulario.js (validação + envio)    │
│  ├─ js/composicao.js (CRUD local)           │
│  ├─ formulario_handlers.php (listeners)     │
│  └─ composicao_handlers.php (listeners)     │
└─────────────────────────────────────────────┘
```

---

## <a name="estrutura-de-arquivos"></a>📁 Estrutura de Arquivos

```
gt_doctotransporte/
│
├── 📄 ARQUIVOS PRINCIPAIS
│   ├── cad.php ........................ Formulário cadastro/edição (490 linhas)
│   ├── insert.php ..................... Handler POST principal (269 linhas)
│   ├── index.php ...................... Lista de documentos
│   ├── delete.php ..................... Deletar documento
│   ├── filtro.php ..................... Filtros para listagem
│   ├── select.php ..................... Autocompletamento/seleção
│   └── GUIA_MANUTENCAO.md ............ Este arquivo
│
├── 📋 COMPONENTES FORMULÁRIO
│   ├── composicao_form.php ........... HTML tabela composição (35 linhas)
│   └── formulario_handlers.php ....... Event listeners (55 linhas)
│
├── 🔧 ENDPOINTS COMPOSIÇÃO (API REST)
│   ├── composicao_listar.php ......... GET composições ativadas
│   ├── composicao_salvar.php ......... POST novo item (74 linhas)
│   ├── composicao_atualizar.php ...... PUT item existente
│   ├── composicao_deletar.php ........ DELETE item
│   └── composicao_handlers.php ....... Event listeners (45 linhas)
│
├── 📂 js/ (JavaScript modularizado)
│   ├── formulario.js ................. Lógica formulário (187 linhas)
│   │   ├── atualizarHiddenInputs()
│   │   ├── emitirDocumento()
│   │   ├── consultarSituacao()
│   │   ├── cancelarDocumento()
│   │   ├── reimprimir()
│   │   ├── carregarCFOPs()
│   │   └── enviarFormularioComValidacao()
│   │
│   └── composicao.js ................ Lógica composição (327 linhas)
│       ├── carregarComposicao()
│       ├── adicionarLinhaComposicao()
│       ├── removerLinhaComposicao()
│       ├── renderizarComposicao()
│       ├── atualizarTotalComposicao()
│       └── salvarItemComposicao()
│
└── 📚 DOCUMENTAÇÃO
    └── IMPLEMENTACAO_LAYOUT_ABAS.md .. Detalhes de UI/UX
```

### Resumo de Linhas de Código
| Arquivo | Tipo | Linhas | Status |
|---------|------|--------|--------|
| cad.php | PHP/HTML | ~490 | ✅ Limpo |
| insert.php | PHP | 269 | ✅ Ativo |
| js/formulario.js | JS | 187 | ✅ Novo |
| js/composicao.js | JS | 327 | ✅ Novo |
| composicao_salvar.php | PHP | 74 | ✅ Ativo |
| **TOTAL** | - | **~1,350** | **Modularizado** |

---

## <a name="fluxos-de-dados"></a>⚡ Fluxos de Dados

### Fluxo 1: Criar Novo Documento

```
1. Usuário abre cad.php (action=0)
   │
2. JavaScript executa:
   ├─ formulario_handlers.php → DOMContentLoaded
   ├─ Define data do documento = hoje
   ├─ Carrega CFOPs via AJAX → dm_cfop/select.php
   └─ Carrega composição (vazia para novo doc)
   │
3. Usuário preenche formulário
   │
4. Clica em "Salvar"
   │
5. enviarFormularioComValidacao() → fetch POST
   │
6. insert.php processa:
   ├─ Validar permissões
   ├─ Preparar dados (pg_escape_string)
   ├─ INSERT em gt_doctotransporte
   ├─ Retorna JSON { sucesso: true, url: ... }
   │
7. JavaScript mostra modal de sucesso
   │
8. Redireciona para edição (action=1)
   └─ Carrega dados do documento criado
```

### Fluxo 2: Adicionar Item de Composição

```
1. Usuário clica em "Adicionar Item"
   │
2. adicionarLinhaComposicao():
   ├─ Valida se documento foi salvo
   ├─ Cria novo objeto {novo: true, ...}
   ├─ Adiciona ao array composicaoItems
   └─ Chama renderizarComposicao()
   │
3. renderizarComposicao():
   ├─ Limpa tbody
   ├─ Cria elemento <tr> para cada item
   ├─ Adiciona inputs: tipo, valor, status
   ├─ Mostra botão "Salvar" para novo
   ├─ Atualiza total em tempo real
   └─ Sincroniza vlrtotal/vlrreceber/impbasecalculo
   │
4. Usuário edita campos (tipo, valor, status)
   │
5. Clica em "Salvar"
   │
6. salvarItemComposicao():
   ├─ Valida valor > 0
   ├─ Se novo: POST → composicao_salvar.php (INSERT)
   ├─ Se modificado: POST → composicao_atualizar.php (UPDATE)
   │
7. Endpoint retorna:
   ├─ {sucesso: true, id: newId} para novo
   ├─ {sucesso: true, id: itemId} para UPDATE
   │
8. JavaScript:
   ├─ Remove flags (novo, modificado)
   ├─ Mostra modal de sucesso
   └─ Re-renderiza tabela
```

### Fluxo 3: Deletar Item de Composição

```
1. Usuário clica em botão "Remover" na linha
   │
2. removerLinhaComposicao(index):
   ├─ Se item.novo === true:
   │  └─ Apenas remove do array local
   │
   └─ Se item.id existir (já no BD):
      ├─ POST → composicao_deletar.php
      ├─ { id: itemId }
      │
      3. composicao_deletar.php:
         ├─ Validar permissões
         ├─ DELETE FROM gt_doctotransporte_composicao
         ├─ Recalcula SUM(valor) dos itens restantes
         └─ UPDATE gt_doctotransporte com novo total
      │
      4. Retorna {sucesso: true}
      │
      5. JavaScript:
         ├─ Remove item do array
         ├─ Re-renderiza tabela
         ├─ Mostra modal de sucesso
         └─ Atualiza totais
```

### Fluxo 4: Atualizar Campos Disabled (SEFAZ)

```
1. Usuário não pode editar direto (campos disabled)
   │
2. Mas precisa sincronizar ao salvar
   │
3. atualizarHiddenInputs() (chamada antes do submit):
   ├─ Sincroniza situacao
   ├─ Sincroniza status
   ├─ Sincroniza numerofiscal
   ├─ Sincroniza seriefiscal
   ├─ Sincroniza chavefiscal
   ├─ Sincroniza protocoloaut
   ├─ Sincroniza dtautorizacao
   └─ Sincroniza dtcancelamento
   │
4. Esses hidden inputs são submetidos
   │
5. insert.php recebe e atualiza BD
```

---

## <a name="descrição-de-componentes"></a>🔧 Descrição Detalhada dos Componentes

### 1️⃣ **cad.php** - Formulário Principal
**Responsabilidade:** Exibir e coordenar toda a interface de cadastro/edição

**Seções HTML:**
```php
┌─ Header (includes PHP)
├─ Modais (sucesso/erro) ← Bootstrap modals
├─ System de Abas (nav-tabs)
│  ├─ TAB 1: Documento Fiscal (ATIVO)
│  │  ├─ Card: Informações Gerais (dtdocto, tipodocto, etc)
│  │  ├─ Card: Participantes (remetente, destinatario, etc)
│  │  ├─ Card: Valores e Impostos
│  │  ├─ Card: Seguros
│  │  └─ Card: Observações
│  │
│  ├─ TAB 2: Composição Valores
│  │  └─ Include: composicao_form.php
│  │
│  ├─ TAB 3: Nota Fiscal (em desenvolvimento)
│  │
│  └─ TAB 4: Autorização SEFAZ
│     └─ Botões: Emitir, Consultar, Cancelar, Reimprimir
│
└─ Scripts (includes)
   ├─ js/composicao.js
   ├─ composicao_handlers.php
   ├─ js/formulario.js
   └─ formulario_handlers.php
```

**Dados Tratados:**
- Informações gerais (data, tipo, filial)
- Participantes (7 campos de FK)
- Valores (vlrtotal, vlrreceber, impostos)
- Seguros
- Observações
- Campos disabled (situacao, status, nf, autorização)

**Importante:** Campos disabled sincronizados via hidden inputs antes do submit

---

### 2️⃣ **insert.php** - Handler de Cadastro/Edição
**Responsabilidade:** Processar POST e gerenciar transações de BD

**Fluxo Lógico:**
```php
1. Validar método POST
2. Detectar se é AJAX ou form tradicional
3. Validar permissões (criar ou editar)
4. Escapar todos os inputs (pg_escape_string)
5. Preparar variáveis
6. Se action=0 (novo): INSERT
7. Se action=1 (editar): UPDATE
8. Retornar JSON ou redirecionar
```

**Campos INSERT/UPDATE:**
```sql
dt_docto, dt_emissão, tipo_docto, tipo_servico
id_filial, id_remetente, id_expedidor, id_destinatario
id_recebedor, id_tomador, id_mercadoria, id_volume
id_veiculo, id_motorista, peso_bruto, vlr_carga
vlr_total, vlr_receber, id_cfop
imp_cst, imp_base_calculo, imp_aliquota, imp_valor
cnpj_seguro, nome_seguro, apolice_seguro
averbacao_seguro, vlr_seguro, obs, obs_fisco
```

**Campos Readonly (apenas leitura)::**
```sql
situacao, status, numero_fiscal, serie_fiscal
chave_fiscal, protocolo_aut, dt_autorizacao, dt_cancelamento
```

**Retorno:**
- **Sucesso:** `{sucesso: true, url: "/gt_doctotransporte/cad.php?id=123&action=1"}`
- **Erro:** `{sucesso: false, erro: "mensagem de erro"}`

---

### 3️⃣ **Endpoints de Composição**

#### **composicao_salvar.php** - INSERT Item
```php
POST /composicao_salvar.php

ENTRADA:
{
  "iddocto": 123,
  "tipocomposicao": 0,      // 0-15 (FRETE PESO, FRETE VALOR, etc)
  "valor": 150.50,
  "status": 0               // 0=Ativo, 1=Inativo
}

SAÍDA:
{
  "sucesso": true,
  "id": 456                 // ID do novo item
}
```

**Processo:**
1. INSERT na gt_doctotransporte_composicao
2. Calcula SUM(valor) WHERE status=0
3. UPDATE em gt_doctotransporte (vlrtotal, vlrreceber, impbasecalculo)
4. Retorna novo ID

#### **composicao_atualizar.php** - UPDATE Item
```php
POST /composicao_atualizar.php

ENTRADA:
{
  "id": 456,                // ID do item
  "iddocto": 123,           // Para validar
  "tipocomposicao": 1,
  "valor": 200.00,
  "status": 0
}

SAÍDA:
{
  "sucesso": true,
  "id": 456
}
```

#### **composicao_deletar.php** - DELETE Item
```php
POST /composicao_deletar.php

ENTRADA:
{
  "id": 456                 // ID do item
}

SAÍDA:
{
  "sucesso": true,
  "mensagem": "Item removido. Novo total: R$ 350,00"
}
```

#### **composicao_listar.php** - GET Items
```php
GET /composicao_listar.php?iddocto=123

SAÍDA:
{
  "sucesso": true,
  "itens": [
    {
      "id": 456,
      "iddocto": 123,
      "tipocomposicao": 0,
      "valor": "150.50",
      "status": 0
    },
    ...
  ]
}
```

---

### 4️⃣ **js/formulario.js** - Lógica do Formulário

**Funções Principais:**

```javascript
// Sincronizar hidden inputs com disabled fields
atualizarHiddenInputs()

// Funcionalidades SEFAZ (em desenvolvimento)
emitirDocumento()
consultarSituacao()
cancelarDocumento()
reimprimir()

// Carregar CFOPs dinamicamente
carregarCFOPs()

// Validar e enviar formulário
enviarFormularioComValidacao(form)
```

**Fluxo de Envio:**
```
enviarFormularioComValidacao(form)
  ├─ FormData do formulário
  ├─ Desabilita botão (mostra "Processando...")
  ├─ fetch(action POST)
  ├─ Parse JSON response
  ├─ Se sucesso:
  │  ├─ Mostra modal "Salvo com sucesso"
  │  ├─ Aguarda 3s
  │  └─ Redireciona para edição
  └─ Se erro:
     ├─ Reabilita botão
     ├─ Mostra modal de erro
     └─ Exibe mensagem de erro
```

---

### 5️⃣ **js/composicao.js** - Lógica de Composição

**Tipos de Composição (0-15):**
```javascript
0: 'FRETE PESO'
1: 'FRETE VALOR'
2: 'PEDAGIO'
3: 'GRIS'
4: 'ADV'
5: 'DESPACHO'
6: 'TDE'
7: 'TRT'
8: 'EMEX'
9: 'SEC/CAT'
10: 'COLETA'
11: 'ENTREGA'
12: 'REENTREGA'
13: 'ARMAZENAGEM'
14: 'ESTADIA'
15: 'OUTROS'
```

**State Management (Array Local):**
```javascript
composicaoItems = [
  {
    index: 0,                      // índice local (para render)
    id: null,                      // null = novo, número = do BD
    tipocomposicao: 0,             // 0-15
    valor: 0,                      // decimal
    status: 0,                     // 0=Ativo, 1=Inativo
    novo: true,                    // flag para novo
    modificado: false              // flag para editado
  },
  ...
]

proximoIndexComposicao = 0         // controle de índice
```

**Ciclo de Vida de um Item:**

```
NOVO ITEM:
novo: true
├─ Mostra "Salvar" button
├─ Ao clicar → POST composicao_salvar.php
├─ Recebe ID do servidor
├─ novo: false
└─ Próximos cliques → POST composicao_atualizar.php

ITEM MODIFICADO:
├─ Ao mudar campo → modificado: true
├─ Mostra "Salvar" button
├─ POST composicao_atualizar.php
├─ Recebe confirmação
└─ modificado: false

DELETAR:
├─ Se novo → apenas remove do array local
└─ Se em BD → POST composicao_deletar.php → remove do array
```

---

## <a name="guias-de-manutenção"></a>🔧 Guias de Manutenção

### ✏️ Como Adicionar um Novo Campo

#### Exemplo: Adicionar "Data de Saída"

**1. Adicionar coluna no BD:**
```sql
ALTER TABLE gt_doctotransporte 
ADD COLUMN dt_saida DATE;
```

**2. Editar cad.php - Adicionar input:**
```php
<div class="col-lg-2">
  <div class="form-group">
    <label class="col-form-label" for="dtsaida">Data Saída</label>
    <input type="date" class="form-control" id="dtsaida" 
           name="dtsaida" 
           value="<?php echo isset($dados['dtsaida']) ? $dados['dtsaida'] : '';?>">
  </div>
</div>
```

**3. Editar insert.php - Capturar e validar:**
```php
$dtsaida = isset($_POST['dtsaida']) && !empty($_POST['dtsaida']) 
  ? pg_escape_string($bdcon, $_POST['dtsaida']) 
  : null;

// Na query INSERT/UPDATE:
// ... dt_saida = '$dtsaida' ...
```

**4. Testar:**
- Criar novo documento
- Preencher campo
- Salvar
- Verificar BD

---

### 📝 Como Adicionar um Novo Tipo de Composição

**1. Editar js/composicao.js - Adicionar tipo:**
```javascript
const tiposComposicao = {
  0: 'FRETE PESO',
  1: 'FRETE VALOR',
  // ... tipos existentes ...
  16: 'NOVO TIPO'     // ← adicionar
};
```

**2. Testar:**
- Abrir documento
- Ir para aba "Composição Valores"
- Clicar em "Adicionar"
- Verificar se novo tipo aparece no select

---

### 🔌 Como Integrar com SEFAZ (Futura)

**Estrutura já preparada em js/formulario.js:**

```javascript
// Apenas placeholders atualmente:
emitirDocumento() → alert()
consultarSituacao() → alert()
cancelarDocumento() → alert()
reimprimir() → alert()
```

**Para implementar:**

**1. Criar arquivo sefaz.php:**
```php
<?php
// Integração com API SEFAZ (webservice SOAP/REST)
require('../include/autenticacao.php');

$acao = isset($_GET['acao']) ? $_GET['acao'] : '';

switch($acao) {
  case 'emitir':
    // Chamar API SEFAZ de emissão
    // Retornar número, série, chave, protocolo
    break;
  case 'consultar':
    // Chamar API SEFAZ de consulta
    // Atualizar situação
    break;
  case 'cancelar':
    // Chamar API SEFAZ de cancelamento
    // Atualizar data de cancelamento
    break;
}
```

**2. Editar js/formulario.js:**
```javascript
function emitirDocumento() {
  const idDocto = document.getElementById('id').value;
  
  fetch(`../gt_doctotransporte/sefaz.php?acao=emitir&id=${idDocto}`)
    .then(res => res.json())
    .then(data => {
      if(data.sucesso) {
        // Atualizar campos
        document.getElementById('numerofiscal').value = data.numero;
        document.getElementById('seriefiscal').value = data.serie;
        document.getElementById('chavefiscal').value = data.chave;
        document.getElementById('protocoloaut').value = data.protocolo;
        
        // Mostrar modal de sucesso
      }
    });
}
```

---

### 🎨 Como Alterar Layout/Estilos

**Estilos customizados:** `../css/gt_doctotransporte.css`

**Classes principais:**
```css
.gt_doctotransporte-card      /* Cards de seção */
.gt_doctotransporte-card-header
.gt_doctotransporte-card-body

.card-primary                  /* Cor primária */
.nav-tabs-bordered             /* Abas */
.card-tms                      /* Template (herdado) */
```

**Para alterar cores das abas em cad.php:**
```php
<!-- Cada aba tem cor diferente em border-top -->
<!-- TAB 1 (Documento): #007bff (azul) -->
<!-- TAB 2 (Composição): #17a2b8 (cyan) -->
<!-- TAB 3 (Nota Fiscal): #ffc107 (amarelo) -->
<!-- TAB 4 (SEFAZ): #28a745 (verde) -->
```

---

## <a name="troubleshooting"></a>🐛 Troubleshooting

### Problema 1: Erro 400 ao Salvar Composição
**Causa:** Dados inválidos sendo enviados

**Solução:**
```javascript
// Debug em js/composicao.js:
console.log('Item a salvar:', item);
console.log('ID Documento:', idDocto);
console.log('Valor:', item.valor);

// Verificar em composicao_salvar.php:
// - iddocto > 0
// - valor > 0
// - tipo 0-15
```

---

### Problema 2: Composição não sincroniza com vlrtotal
**Causa:** Função `renderizarComposicao()` não atualiza campos

**Solução:**
1. Verificar em js/composicao.js:
```javascript
// Fim da função renderizarComposicao():
if(document.getElementById('vlrtotal')) {
  document.getElementById('vlrtotal').value = total.toFixed(2);
}
```

2. Verificar em composicao_salvar.php:
```php
// UPDATE gt_doctotransporte deve ter:
// vlrtotal = $totalComposicao
// vlrreceber = $totalComposicao
// impbasecalculo = $totalComposicao
```

---

### Problema 3: Campos Disabled não Salvam
**Causa:** Hidden inputs não estão sincronizados

**Solução:**
1. Verificar em cad.php se todos hidden inputs existem:
```php
<input type="hidden" id="situacao_hidden" name="situacao" ... />
<input type="hidden" id="status_hidden" name="status" ... />
<!-- etc -->
```

2. Verificar chamada de atualizarHiddenInputs():
```javascript
// Em formulario_handlers.php, antes do submit:
document.getElementById('cadform').addEventListener('submit', function() {
  atualizarHiddenInputs();
});
```

---

### Problema 4: Modal de Erro não Aparece
**Causa:** Elemento #modalErro não existe

**Solução:**
1. Verificar em cad.php se modais estão definidas:
```php
<div class="modal fade" id="modalSucesso" ... >
<div class="modal fade" id="modalErro" ... >
```

2. Verificar IDs dos elementos mensagem:
```javascript
document.getElementById('modalErroMensagem')
document.getElementById('modalSucessoMensagem')
```

---

### Problema 5: AJAX retorna HTML ao invés de JSON
**Causa:** Require wrong file ou erro de parsing

**Solução:**
```php
// No início de cada arquivo AJAX:
header('Content-Type: application/json');
ob_start();

require('../include/autenticacao.php');

ob_clean();  // ← IMPORTANTE: limpa output antes

// Resto do código ...

echo json_encode(['sucesso' => false, 'erro' => $msg]);
exit;
```

---

### Problema 6: Permissões Negadas
**Causa:** Usuário sem permissão para ação

**Solução:**
1. Verificar em insert.php:
```php
if($action == 0) {
  validarPermissaoOuRedirecionar($rot, 'criar');
} else {
  validarPermissaoOuRedirecionar($rot, 'editar');
}
```

2. Verificar permissões do usuário em [../include/](../include/):
- usuario.php
- permissaogrupo.php

---

## <a name="padrões-e-convenções"></a>📋 Padrões e Convenções

### Nomenclatura Campos Banco de Dados
```sql
-- Prefixo + Campo
id*                    -- Chave primária
*id                    -- Chave estrangeira (FK)
dt_*                   -- Data/DateTime
vlr_*                  -- Valor monetário
imp_*                  -- Informação imposto
qtd_*                  -- Quantidade
nr_*                   -- Número
tx_*                   -- Taxa/Alíquota
fl_*                   -- Flag (0/1)
st_*                   -- Status (0/1)
```

### Nomenclatura Variáveis JavaScript
```javascript
// camelCase para variáveis
let composicaoItems = [];
let proximoIndexComposicao = 0;

// UPPERCASE para constantes
const tiposComposicao = { ... };

// Prefixos especiais
btn* → buttons
frm* → forms
inp* → inputs
txt* → text areas
sel* → selects
modal* → modals
```

### Nomenclatura Funções PHP
```php
// Verbo + Substantivo
salvarDocumento()
deletarItem()
carregarDados()
validarPermissao()

// Retorna booleano: é*
éValido()
éNovo()
éAtivo()
```

### Nomenclatura Classes CSS
```css
/* Componente + Estado */
.gt_doctotransporte-card
.gt_doctotransporte-card-header
.gt_doctotransporte-card-body

/* BEM (Block Element Modifier) */
.card__header--active
.table__row--disabled
```

### Padrão de Resposta JSON
```javascript
// Sucesso
{
  "sucesso": true,
  "id": 123,
  "mensagem": "Operação realizada",
  "url": "/redirecionar"
}

// Erro
{
  "sucesso": false,
  "erro": "Descrição do erro",
  "codigo": "ERRO_VALIDACAO"
}
```

### Validação de Entrada
```php
// Sempre usar:
pg_escape_string($bdcon, $valor)     // SQL injection
intval($valor)                        // Type casting
isset() && !empty()                   // Existência
filter_var()                          // Validação específica
```

---

## 🔐 Checklist de Segurança

- [ ] Todas as queries usam `pg_escape_string()`
- [ ] Validar permissões no início de cada arquivo
- [ ] Header `Content-Type: application/json` em endpoints
- [ ] `ob_clean()` antes de retornar JSON
- [ ] Inputs escapados antes de usar em SQL
- [ ] Validar tipos de dados (intval, floatval)
- [ ] Mensagens de erro não expõem estrutura do BD
- [ ] Senhas/tokens nunca em console.log
- [ ] CORS headers se necessário

---

## 📞 Suporte e Referências

**Arquivos relacionados:**
- [include/autenticacao.php](../include/autenticacao.php) - Autenticação
- [include/validacaopermissao.php](../include/validacaopermissao.php) - Permissões
- [dm_cfop/select.php](../dm_cfop/select.php) - CFOPs
- [css/gt_doctotransporte.css](../css/gt_doctotransporte.css) - Estilos

**Banco de Dados:**
- Tabela: `gt_doctotransporte`
- Tabela: `gt_doctotransporte_composicao` (relacionada)

**Contato para dúvidas:**
- Backend: Verificar logs em `../logs/`
- Frontend: Console do navegador (F12)
- BD: Verificar em PostgreSQL client

---

**Última Atualização:** 06 de Fevereiro de 2026  
**Versão do Documento:** 2.0  
**Status:** ✅ Completo e Atualizado
