# 04 — Backend API

## Estrutura do Backend

```
webapp/api/
├── init_client.php          ← Middleware: bootstrap do tenant
├── master_db_config.php     ← Conexão ao BD master
├── gcs_config.php           ← Google Cloud Storage SDK
├── send_notification.php    ← Helper de push notifications
│
├── pre_login.php            ← Pré-autenticação multi-tenant
├── login.php                ← Login no cliente específico
├── change_password.php      ← Alteração de senha
├── register_push_token.php  ← Registro de token Expo Push
│
├── dashboard.php            ← Contadores do painel
├── tasks.php                ← Lista de tarefas (inbox, execução, etc.)
├── task_actions.php         ← CRUD de tarefas e afazeres
├── task_details.php         ← Detalhes completos de uma tarefa
├── upload_attachment.php    ← Upload de anexo de tarefa (→ GCS)
├── download_attachment.php  ← Download via URL assinada
│
├── project_details.php      ← Detalhes completos de um projeto
├── project_actions.php      ← CRUD de projeto, custos, notas, anexos
├── create_project.php       ← Criação de novo projeto
├── my_projects.php          ← Lista "Meus Projetos" do dashboard
├── upload_project_attachment.php ← Upload de anexo do projeto
├── upload_cost_attachment.php    ← Upload de comprovante de custo
│
├── create_demand.php        ← Criação de demanda rápida
├── demand_actions.php       ← CRUD de demanda rápida
├── demand_details.php       ← Detalhes da demanda rápida
├── demand_list.php          ← Lista de demandas rápidas
├── get_demand_lists.php     ← Listas auxiliares para tela de demanda
│
├── get_notifications.php    ← Lista de notificações do usuário
├── global_search.php        ← Busca global (projetos, tarefas, demandas)
├── acknowledge.php          ← Ciência de conclusão de tarefa/projeto
├── get_users.php            ← Lista de usuários ativos
├── get_project_lists.php    ← Listas auxiliares para criação de projeto
├── system_status.php        ← Status de configuração do sistema
│
└── settings/
    ├── constants.php        ← CRUD de constantes e nomenclaturas
    ├── structures.php       ← CRUD de estrutura organizacional
    ├── users.php            ← CRUD de usuários
    ├── themes.php           ← CRUD de temas de projeto
    ├── cost_categories.php  ← CRUD de categorias de custo
    └── cost_centers.php     ← CRUD de centros de custo
```

---

## Middleware Core

### `init_client.php`
**Propósito:** Incluído no início de todos os endpoints. Resolve o tenant e inicializa a conexão com o BD.

**Fluxo:**
1. Extraí `cliente` de `$_REQUEST` ou do JSON body
2. Armazena o raw body em `$GLOBALS['__raw_input']` (stream lido uma única vez)
3. Inclui `webapp/Parametros/{cliente}/parametros.php` → define credenciais de BD
4. Inclui `funcoes_comum.php` e `comunicacaoBD.php` → abre conexão MySQL
5. Armazena em `$_SESSION['S_conn']`

**Erros retornados:**
- `Parâmetro 'cliente' não fornecido` (HTTP 200, JSON)
- `Arquivo de parâmetros não encontrado para o cliente: X` (HTTP 200, JSON)

---

## Endpoints de Autenticação

### `POST /pre_login.php`
**Propósito:** Verificar credenciais e listar clientes disponíveis para o usuário.

**Request:**
```json
{ "email": "user@empresa.com", "password": "senha123" }
```

**Response (sucesso, 1 cliente):**
```json
{
  "success": true,
  "action": "direct_login",
  "usuario_global_id": 42,
  "cliente": { "cliente_id": 1, "codigo": "dev", "nome": "Empresa Dev" }
}
```

**Response (sucesso, N clientes):**
```json
{
  "success": true,
  "action": "select_client",
  "usuario_global_id": 42,
  "clientes": [ { "cliente_id": 1, "codigo": "dev", "nome": "..." }, ... ]
}
```

---

### `POST /login.php`
**Propósito:** Autenticar usuário no BD do cliente específico e retornar dados da sessão.

