# Usuários — Resumo Executivo

> **Versão analisada:** `v6` (módulo migrado da `v5`, com acréscimo do registro de módulos)
> **Slug do módulo:** `usuarios` (tabela `modulos`, id 11, `status = true`)
> **Natureza:** CMS (painel administrativo)
> **Estado:** migrado v5 -> v6 (funcionalidade de usuários/perfis/permissões idêntica; a v6 acrescenta o registro de módulos e o filtro por módulo na matriz de permissões)

---

## 1. Objetivo

Administrar quem opera o CMS da prefeitura: cadastro, ativação/inativação e
edição de operadores, definição de **perfis** (roles) e a matriz de
**permissões** que o perfil carrega, além do cadastro de **recursos** (módulos
do sistema) e das **permissões** atômicas (listar, cadastrar, editar, deletar,
inativar, ativar, detalhes, publicar). É a base de toda a autorização do
painel: qualquer tela do CMS consulta `has_access()` antes de renderizar.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Nenhum efeito direto. O módulo é interno ao CMS. |
| Prefeitura (CMS) | Permite separar a operação por departamento, com um perfil "Administrador" padrão e um perfil "super-admin" com acesso irrestrito. |
| Transparência e legalidade | O `activity_log` registra quem criou/editou usuários e perfis, permitindo rastreabilidade de quem alterou permissões. |
| Operação técnica | `has_access()` é o único ponto de checagem de autorização do CMS; `check.route.permission` é o middleware complementar. |

## 3. Comportamento

- Um usuário é identificado pelo **e-mail** (`users.email` é único). O login
  usa `Sentinel::authenticate` (`v6/app/Http/Controllers/Admin/LoginController.php:23`).
- O estado do usuário é derivado da tabela `activations`: usuário **ativo** tem
  registro de ativação concluído; **inativo** não tem.
  Inativar = `Activation::remove($user)`; ativar = `Activation::create()` +
  `Activation::complete()` (`v6/app/Http/Controllers/Admin/UserController.php:314-337`).
- Um usuário pode ter **vários perfis** (tabela pivô `role_users`); a
  autorização efetivo é a **união** das permissões dos perfis
  (`User::createPermissions()` em `v6/app/Http/Model/Admin/User.php:449-465`).
- As permissões de um perfil são gravadas como **JSON** na coluna
  `roles.permissions` (não existe tabela `role_permissions`). A chave é
  `<recurso-slug>.<permissao-slug>`, ex.: `usuario.index`, `usuario.create`.
- A matriz de permissões é montada cruzando a tabela `resources` (linhas) com a
  tabela `permissions` (colunas) — 8 colunas atômicas + `publish`.
- `super-admin` ignora toda checagem: `has_access()` retorna `true` para
  qualquer chave (`v6/app/Library/Helper/appHelpers.php:34-36`).
- O perfil `super-admin` é **protegido**: usuários não-super-admin não podem
  listá-lo, editar usuários que o possuam, nem atribuí-lo
  (`v6/app/Http/Controllers/Admin/UserController.php:60-63,196-200,311-317`).
- A listagem de usuários é alimentada por **views SQL** (`listar_usuarios`,
  `listar_todos_usuarios`, `listar_usuarios_inativos`), não por consultas
  Eloquent diretas.

## 4. Como o Usuário Interage

- Menu lateral do CMS: **Usuários > Listar / Editar Meu Usuário / Perfis /
  Recursos / Permissões** (`v6/app/Providers/MenuServiceProvider.php:336-356`).
- Telas: `/cms/usuario` (lista com filtros Todos/Ativos/Inativos),
  `/cms/usuario/create`, `/cms/usuario/{id}/edit`, `/cms/perfil` (lista de
  perfis), `/cms/perfil/create`, `/cms/perfil/{id}/edit` (matriz de
  permissões), `/cms/permissao`, `/cms/recurso`.
- Tabela com DataTables (Yajra) alimentada por AJAX em `/cms/datatable/*`.
- Ações de linha: ativar/inativar (POST `/cms/usuario/{id}/status`), editar,
  inativar (DELETE `/cms/usuario/{id}/inactivate`), restaurar
  (GET `/cms/usuario/{id}/restore`).
- Ao salvar um usuário, o CMS grava um registro em `activity_log` com o
  detalhe (id, nome, perfis, autor da ação).

## 5. Detalhes e Particularidades Técnicas

- Camadas: `Route` -> `check.logged` / `check.route.permission` ->
  `Admin\UserController` / `Admin\RoleController` / `Admin\PermissionController`
  -> `Sentinel` (papéis) + Eloquent (`User`, `Role`, `Permissions`, `Resource`)
  -> tabelas `users`, `roles`, `role_users`, `permissions`, `resources`.
