# ❓ FAQ - Status e Soft Delete

## O que é Soft Delete?

**Soft delete** significa marcar um registro como deletado sem remover fisicamente do banco de dados.

### Antes (Hard Delete - ❌ ERRADO):
```sql
DELETE FROM dim_motorista WHERE id=123;  -- Registro desaparece para sempre!
```

### Depois (Soft Delete - ✅ CORRETO):
```sql
UPDATE dim_motorista SET status=2 WHERE id=123;  -- Marca como deletado, dados preservados
```

---

## Por que usar Soft Delete?

### 1. **Recuperação de Dados**
Você pode restaurar um registro se alguém deletou por erro.

```sql
-- Restaurar um registro
UPDATE dim_motorista SET status=0 WHERE id=123;
```

### 2. **Auditoria e Histórico**
É possível ver quando algo foi deletado e por quem (se você adicionar `deletado_em` e `deletado_por`).

### 3. **Integridade de Dados**
Evita problemas com chaves estrangeiras em outras tabelas.

### 4. **Conformidade Legal**
Algumas regulamentações exigem que os dados não sejam destruídos.

---

## Como implementar nos CRUDs?

### ✅ Na DDL:
```sql
CREATE TABLE public.dim_novo_modulo (
	id serial4 NOT NULL PRIMARY KEY,
	empresa int4 NOT NULL,
	descricao varchar NOT NULL,
	status int4 DEFAULT 0 NOT NULL,
	CONSTRAINT dim_novo_modulo_pk PRIMARY KEY (id)
);
```

**Importante:** `status int4 DEFAULT 0`

### ✅ No select.php:
```php
$query = "
	SELECT * 
	FROM dim_novo_modulo 
	WHERE empresa=$codempresa 
	AND status != 2
";
```

**Sempre filtrar:** `AND status != 2`

### ✅ No insert.php:
```php
$sql = "INSERT INTO dim_novo_modulo (empresa, descricao, status) VALUES ($empresa, '$descricao', 0)";
// Ou deixar DEFAULT 0
```

**Sempre status=0** na criação

### ✅ No delete.php:
```php
validarPermissaoOuRedirecionar($rot, 'deletar');

$sql = "UPDATE dim_novo_modulo SET status=2 WHERE id=$id AND empresa=$empresa";
pg_query($bdcon, $sql);

echo "<script>alert('Registro excluído com sucesso'); location='index';</script>";
```

**NUNCA:** `DELETE FROM dim_novo_modulo WHERE id=$id;`

### ✅ No cac.php (Formulário):
```php
<div class="form-group">
	<label for="status" class="col-form-label">Status:</label>
	<select class="form-control" id="status" name="status">
		<option value="0" <?php if($dados['status']==0){echo "selected";}?>>Ativo</option>
		<option value="2" <?php if($dados['status']==2){echo "selected";}?>>Excluído</option>
	</select>
</div>
```

---

## Valores de Status

| Valor | Significado | Exemplo |
|-------|-------------|---------|
| `0` | Ativo (Padrão) | Registro novo ou restaurado |
| `2` | Excluído (Soft Delete) | Marcado para exclusão, mas ainda no banco |

**❌ NUNCA use:**
- `1` (confunde com "sim/não")
- `9` ou outros números aleatórios
- `null` (cria ambiguidade)

---

## Restaurar um Registro

### Cenário: "Alguém deletou um motorista por erro!"

#### 1. Ver registros deletados:
```sql
SELECT * FROM dim_motorista WHERE empresa=1 AND status=2;
```

#### 2. Verificar qual é:
```sql
SELECT id, nome, status FROM dim_motorista WHERE id=123;
-- Resultado: id=123, nome="João Silva", status=2
```

#### 3. Restaurar:
```sql
UPDATE dim_motorista SET status=0 WHERE id=123;
```

#### 4. Verificar restauração:
```sql
SELECT * FROM dim_motorista WHERE id=123;
-- Resultado: status muda para 0 (Ativo)
```

---

## Listar Diferentes Estados

### Todos os Ativos:
```sql
SELECT * FROM dim_motorista WHERE empresa=1 AND status=0;
```

### Todos os Deletados:
```sql
SELECT * FROM dim_motorista WHERE empresa=1 AND status=2;
```

### Todos (Ativos + Deletados):
```sql
SELECT * FROM dim_motorista WHERE empresa=1 ORDER BY id;
```