**Request (Modo 1 — Multi-tenant):**
```json
{ "usuario_global_id": 42, "cliente_codigo": "dev" }
```

**Response:**
```json
{
  "success": true,
  "user": {
    "usuario_id": 5, "nome": "João Silva", "cargo": "1",
    "divisao_id": 3, "admin": 0, "ativo": 1, ...
  },
  "cliente_codigo": "dev",
  "cliente_nome": "Empresa Dev"
}
```

---

### `POST /change_password.php`
**Propósito:** Alterar senha do usuário, verificando no master DB.

**Request:**
```json
{
  "user_id": 5, "cliente": "dev",
  "current_password": "senha_atual",
  "new_password": "nova_senha"
}
```

---

## Endpoints do Dashboard

### `GET /dashboard.php`
**Propósito:** Retornar contadores para todos os cards do dashboard, baseados no `cargo` do usuário.

**Params:** `user_id`, `cliente`

**Response:**
```json
{
  "success": true,
  "counts": {
    "inbox": 3,
    "execucao": 12,
    "monitoramento": 5,
    "custos": 2,
    "afazeres": 7,
    "demandas": 4,
    "meus_projetos": 8,
    "concluidos": 1
  },
  "user_data": { ... }
}
```

**Lógica de contagem (cargo-based):**

| Card | Cargo 0 | Cargo 1 | Cargo 2 | Cargo 3 | Cargo 4 |
|------|---------|---------|---------|---------|---------|
| INBOX | 0 | tarefas na divisão para distribuir | idem | idem | idem |
| EXECUÇÃO | status 1,2,4 (minha) | status 1,2,3 + 6 (divisão) | status 1,2,5,13 | status 1,2,11,15 | status 1,2,14 |
| MONITORAMENTO | status 3,5,6,9,10... (minhas) | status 9,10,5,11,13,14,15 | status 9,10,11,14,15 | status 9,10,14 | status 9,10 |

---

## Endpoints de Tarefas

### `GET /tasks.php`
**Propósito:** Lista de tarefas filtradas por tipo e cargo.

**Params:** `user_id`, `cliente`, `type`, `filter`

| `type` | Conteúdo |
|--------|----------|
| `inbox` | Tarefas para distribuição na divisão do usuário |
| `execucao` | Tarefas para execução/revisão |
| `monitoramento` | Tarefas em monitoramento |
| `afazeres` | Afazeres (tarefa_todo) atribuídos ao usuário |
| `concluidos` | Tarefas ou projetos com ciência pendente |
| `custos` | Custos aguardando aprovação (por alçada) |

**Params extras:**
- `filter=expiradas` — Tarefas com prazo ultrapassado
- `filter=vencendo` — Tarefas vencendo nos próximos `a_vencer` dias
- `filter=projetos` — (type=concluidos) Mostra projetos concluídos

---

### `POST /task_actions.php`
**Propósito:** Todas as ações de mutação relacionadas a tarefas. Usa `action` como discriminador.

**Parâmetro comum:** `action`, `user_id`, `cliente`

| `action` | Descrição | Parâmetros Específicos |
|----------|-----------|----------------------|
| `create_task` | Cria nova tarefa | `demanda_id`, `descricao`, `usuariodemandado_id` ou `distribuicao=true`, `distribuicao_divisao_id`, `data_inicio`, `prazo` |
| `update_task_status` | Atualiza status | `tarefa_id`, `new_status_id` |
| `update_task_responsible` | Muda responsável | `tarefa_id`, `new_user_id` ou `distribuicao=true`, `distribuicao_divisao_id` |
| `update_task_dates` | Atualiza datas | `tarefa_id`, `data_inicio`, `prazo`, `force_update` |
| `add_todo` | Cria afazer | `tarefa_id`, `descricao`, `assigned_user_id` |
| `toggle_todo` | Toggle status afazer | `tarefa_todo_id` |
| `update_todo` | Atualiza obs do afazer | `tarefa_todo_id`, `observacao` |
| `delete_todo` | Deleta afazer | `tarefa_todo_id` |
| `update_todo_responsible` | Muda responsável do afazer | `tarefa_todo_id`, `new_user_id` |
| `reorder_todo` | Reordena afazer | `tarefa_todo_id`, `tarefa_id`, `direction` (up/down) |
| `add_link` | Adiciona link | `tarefa_id`, `descricao`, `link` |
| `delete_link` | Deleta link | `tarefa_link_id` |
| `add_providence` | Adiciona providência | `tarefa_id`, `descricao` |
| `delete_providence` | Deleta providência | `tarefa_providencia_id` |
| `delete_attachment` | Deleta anexo (físico + BD) | `tarefa_anexo_id` |