- **Não há Repository** para este módulo: o acesso ao Sentinel é feito
  diretamente nos controllers.
- `has_access($access)` aceita string ou array; array vira
  `Sentinel::check()->hasAnyAccess($access)`.
- `check.route.permission` (v6/app/Http/Middleware/CheckRoutePermission.php)
  deriva a permissão do **nome da rota** e de segmentos da URL; a lista de
  rotas "abertas" está embutida no middleware.
- O contador de cliques de menu (`menuClicks('usuario')`) grava em
  `menu_orders.clicks` e ordena o menu do CMS.
- Dependências: `cartalyst/sentinel` 2.0.*, `spatie/laravel-activitylog` ^2.8,
  `yajra/laravel-datatables` ^1.5.

## 6. Estrutura de Dados

| Tabela | Papel |
|---|---|
| `users` | Usuários do CMS (Sentinel) |
| `roles` | Perfis; `permissions` em JSON |
| `role_users` | Pivô usuário <-> perfil |
| `permissions` | 9 permissões atômicas (catálogo) |
| `resources` | Recursos/módulos do sistema (linhas da matriz) |
| `modulos` | Registro de módulos (58 linhas na v6, 1 slug duplicado) |
| `activations` | Estado ativo/inativo do usuário |
| `menu_orders` | Slug do menu + contador de cliques |

Views SQL: `listar_usuarios`, `listar_todos_usuarios`,
`listar_usuarios_inativos`, `perfis`, `permissoes`, `recursos`.

## 7. Como Testar

- Login com perfil sem `usuario.index` deve ver o item "Usuários" ausente do
  menu lateral.
- Criar usuário com perfil `super-admin` selecionado por um não-super-admin
  deve ser bloqueado com a mensagem "Você não tem permissão para criar usuário
  com o perfil selecionado.".
- Inativar um usuário já inativo deve devolver HTTP 500 com
  `{"erro": "Ocorreu um erro! ..."}` (comportamento atual, ver
  `08-GAPS-E-DIVIDAS.md`).
- Conceder `usuario.index` a um perfil deve fazer o item aparecer no menu.

## 8. Migração para Laravel Moderno

Substituir o Sentinel por `spatie/laravel-permission` ou Gates nativos;
modelar `users`, `roles`, `permissions` e `role_users` como tabelas normais
(pivô com chave composta); transformar `roles.permissions` (JSON) em linhas de
`role_has_permission`; criar `FormRequest` (`StoreUserRequest`,
`UpdateUserRequest`, `StoreRoleRequest`); criar `UserPolicy`/`RolePolicy` no
lugar de `has_access()`; mover a matriz de permissões para um formulário
POST com checkboxes; expor `GET /api/users`, `GET /api/roles`,
`GET /api/permissions` com API Resources.

## 9. Resumo Geral

O módulo "Usuários" é o centro de autorização do CMS. O login é feito por
e-mail contra `cartalyst/sentinel`; a autorização é calculada a partir de
perfis (`roles`) que carregam um JSON de permissões no formato
`<recurso>.<permissão>`. A checagem é feita em duas camadas: o helper global
`has_access()` dentro dos controllers/views e o middleware
`check.route.permission`, que infere a permissão a partir do nome da rota.
A listagem de usuários, perfis, permissões e recursos é servida por DataTables
alimentados por views SQL, não por Eloquent. Há falhas relevantes: o
middleware concede acesso incondicionalmente a rotas cujo nome contenha
`store`, `update` ou `destroy`; o `RoleController@store` não checa permissão
própria (escalada de privilégio); e as views `admin.user.show`,
`admin.user.roles` e `admin.user.profile.edit` não existem, quebrando três
ações do controller.

---

## Índice do dossiê

| Arquivo | Conteúdo |
|---|---|
| `00-RESUMO.md` | Este documento |
| `01-ARQUITETURA.md` | Camadas, classes e o diagrama de fluxo |
| `02-MODELAGEM.md` | Estrutura de dados detalhada |
| `03-ROTAS-E-CONTROLADORES.md` | Rotas, controllers, requests, resources |
| `04-VIEWS-E-UX.md` | Telas, componentes, JS, assets |
| `05-REGRAS-E-PORTABILIDADE.md` | Particularidades e armadilhas |
| `06-MIGRACAO-MODERNA.md` | Plano de reconstrução em Laravel moderno |
| `07-TESTES.md` | Estratégia e casos de teste |
| `08-GAPS-E-DIVIDAS.md` | Pendências, riscos, comparativo v5 vs v6 |
| `09-API-VIEWS-E-INFRA.md` | Endpoints REST, API Resources, views Blade modernas, fila/cache/storage (parte 2 da migração) |