### Contar por Status:
```sql
SELECT 
	status,
	CASE WHEN status=0 THEN 'Ativo' WHEN status=2 THEN 'Excluído' END as desc_status,
	COUNT(*) as total
FROM dim_motorista
WHERE empresa=1
GROUP BY status;
```

---

## Perguntas Frequentes

### P1: "Se eu deletar, o registro realmente desaparece?"

**Não!** O soft delete apenas marca como `status=2`. Os dados continuam no banco.

Para realmente deletar (hard delete), você precisa rodar um script SQL:
```sql
DELETE FROM dim_motorista WHERE id=123 AND status=2;
```

Mas isso é raro. Normalmente você NUNCA deleta fisicamente.

---

### P2: "Como saber quem deletou e quando?"

Adicione campos na DDL:
```sql
CREATE TABLE public.dim_motorista (
	id serial4 PRIMARY KEY,
	empresa int4 NOT NULL,
	nome varchar NOT NULL,
	status int4 DEFAULT 0 NOT NULL,
	deletado_em timestamp,
	deletado_por int4,
	FOREIGN KEY (deletado_por) REFERENCES sis003_usuario(id)
);
```

No delete.php:
```php
$usuario_id = $_SESSION['UsuarioID'];
$sql = "UPDATE dim_motorista SET status=2, deletado_em=CURRENT_TIMESTAMP, deletado_por=$usuario_id WHERE id=$id";
```

Agora você sabe QUEM deletou e QUANDO!

---

### P3: "E se alguém acidentalmente atualizar um campo?"

Soft delete não resolve isso. Para auditoria de UPDATE/DELETE, você precisa:
1. Trigger na tabela
2. Tabela de auditoria (audit log)

Exemplo básico:
```sql
CREATE TABLE dim_motorista_audit (
	audit_id serial PRIMARY KEY,
	id int,
	nome varchar,
	acao varchar,
	data timestamp,
	usuario int
);
```

---

### P4: "Posso usar status para outras coisas?"

**Não!** Reserve `0` e `2` para ativo/excluído apenas.

Se precisar de outros estados (suspenso, inativo, bloqueado), crie outro campo:
```sql
CREATE TABLE public.dim_motorista (
	id serial4 PRIMARY KEY,
	empresa int4 NOT NULL,
	nome varchar NOT NULL,
	status int4 DEFAULT 0 NOT NULL,           -- 0=Ativo, 2=Excluído
	bloqueado boolean DEFAULT false,          -- Adicional: bloqueado/ativo
	suspenso boolean DEFAULT false            -- Adicional: suspenso/ativo
);
```

No select.php:
```php
$query = "SELECT * FROM dim_motorista WHERE empresa=$codempresa AND status != 2 ";
```

---

### P5: "Como transferir para outro banco/backup?"

Como os registros deletados ainda existem, seu backup completo está protegido:

```sql
-- Backup completo (com deletados):
pg_dump -U postgres sagadm > backup_completo.sql

-- Depois restaurar:
psql -U postgres sagadm < backup_completo.sql
```

---

### P6: "Preciso limpar dados antigos deletados?"

Depois de alguns meses/anos, você pode fazer limpeza de "soft deletes":

```sql
-- Ver registros deletados há mais de 1 ano
SELECT * FROM dim_motorista 
WHERE status=2 
AND deletado_em < CURRENT_DATE - INTERVAL '1 year';

-- Deletar fisicamente (HARD DELETE - cuidado!)
DELETE FROM dim_motorista 
WHERE status=2 
AND deletado_em < CURRENT_DATE - INTERVAL '1 year';
```

⚠️ **Faça backup antes de hard delete!**

---

## Resumo Executivo

| Operação | Comando SQL | Efeito | Recuperável |
|----------|-------------|--------|------------|
| Criar | `INSERT INTO dim_motorista (nome) VALUES ('João')` | Novo registro com status=0 | Sim |
| Editar | `UPDATE dim_motorista SET nome='Jose' WHERE id=1` | Altera dados | Sim (com auditoria) |
| Soft Delete | `UPDATE status=2 WHERE id=1` | Marca como deletado, dados preservados | ✅ SIM! |
| Hard Delete | `DELETE FROM dim_motorista WHERE id=1` | Remove permanentemente | ❌ Não! |

---

**Lembre-se:** 

> **Em 99% dos casos, use SOFT DELETE (`UPDATE status=2`). NUNCA use `DELETE FROM` nos CRUDs.**

---

**Última atualização:** 27/01/2026  
**Versão:** 1.0  
**Status:** Produção ✅