**Efeito de `update_task_status` com notificações:**
- status_id 3, 5, 11, 14 → notifica recursos do projeto com o cargo-alvo
- status_id 4, 6, 13, 15 → notifica recursos com cargo-alvo (um nível abaixo)

---

### `GET /task_details.php`
**Propósito:** Detalhes completos de uma tarefa.

**Params:** `tarefa_id`, `user_id`, `cliente`

**Response inclui:** tarefa, providências, afazeres (todos com responsável), historico de status, anexos (com URL assinada do GCS), links, usuários disponíveis para atribuição.

---

## Endpoints de Projetos

### `GET /project_details.php`
**Propósito:** Dados completos de um projeto.

**Params:** `demanda_id`, `user_id`, `cliente`

**Response inclui:** projeto, equipe, all_users, tasks (com status_color), attachments, links, costs (com anexos e aprovações), comments, lists (status, divisões, temas, progress_options, cost_categories, cost_centers)

---

### `POST /project_actions.php`
Gerencia todas as mutações do projeto. Discriminado por `action`.

| `action` | Descrição |
|----------|-----------|
| `update_project_status` | Atualiza status do projeto |
| `update_project_division` | Muda divisão (e auto-adiciona usuários com cargo correspondente) |
| `update_project_progress` | Atualiza progresso (%, demanda_progresso_id) |
| `update_project_description` | Edita descrição/resumo/NUP/OS/orçamento |
| `update_project_dates` | Atualiza datas início/fim do projeto |
| `add_team_member` | Adiciona membro à equipe (INSERT demanda_recursos) |
| `remove_team_member` | Remove membro da equipe (UPDATE status=0) |
| `add_project_comment` | Adiciona nota ao projeto (INSERT demanda_nota) |
| `delete_project_comment` | Deleta nota |
| `add_project_link` | Adiciona link ao projeto |
| `delete_project_link` | Deleta link |
| `add_project_cost` | Adiciona custo (INSERT demanda_custo + autoriza_custo se necessário) |
| `delete_project_cost` | Deleta custo |
| `approve_cost` / `reject_cost` | Aprova/rejeita custo (INSERT autoriza_custo) |
| `delete_project_attachment` | Deleta anexo do projeto (GCS + BD) |
| `conclude_project` | Conclui projeto (status=2 + INSERT demanda_conclusao para equipe) |

---

### `POST /create_project.php`
**Propósito:** Criação de novo projeto.

**Request (multipart/form-data):**
- `descricao`, `resumo`, `divisao_id`, `demanda_tema_id`, `data_inicio`, `prazo`, `user_id`, `cliente`
- Opcional: `links[]` (JSON array), `anexos_file[]` (arquivos para upload no GCS)

---

## Endpoints de Demandas Rápidas

### `POST /create_demand.php`
Cria uma nova `tarefarapida`. Aceita links e arquivos (GCS).

### `POST /demand_actions.php`
Mutações de demanda. Actions: `update_main`, `add_link`, `delete_link`, `add_providencia`, `add_attachment`, `delete_attachment`, `conclude_demand`, `cancel_demand`, `reactivate_demand`.

### `GET /demand_details.php`
Detalhes completos: demanda, providências, links, anexos (URLs assinadas), usuários disponíveis.

### `GET /demand_list.php`
Lista demandas com filtros por status e atribuídas ao/pelo usuário.

---

## Endpoints de Busca e Utilitários

### `GET /global_search.php`
**Params:** `query`, `user_id`, `cliente`

Busca LIKE em: `demanda.descricao+resumo`, `tarefa.descricao`, `tarefarapida.descricao`.

