# Usuários — Gaps, Dívidas e Divergências v5 → v6

> Levantamento de problemas conhecidos, funcionalidades mortas, riscos de
> dados e perguntas em aberto do módulo de usuários.

---

## 1. Bugs e erros conhecidos

### 1.1 [CRÍTICO] Escalada de privilégio via `perfil.store`

`check.route.permission` libera **incondicionalmente** qualquer rota cujo
nome contenha `store`, `update` ou `destroy`
(`v6/app/Http/Middleware/CheckRoutePermission.php:48-52,82-90` — o `in_array`
compara com os **valores** do array `$resourceRoutes`, não com as chaves).

`RoleController@store`
(`v6/app/Http/Controllers/Admin/RoleController.php:53-93`) **não** faz
nenhuma checagem de permissão no corpo. Resultado: **qualquer usuário
autenticado** no CMS pode criar um perfil com permissões arbitrárias
(inclusive `super-admin`? não — o slug é gerado a partir do nome, mas
`perfil.create` etc. sim) e se auto-conceder acesso.

**Correção mínima na v7:** Policy `RolePolicy::create()` + remoção do
middleware ou correção da comparação.

### 1.2 [ALTO] `RoleController@update` zera as permissões ao salvar vazio

`v6/app/Http/Controllers/Admin/RoleController.php:140-151`: quando
`$request->permissions` vem como array vazio, `$roleDate['permissions']`
vira `[]` e `role->fill($roleDate)` **apaga todas as permissões** do perfil.
Salvar o formulário de perfil sem marcar nada destrói o perfil silenciosamente.

### 1.3 [ALTO] Três views referenciadas não existem

| View | Referência | Consequência |
|---|---|---|
| `admin.user.show` | `UserController@show` (linha 171) e `@profile` (466) | `GET /cms/usuario/{id}` → erro "view not found" |
| `admin.user.roles` | `UserController@addRules` (linha 490) | `GET /cms/usuario/{user}/add/roles` → erro |
| `admin.user.profile.edit` | `UserController@editProfile` (linha 475) | erro |

As telas equivalentes existem em `v6/resources/views/admin/user_new/**`
(uma reescrita parcial, com `forms/`, `profile/edit` e `roles`), mas
**nenhum controller** as referencia. A busca por `admin.user_new` em `v6/`
não retorna nenhum resultado.

### 1.4 [MÉDIO] `usuario.addRoles` declarado com o mesmo nome duas vezes

`v6/routes/basepro.php:50` e `:52`. A segunda (sem `{user}`) sobrescreve a
primeira no dicionário de rotas. `route('usuario.addRoles')` resolve para
`/cms/usuario/add/roles`; `addRules($id)` recebe `$id = null`; e a view
`admin.user.roles` não existe (1.3). A funcionalidade está inoperante.

### 1.5 [MÉDIO] `UserController@inactivate` devolve 500 para usuário já inativo

`v6/app/Http/Controllers/Admin/UserController.php:320-331`: se o usuário não
tem ativação, cai no `return response()->json(['erro' => 'Ocorreu um erro! ...'], 500)`.
O correto seria um idempotente 200.

### 1.6 [MÉDIO] `UserController@update` não aborta a edição de `super-admin`

`v6/app/Http/Controllers/Admin/UserController.php:236-240`: dentro do
closure de `DB::transaction`, o `return redirect(...)` é **ignorado** (o
closure não pode retornar a response) e o `exit` na linha seguinte é código
morto. O fluxo continua e o usuário é atualizado. O `flash` também é
perdido, pois a action retorna o redirect de sucesso no fim.

### 1.7 [MÉDIO] `UserController@inactive` pagina só para `super-admin`

Linha 389-391: `->doesntHave('activations')->paginate(16)` para
`super-admin` e `->get()` (sem limite) para os demais. Além disso, a
coleLECTION `$users` **não é usada** pela view (que renderiza um DataTable),
então a paginação é inefetiva.

### 1.8 [BAIXO] `UserController@all` é idêntico a `@active`

Linhas 400-423: ambos usam `has('activations')`. O filtro "Todos" da UI
mostra o mesmo conjunto de "Ativos" no controller; a diferença só aparece
na view SQL `listar_todos_usuarios`.

### 1.9 [BAIXO] Caminhos de asset com barras invertidas

`v6/resources/views/admin/user/index.blade.php` e
`v6/resources/views/admin/user/active.blade.php` usam
`asset('assets\js\custom\contents\usuarios\listar_todos\datatable.js')`.
Em Linux o arquivo não é encontrado.

### 1.10 [BAIXO] `SentinelFilter` usa um perfil inexistente

`v6/app/Library/Menu/Filters/SentinelFilter.php:33`:
`Sentinel::inRole('administrators')` — o perfil real é `administrador`
(sem "s"). O atalho nunca é acionado.

