# Usuários — Migração para Laravel Moderno (parte 2)

> Continuação de `06-MIGRACAO-MODERNA.md`. Aqui estão os endpoints REST/JSON
> sugeridos, os API Resources, as views Blade modernas e as decisões de
> fila/cache/storage.

---

## 6. Endpoints REST/JSON sugeridos

| Método | URI | Descrição | Autorização |
|---|---|---|---|
| GET | `/api/users` | lista paginada com filtros `status=active\|inactive\|all` | `usuario.index` |
| POST | `/api/users` | cria usuário + vínculo de perfis | `usuario.create` |
| GET | `/api/users/{user}` | detalhe (com `person`) | `usuario.show` |
| PUT | `/api/users/{user}` | atualiza (inclusive troca de senha) | `usuario.edit` |
| DELETE | `/api/users/{user}` | exclui (soft) | `usuario.delete` |
| POST | `/api/users/{user}/activate` | ativa (`is_active = true`) | `usuario.restore` |
| POST | `/api/users/{user}/deactivate` | inativa (`is_active = false`) | `usuario.inactivate` |
| GET | `/api/roles` | lista perfis com capacidades | `perfil.index` |
| POST | `/api/roles` | cria perfil + capacidades | `perfil.create` |
| PUT | `/api/roles/{role}` | atualiza capacidades | `perfil.edit` |
| DELETE | `/api/roles/{role}` | exclui perfil | `perfil.delete` |
| GET | `/api/permissions` | catálogo de ações | `permissao.index` |
| GET | `/api/resources` | catálogo de recursos | `recurso.index` |
| GET | `/api/modules` | registro de módulos | `modulos` |

O CMS (v7) passa a consumir esses endpoints; a listagem deixa de depender de
views SQL.

---

## 7. API Resources

```php
final class UserResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id'        => $this->id,
            'name'      => $this->name,
            'email'     => $this->email,
            'is_active' => $this->is_active,
            'roles'     => RoleResource::collection($this->whenLoaded('roles')),
            'last_login'=> $this->last_login?->toIso8601String(),
            'created_at'=> $this->created_at?->toIso8601String(),
        ];
    }
}
```

```php
final class RoleResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id'           => $this->id,
            'slug'         => $this->slug,
            'name'         => $this->name,
            'capabilities' => $this->whenLoaded('capabilities', fn () => $this->capabilities->pluck('key')),
        ];
    }
}
```

O campo `capabilities` (lista de chaves) é o substituto direto do JSON
`roles.permissions` e mantém a mesma informação para o front-end.

---

## 8. Views Blade modernas

| Tela legada | v7 |
|---|---|
| `admin/user/index.blade.php` + `list.blade.php` | `<x-data-table endpoint="/api/users" ...>` reutilizável, com abas Todos/Ativos/Inativos |
| `admin/user/form.blade.php` | componente `<x-user-form :user="..." :roles="..." />` |
| `admin/role/form.blade.php` (matriz) | componente `<x-capability-matrix :resources="..." :permissions="..." />` com Alpine.js e `POST` de um array `capabilities[]` |
| `admin/permission/index.blade.php` | listagem simples com Inertia/Livewire |

Sugestão de stack de front: **Livewire 3** ou **Inertia + Vue 3**, com
`<x-capability-matrix>` substituindo o JavaScript imperativo
(`checkAll`, `atualizaCheck`) que hoje vive dentro do Blade.

A busca de "Filtrar menus..." da sidebar
(`v6/resources/views/vendor/adminlte/page.blade.php:452-500`) pode virar um
componente Alpine.

---

## 9. Fila, cache e storage

| Recurso | Situação na v6 | Proposta v7 |
|---|---|---|
| Cache | `ModulosServiceProvider` usa `Cache::rememberForever('modulos')` | manter, mas invalidar com `Cache::forget` em vez de `Cache::pull` |
| Sessão | `StartSession` (grupo `web`) | manter |
| Fila | Nenhuma no módulo | não é necessário |
| Storage | Nenhum arquivo no módulo | não é necessário |
| E-mail | `ForgotPasswordController` usa o mailer do Laravel | migrar para notificações (`Notification::route('mail', ...)`) com `MAIL_MAILER` configurável |
| Senha | Hash do Sentinel | `Hash::make` (bcrypt/argon2) com `password` cast `hashed` |

---

---

## 10. Riscos de equivalência

| Risco | Impacto | Mitigação |
|---|---|---|
| Trocar o formato da chave de permissão | todos os `has_access()` do CMS param de funcionar | manter `<recurso>.<acao>` ou migrar em bloco único com busca global |
| Perder as chaves `false` do JSON | permissões revogadas viram concedidas | migrar apenas entradas `true` e logar as `false` |
| Recriar `activations` como coluna | "inativo" deixa de existir | migrar `is_active` e manter a semântica |
| Esquecer a proteção do `super-admin` | qualquer perfil vira admin | policy + teste dedicado |
| Manter `check.route.permission` | escalada de privilégio persiste | remover o middleware; migrar para Policy |
| O `menuClicks` escrever a cada visita | contenção de escrita no banco | mover para um listener assíncrono ou remover |
| Recursos `site.*`, `midias.*` etc. órfãos | permissões perdidas na migração | logar e mapear para o slug novo |