Suporta busca exata com aspas: `"termo exato"` → usa `=` ao invés de `LIKE`.

**Response:**
```json
{
  "success": true,
  "results": {
    "projetos": [...],
    "tarefas": [...],
    "demandas": [...]
  },
  "counts": { "projetos": 3, "tarefas": 12, "demandas": 1 }
}
```

---

### `POST /acknowledge.php`
**Propósito:** Registrar ciência do usuário sobre conclusão de tarefa ou projeto.

**Params:** `type` (`tarefa` ou `projeto`), `id`, `user_id`, `cliente`

---

### `GET /get_notifications.php`
**Params:** `user_id`, `cliente`, `limit` (default 50), `unread_only` (0/1)

Marca como lidas ao listar (a menos que `unread_only=1`).

---

### `POST /register_push_token.php`
**Params:** `user_id`, `token`, `platform`, `cliente`

Faz upsert em `push_tokens` (se token já existe, atualiza `usuario_id`).

---

## Sistema de Configurações (settings/)

Todos os endpoints em `settings/` seguem o padrão:
- `GET` → lista dados
- `POST` com `action=create|update|delete` → mutações
- Requerem `user_id` + `cliente`

| Endpoint | Tabelas gerenciadas |
|----------|---------------------|
| `constants.php` | `constantes`, `categoria_cargo`, nomes de níveis |
| `structures.php` | `divisao`, `coordenacao`, `diretoria`, `estrutura_gerencial_4` |
| `users.php` | `usuario` (local) + sync com `usuarios_globais` + `usuario_cliente` no master |
| `themes.php` | `demanda_tema` |
| `cost_categories.php` | `categoria_custo`, `alcada_custo` |
| `cost_centers.php` | `centro_custo` |

**Atenção especial em `users.php`:**
Ao criar/editar usuário, sincroniza com o master:
- Criação: verifica se email já existe em `usuarios_globais`; se não, cria; depois cria link em `usuario_cliente`
- Edição de `ativo=0`: atualiza `usuario_cliente.ativo=0` no master
- Edição de senha: atualiza `usuarios_globais.senha_hash` no master

---

## Google Cloud Storage (gcs_config.php)

### Configurações
```php
GCS_BUCKET_NAME = 'webgruppo-attachments'
GCS_PROJECT_ID  = 'webgruppo-app'
GCS_KEY_FILE    = /webapp/api/credentials/gcs-key.json
```

### Funções Disponíveis
| Função | Parâmetros | Retorno |
|--------|-----------|---------|
| `uploadToGCS($localPath, $gcsPath, $contentType)` | Caminho local, path no GCS, MIME | `$gcsPath` ou `false` |
| `getSignedUrl($gcsPath, $expirationMinutes=15)` | Path no GCS, minutos de validade | URL string ou `false` |
| `deleteFromGCS($gcsPath)` | Path no GCS | `true` ou `false` |
| `getBucket()` | — | StorageClient bucket instance |

### Convenção de Paths no GCS
```
{cliente}/tarefas/{tarefa_id}/{YYYY-MM-DD_HHhMMmSSs}_{filename}
{cliente}/projetos/{demanda_id}/{timestamp}_{filename}
{cliente}/demandas/{tarefarapida_id}/{timestamp}_{filename}
{cliente}/custos/{demanda_custo_id}/{timestamp}_{filename}
```

---

## Helper de Notificações (send_notification.php)

### `sendPushNotification($conn, $user_ids, $tipo, $titulo, $mensagem, $referencia_id)`

**Fluxo:**
1. Normaliza `$user_ids` para array
2. Grava em `notificacoes` para cada destinatário
3. Busca push_tokens dos destinatários
4. Envia para `https://exp.host/--/api/v2/push/send` em lotes de 100
5. Payload inclui `data.tipo` e `data.referencia_id` para deep link no app

**Tipos:**
| `$tipo` | Cenário |
|---------|---------|
| `tarefa` | Tarefa criada/atribuída |
| `demanda` | Demanda rápida criada |
| `afazer` | Afazer criado para usuário |
| `revisao` | Status de tarefa mudou para revisão ou foi analisada |