### 1.11 [BAIXO] `has_access()` sem argumento libera tudo

`v6/app/Library/Helper/appHelpers.php:28-30`. API perigosa; na v7 o
argumento deve ser obrigatório.

### 1.12 [BAIXO] `RoleController@show` e `@getAll` têm corpo vazio

`v6/app/Http/Controllers/Admin/RoleController.php:96-99` e `196-199`
retornam `null` (sem view). `GET /cms/perfil/{id}` e
`GET /cms/role/list/all` respondem vazio.

### 1.13 [BAIXO] `GET /cms/usuario/save/rules` cria um perfil

`v6/routes/basepro.php:54`: uma action de criação (`RoleController@store`)
exposta por **GET**, o que permite ser acionada por link (CSRF) e viola
o padrão REST.

### 1.14 [BAIXO] `menuClicks()` escreve a cada visita

`v6/app/Helpers/functions.php:865-871`: um `SELECT` + `UPDATE` em
`menu_orders` por carregamento de página de listagem.

### 1.15 [BAIXO] `UserFactory` aponta para uma classe inexistente

`v6/database/factories/UserFactory.php`: `$factory->define(App\User::class, ...)`.
O model é `App\Admin\User`. A factory não pode ser usada.

---

## 2. Funcionalidades incompletas ou mortas

| Item | Situação |
|---|---|
| `v6/resources/views/admin/user_new/**` (10 arquivos) | Telas reescritas e **nunca referenciadas**. Mortas. |
| `UserController@profile` / `@editProfile` | Sem rota declarada; as views que usariam não existem. |
| `UserController@addRules` | Rota existe (mas com nome duplicado) e a view alvo não existe. |
| `users.permissions` (permissão por usuário) | Coluna e accessor existem (`App\Admin\User`), mas **nenhum** controller escreve esse campo. Recurso não utilizado. |
| `permissions` como tabela de catálogo | É usada só para desenhar as **colunas** da matriz e pelo CRUD de `/cms/permissao`. A autorização real vive no JSON de `roles.permissions`. |
| Tabela `role_permissions` | **Não existe** (a tarefa a citava). Foi substituída pelo JSON em `roles.permissions`. |
| `RoleController@getAll` | Rota `role.listAll` declarada, método vazio. |

---

## 3. Itens da v5 removidos na v6 (e o contrário)

### 3.1 Removidos na v6

| Item v5 | Situação na v6 |
|---|---|
| Nenhum item **do módulo de usuários** foi removido. | — |

A única remoção de rota em todo o `basepro.php` que afeta este dossiê foi
o **nome** da rota de suporte (que pertence ao módulo `suporte`, não a este):
`informacoes-prefeitura` → `informacoes-instituicao`.

### 3.2 Adicionados na v6

| Item | Descrição |
|---|---|
| Tabela `modulos` | Registro de módulos (58 linhas) com `status` de ativação |
| Tela `/cms/modulos` | `Admin\ModulosController` + `admin/modulos/*.blade.php` (novo na v6) |
| `resources.modulo_id` | Liga cada recurso a um módulo |
| `menu_orders.modulo_id` | Liga cada item de menu a um módulo |
| `ModulosServiceProvider` | Injeta `$modulos` nas views do portal e do dashboard |
| `RoleController@edit` passou a filtrar por módulo ativo | Ordena a matriz por `modulo_id` |
| `MenuServiceProvider` filtra por `$menu->modulo->status` | Itens de módulo desativado somem do menu |

### 3.3 Mapa v5 → v6 (módulo `usuarios`)

| Aspecto | v5 | v6 |
|---|---|---|
| `UserController` | 531 linhas | **idêntica** |
| `PermissionController` | 227 linhas | **idêntica** |
| `RoleController@edit` | `Resource::whereNotIn(...)->get()` | `Resource::with('modulo')->whereNotIn(...)->orderBy('modulo_id','asc')` |
| `Model/Admin/User.php` | 479 linhas | **idêntica** |
| Views `admin/user/**` | 7 arquivos | **idênticos** |
| Views `admin/role/**` | 4 arquivos | **idênticos** |
| Views `admin/permission/**` | 5 arquivos | **idênticos** |
| `check.route.permission` | idêntico | idêntico |
| `has_access()` | idêntico | idêntico |
| Autorização de `store`/`update`/`destroy` | quebrada | **ainda quebrada** (não corrigida na v6) |
| Escalada de privilégio em `perfil.store` | presente | **ainda presente** |
| `modulos` / filtro por módulo | inexistente | **novo** |

**Conclusão:** o módulo de usuários é, em essence, o **mesmo código** na v5
e na v6. A v6 apenas adicionou a camada de registro de módulos por cima. A
reconstrução em Laravel moderno é, portanto, a oportunidade de corrigir as
falhas estruturais (itens 1.1 a 1.6) sem quebra de equivalência funcional.

---

