# 10 — Multi-Tenant: Clientes e Isolamento

## Conceito

O Antigravity usa uma arquitetura **multi-tenant com banco de dados por tenant**. Cada cliente (empresa/organização) é completamente isolada — um banco MySQL separado, com seu próprio conjunto de usuários, projetos e tarefas.

A vantagem dessa abordagem:
- Zero risco de vazamento de dados entre clientes
- Cada cliente pode ter configurações completamente diferentes (módulos ativos, nomenclaturas, hierarquia)
- Pode ser feito backup/restore independente por cliente

---

## Estrutura e Anatomia de um Cliente

### 1. Registro no Master DB
```sql
-- antigravity_master.clientes
INSERT INTO clientes (codigo, nome, ativo) VALUES ('acmecorp', 'Acme Corporation', 1);
```

### 2. Banco de Dados Dedicado
```sql
CREATE DATABASE antigravity_acmecorp CHARACTER SET utf8 COLLATE utf8_unicode_ci;
-- Importar a estrutura base
source /path/to/antigravity_test.sql;
```

### 3. Arquivo de Parâmetros
```
webapp/Parametros/acmecorp/parametros.php
```

```php
<?php
$banco_de_dados = 'antigravity_acmecorp';
$S_servidor     = 'localhost';
$S_login        = 'root';
$S_senha        = 'senha_segura_aqui';
```

### 4. Registro de Usuários

**No master:**
```sql
INSERT INTO usuarios_globais (nome, email, senha_hash, ativo) 
VALUES ('João Silva', 'joao@acme.com', MD5('senha'), 1);

INSERT INTO usuario_cliente (usuario_global_id, cliente_id, usuario_id_local, ativo) 
VALUES (1, 2, 5, 1);
-- usuario_id_local = ID do usuário na tabela usuario do BD do cliente
```

**No BD do cliente:**
```sql
INSERT INTO usuario (nome, cpf, login, cargo, divisao_id, admin, ativo) 
VALUES ('João Silva', 'joao@acme.com', 'joao', 0, 1, 0, 1);
```

---

## Fluxo de Inicialização por Request

```
Request: GET /dashboard.php?user_id=5&cliente=acmecorp
                                            ↑
                                     Código do cliente

init_client.php:
  1. $cliente_codigo = 'acmecorp'
  2. include webapp/Parametros/acmecorp/parametros.php
        → $banco_de_dados = 'antigravity_acmecorp'
  3. comunicacaoBD.php → mysqli_connect(localhost, root, senha, 'antigravity_acmecorp')
  4. $_SESSION['S_conn'] = $conn
  5. Endpoint PHP usa $conn para todas as queries

Próximo request com cliente=dev:
  init_client.php:
  → Re-executa com 'dev' → conecta em antigravity_dev
  → ISOLAMENTO TOTAL
```

---

## Clientes Ativos (Configuração do Servidor)

| Código | BD | Pasta de Parâmetros |
|--------|----|---------------------|
| `dev` | `antigravity_dev` | `webapp/Parametros/dev/` |
| `bpoconsig` | `antigravity_bpoconsig` | `webapp/Parametros/bpoconsig/` |
| *(novos)* | `antigravity_{codigo}` | `webapp/Parametros/{codigo}/` |

---

## Autenticação Multi-Tenant

### Pré-Login
```
POST /pre_login.php { email, password }

1. Busca em antigravity_master.usuarios_globais WHERE email=X AND senha_hash=MD5(Y)
2. Busca clientes vinculados:
   SELECT c.* FROM clientes c
   JOIN usuario_cliente uc ON c.cliente_id = uc.cliente_id
   WHERE uc.usuario_global_id = Z AND uc.ativo = 1 AND c.ativo = 1

3. [1 cliente] → action: "direct_login" com { usuario_global_id, cliente }
4. [N clientes] → action: "select_client" com lista de clientes para escolha
```

### Login Completo
```
POST /login.php { usuario_global_id, cliente_codigo }

1. Busca usuario_id_local em usuario_cliente:
   SELECT usuario_id_local FROM usuario_cliente
   WHERE usuario_global_id = X AND cliente_id = Y

2. Busca dados completos do usuário no BD do cliente:
   SELECT * FROM usuario WHERE usuario_id = usuario_id_local

3. Retorna user data + cliente info
```

---

## Usuário em Múltiplos Clientes

Um usuário pode ter acesso a N clientes com IDs diferentes em cada BD:

```
usuarios_globais: { usuario_global_id: 1, email: "ceo@holding.com" }

usuario_cliente:
  { usuario_global_id: 1, cliente_id: 1 (Dev), usuario_id_local: 3 }
  { usuario_global_id: 1, cliente_id: 2 (Empresa A), usuario_id_local: 7 }
  { usuario_global_id: 1, cliente_id: 3 (Empresa B), usuario_id_local: 1 }
```

O usuário vê um modal para seleção do cliente no login quando tem múltiplos.

---

## Sincronização de Usuários

A tela `SettingsUsersScreen` (admin) garante que qualquer criação/edição de usuário seja refletida no master:

| Operação Local | Operação no Master |
|----------------|-------------------|
| Criar usuário | INSERT usuarios_globais (se email novo) + INSERT usuario_cliente |
| Desativar usuário | UPDATE usuario_cliente SET ativo=0 |
| Mudar senha | UPDATE usuarios_globais SET senha_hash=MD5(nova) |

---

## Adicionando Novo Cliente (Checklist)

```bash
# 1. Criar banco de dados
mysql -u root -p
CREATE DATABASE antigravity_novaempresa;
USE antigravity_novaempresa;
SOURCE /path/to/antigravity_test.sql;

# 2. Criar pasta de parâmetros
mkdir -p webapp/Parametros/novaempresa
nano webapp/Parametros/novaempresa/parametros.php
# → Preencher com credenciais do BD

# 3. Registrar no master DB
mysql antigravity_master
INSERT INTO clientes (codigo, nome, ativo) VALUES ('novaempresa', 'Nova Empresa Ltda.', 1);

# 4. Criar tabelas de notificações
# Rodar migrate_notifications_db.php via browser ou PHP CLI

# 5. Criar primeiro usuário admin via SettingsUsersScreen
# (ou INSERT direto no BD)
```