## 4. Riscos de dados (migração de schema)

| Risco | Detalhe | Mitigação |
|---|---|---|
| JSON → tabela | `roles.permissions` guarda `true` **e** `false`; só as entradas `true` viram linhas | migrar `true` e registrar as `false` |
| Chaves órfãs | O perfil `administrador` (seed) contém chaves cujo recurso não existe na base atual: `site.*`, `midias.*`, `menu.*`, `pessoa-fisica.*`, `pessoa-juridica.*`, `set-status.*` | log de chaves ignoradas durante a migração |
| `role_users` sem FK | Só tem PK composta; `softDeletes` permite duplicatas "apagadas" | recriar com FK + unicidade |
| `activations` → coluna | O estado ativo/inativo é derivado de uma tabela sem `deleted_at` | migrar para `users.is_active` |
| Duplicidade de `users.email` | O índice único garante unicidade, mas o `SoftDeletes` impede reutilizar o e-mail de um usuário excluído | decidir: liberar ou não |
| `permissions.id` fora de sequência | Os ids vão de 2 a 10 | recriar a sequência antes de inserir novas ações |
| `resources` x `permissions` | 79 x 9 = 711 combinações, das quais poucas são usadas | consolidar em "capacidades" (`usuario.listar`, ...) |

---

## 5. Perguntas em aberto para o negócio

1. **Perfil por usuário (`users.permissions`) deve ser suportado?** Se sim,
   a v7 precisa de uma tela para conceder permissões individuais; se não, a
   coluna deve ser removida.
2. **O catálogo de permissões (`/cms/permissao`) é administrável de verdade?**
   Hoje ele é editável, mas as permissões **não** são lidas de forma
   estruturada em lugar nenhum além das colunas da matriz. Criar uma
   permissão nova não dá capacidade nova a ninguém.
3. **`super-admin` como perfil editável?** Hoje é protegido contra edição
   por não-super-admin, mas o próprio `super-admin` **pode** editá-lo
   (`RoleController@update` mantém o slug `super-admin` e aceita novo JSON
   de permissões — o que, num `Gate::before`, é inofensivo, mas na lógica
   `has_access()` também).
4. **O perfil `administrador` (seed) deve ser o padrão das novas prefeituras?**
   Ele traz um JSON fixo de permissões que já diverge do catálogo atual.
5. **Deve existir um "meu perfil" para o operador?** Hoje `admin.user.profile.edit`
   não existe, embora a rota de perfil exista no AdminLTE
   (`config/adminlte.php:87` aponta para `/cms/user/profile` — que **não
   existe** como rota!). Verificar: `config/adminlte.php:87` define
   `'profile' => '/cms/user/profile'`, mas nenhuma rota com esse path foi
   declarada em `v6/routes/basepro.php`.
6. **A matriz de permissões deve incluir os módulos desativados?** Hoje
   não (filtro `$resource->modulo->status`), o que torna impossível
   pré-configurar permissões de um módulo que será ativado depois.

---

## 6. Checklist de correção (priorizado)

| Prioridade | Item | Arquivo |
|---|---|---|
| P0 | Corrigir `check.route.permission` (comparação de array) | `v6/app/Http/Middleware/CheckRoutePermission.php:48-52` |
| P0 | Checagem de permissão no corpo de `RoleController@store`/`@update`/`@destroy` | `v6/app/Http/Controllers/Admin/RoleController.php` |
| P0 | Confirmar/criar as views `admin.user.show`, `admin.user.roles`, `admin.user.profile.edit` (ou remover os métodos) | `v6/resources/views/admin/user/` |
| P1 | Preservar permissões quando a matriz vem vazia | `v6/app/Http/Controllers/Admin/RoleController.php:140-151` |
| P1 | Corrigir o `return`/`exit` dentro da transação | `v6/app/Http/Controllers/Admin/UserController.php:236-240` |
| P1 | Idempotência no `inactivate` | `v6/app/Http/Controllers/Admin/UserController.php:320-331` |
| P2 | Remover o nome duplicado `usuario.addRoles` | `v6/routes/basepro.php:50-53` |
| P2 | Corrigir as barras invertidas nos assets | `v6/resources/views/admin/user/index.blade.php`, `active.blade.php` |
| P2 | Corrigir `SentinelFilter` (`administrators` → `administrador`) | `v6/app/Library/Menu/Filters/SentinelFilter.php:33` |
| P2 | Apagar ou ligar `v6/resources/views/admin/user_new/**` | — |
| P3 | Corrigir `UserFactory` (`App\User` → `App\Admin\User`) | `v6/database/factories/UserFactory.php` |
| P3 | Corrigir `inactive`/`all` (paginação e filtro) | `v6/app/Http/Controllers/Admin/UserController.php:387-423` |
| P3 | Trocar `GET /cms/usuario/save/rules` por POST | `v6/routes/basepro.php:54` |
