# Admin y Superadmin

Este documento describe los roles privilegiados existentes, sus permisos, las rutas disponibles y las reglas de
autorizacion aplicadas en la API.

## Modelo de roles

Los roles estan definidos en `App\Models\User`:

| Rol          | Constante               | Descripcion                                                                                |
|--------------|-------------------------|--------------------------------------------------------------------------------------------|
| `user`       | `User::ROLE_USER`       | Usuario normal de la aplicacion. No puede entrar por el login admin ni usar rutas admin.   |
| `admin`      | `User::ROLE_ADMIN`      | Usuario privilegiado con permisos granulares registrados en `admin_permissions`.           |
| `superadmin` | `User::ROLE_SUPERADMIN` | Usuario privilegiado raiz. Tiene todos los permisos de administracion por regla de codigo. |

La lista completa de roles permitidos se obtiene con `User::allowedRoles()`.

## Permisos admin

Los permisos admin estan definidos en `App\Models\User` y la lista permitida se obtiene con
`User::allowedAdminPermissions()`.

| Permiso               | Constante                              | Habilita                                                |
|-----------------------|----------------------------------------|---------------------------------------------------------|
| `view_users`          | `User::PERMISSION_VIEW_USERS`          | Listar usuarios desde rutas admin.                      |
| `view_user_sessions`  | `User::PERMISSION_VIEW_USER_SESSIONS`  | Ver sesiones de un usuario desde rutas admin.           |
| `edit_users`          | `User::PERMISSION_EDIT_USERS`          | Editar usuarios con rol `user`.                         |
| `delete_users`        | `User::PERMISSION_DELETE_USERS`        | Eliminar usuarios con rol `user`.                       |
| `suspend_users`       | `User::PERMISSION_SUSPEND_USERS`       | Suspender y reactivar usuarios con rol `user`.          |
| `view_profiles`       | `User::PERMISSION_VIEW_PROFILES`       | Ver perfiles `people_info` y `pets` de un usuario.      |
| `view_profile_images` | `User::PERMISSION_VIEW_PROFILE_IMAGES` | Ver fotografias de perfiles `people_info` y `pets`.     |
| `edit_profiles`       | `User::PERMISSION_EDIT_PROFILES`       | Editar perfiles `people_info` y `pets` de un usuario.   |
| `delete_profiles`     | `User::PERMISSION_DELETE_PROFILES`     | Eliminar perfiles `people_info` y `pets` de un usuario. |
| `manage_admins`       | `User::PERMISSION_MANAGE_ADMINS`       | Crear, actualizar permisos y eliminar admins.           |

Los permisos se guardan en la tabla `admin_permissions`:

| Campo        | Descripcion                                                                                       |
|--------------|---------------------------------------------------------------------------------------------------|
| `id`         | Identificador del registro.                                                                       |
| `user_id`    | Usuario admin al que pertenece el permiso. Tiene foreign key a `users.id` con borrado en cascada. |
| `permission` | Nombre del permiso. Maximo 50 caracteres.                                                         |

La tabla impide permisos duplicados por usuario con un indice unico sobre `user_id` y `permission`.

## Reglas de autorizacion

Todas las rutas de `AdminUserController` y `AdminProfileController`, excepto bootstrap de superadmin, aplican:

| Middleware              | Regla                                           |
|-------------------------|-------------------------------------------------|
| `auth:api`              | Requiere JWT valido.                            |
| `token.version`         | Requiere que la version del token siga vigente. |
| `role:admin,superadmin` | Requiere rol `admin` o `superadmin`.            |

Ademas, cada accion admin aplica un permiso especifico:

| Accion                                 | Permiso requerido     |
|----------------------------------------|-----------------------|
| Crear admin                            | `manage_admins`       |
| Actualizar permisos de admin           | `manage_admins`       |
| Eliminar admin                         | `manage_admins`       |
| Listar usuarios                        | `view_users`          |
| Ver sesiones de usuario                | `view_user_sessions`  |
| Editar usuario (`user`)                | `edit_users`          |
| Eliminar usuario (`user`)              | `delete_users`        |
| Suspender / reactivar usuario (`user`) | `suspend_users`       |
| Ver perfiles de usuario                | `view_profiles`       |
| Ver fotografias de perfiles            | `view_profile_images` |
| Editar perfiles de usuario             | `edit_profiles`       |
| Eliminar perfiles de usuario           | `delete_profiles`     |

`superadmin` no necesita registros en `admin_permissions`: `User::hasPermission()` devuelve `true` automaticamente para
cualquier permiso si el usuario tiene rol `superadmin`.

`admin` si necesita permisos explicitos: `User::hasPermission()` solo devuelve `true` si existe un registro en
`admin_permissions` para el permiso solicitado.

## Reglas para otorgar permisos

Solo pueden crear admins u otorgar permisos a otros admins:

- usuarios con rol `superadmin`, o
- usuarios con rol `admin` y permiso efectivo `manage_admins`.

Las rutas `POST /admin/users` y `PUT /admin/users/{user}/permissions` exigen el middleware `permission:manage_admins`.
Cualquier otro admin recibe `403 Forbidden` aunque tenga permisos como `view_users` o `edit_users`.

La validacion adicional en `AdminUserController::assertGrantablePermissions()` aplica las reglas siguientes cuando la
lista de permisos no esta vacia.

| Actor                       | Puede otorgar                                                                                                                  |
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| `superadmin`                | Cualquier permiso permitido por `User::allowedAdminPermissions()`, incluido `manage_admins`.                                   |
| `admin` con `manage_admins` | Cualquier permiso de `User::allowedAdminPermissions()` **excepto** `manage_admins` (no necesita tenerlos en su propia cuenta). |
| `admin` sin `manage_admins` | No puede crear admins ni actualizar permisos.                                                                                  |

Solo el `superadmin` puede otorgar el permiso `manage_admins` a otro admin. Si un `admin` intenta incluir`manage_admins`
al crear o actualizar permisos, la API responde `403` con`Only superadmin can grant manage_admins permission`.

Un admin puede crear otro admin sin permisos adicionales si ya paso el middleware `manage_admins`, porque la lista de
permisos a otorgar puede venir vacia.

## Autenticacion admin

### POST `/admin/login`

Controlador: `AuthController::adminLogin()`.

Permite login solo para usuarios con rol:

- `admin`
- `superadmin`

Requisitos:

- `email`: requerido, email.
- `password`: requerido, string, minimo 6.
- `remember_me`: opcional, boolean.
- El usuario debe tener password local.
- El rol debe ser `admin` o `superadmin`.
- `email_verified_at` debe estar presente.

Respuesta exitosa: token JWT con estructura comun de login.

Los roles privilegiados no pueden entrar por `/auth/login`, porque ese endpoint solo acepta rol `user`.

## Bootstrap del primer superadmin

### POST `/admin/bootstrap/superadmin`

Controlador: `AdminUserController::bootstrapSuperadmin()`.

Esta ruta no requiere JWT y tiene `throttle:5,1`.

Header requerido:

```http
X-Superadmin-Bootstrap-Token: <token>
```

El token se compara con `config('auth.superadmin_bootstrap_token')`, que viene de la variable de entorno:

```env
SUPERADMIN_BOOTSTRAP_TOKEN=
```

Reglas:

- Solo funciona si no existe ningun usuario con rol `superadmin`.
- Si ya existe un superadmin, responde `403` con `Superadmin already exists`.
- Si el token no existe en config, viene vacio o no coincide, responde `403` con `Forbidden`.
- El superadmin creado queda con `email_verified_at` marcado automaticamente.
- No se crean registros en `admin_permissions` para superadmin.

Body:

```json
{
  "name": "Root User",
  "email": "root@example.com",
  "phone": "+56911111111",
  "password": "secret123",
  "password_confirmation": "secret123"
}
```

Validaciones:

| Campo      | Reglas                                                 |
|------------|--------------------------------------------------------|
| `name`     | requerido, string, entre 2 y 100 caracteres            |
| `email`    | requerido, string, email, maximo 100, unico en `users` |
| `phone`    | requerido, string, maximo 50                           |
| `password` | requerido, string, confirmado, minimo 6                |

Respuesta exitosa: `201`.

```json
{
  "message": "Superadmin created successfully",
  "user": {
    "role": "superadmin"
  }
}
```

## Rutas admin

Todas estas rutas estan bajo prefijo `/admin`.

| Metodo   | Ruta                                                           | Controlador                                   | Requiere auth | Rol requerido                                    | Permiso requerido                | Descripcion                                                                                 |
|----------|----------------------------------------------------------------|-----------------------------------------------|---------------|--------------------------------------------------|----------------------------------|---------------------------------------------------------------------------------------------|
| `POST`   | `/admin/login`                                                 | `AuthController::adminLogin`                  | No            | `admin` o `superadmin` validado por credenciales | Ninguno                          | Login de usuarios privilegiados.                                                            |
| `POST`   | `/admin/bootstrap/superadmin`                                  | `AdminUserController::bootstrapSuperadmin`    | No            | Ninguno                                          | Token de bootstrap               | Crea el primer superadmin.                                                                  |
| `GET`    | `/admin/users`                                                 | `AdminUserController::listUsers`              | Si            | `admin` o `superadmin`                           | `view_users`                     | Lista hasta 50 usuarios, opcionalmente filtrados por email.                                 |
| `GET`    | `/admin/users/{user}/sessions`                                 | `AdminUserController::userSessions`           | Si            | `admin` o `superadmin`                           | `view_user_sessions`             | Lista hasta 50 sesiones del usuario indicado.                                               |
| `GET`    | `/admin/users/{user}/profiles`                                 | `AdminProfileController::listProfiles`        | Si            | `admin` o `superadmin`                           | `view_profiles`                  | Lista perfiles `people_info` y `pets` del usuario.                                          |
| `PUT`    | `/admin/users/{user}`                                          | `AdminUserController::updateUser`             | Si            | `admin` o `superadmin`                           | `edit_users`                     | Actualiza un usuario con rol `user`.                                                        |
| `DELETE` | `/admin/users/{user}`                                          | `AdminUserController::deleteUser`             | Si            | `admin` o `superadmin`                           | `delete_users` o `manage_admins` | Elimina un `user` (`delete_users`) o un `admin` (`manage_admins`). No elimina `superadmin`. |
| `POST`   | `/admin/users/{user}/suspend`                                  | `AdminUserController::suspendUser`            | Si            | `admin` o `superadmin`                           | `suspend_users`                  | Suspende un usuario con rol `user`.                                                         |
| `POST`   | `/admin/users/{user}/unsuspend`                                | `AdminUserController::unsuspendUser`          | Si            | `admin` o `superadmin`                           | `suspend_users`                  | Reactiva un usuario suspendido.                                                             |
| `GET`    | `/admin/users/{user}/people/{peopleInfo}/images`               | `AdminProfileController::listPeopleImages`    | Si            | `admin` o `superadmin`                           | `view_profile_images`            | Lista fotografias de un perfil `people_info`.                                               |
| `GET`    | `/admin/users/{user}/people/{peopleInfo}/images/{peopleImage}` | `AdminProfileController::showPeopleImage`     | Si            | `admin` o `superadmin`                           | `view_profile_images`            | Devuelve el archivo de imagen.                                                              |
| `PUT`    | `/admin/users/{user}/people/{peopleInfo}`                      | `AdminProfileController::updatePeople`        | Si            | `admin` o `superadmin`                           | `edit_profiles`                  | Actualiza un perfil `people_info` del usuario.                                              |
| `DELETE` | `/admin/users/{user}/people/{peopleInfo}`                      | `AdminProfileController::deletePeople`        | Si            | `admin` o `superadmin`                           | `delete_profiles`                | Elimina un perfil `people_info` del usuario.                                                |
| `GET`    | `/admin/users/{user}/pets/{pet}/images`                        | `AdminProfileController::listPetImages`       | Si            | `admin` o `superadmin`                           | `view_profile_images`            | Lista fotografias de un perfil `pet`.                                                       |
| `GET`    | `/admin/users/{user}/pets/{pet}/images/{petImage}`             | `AdminProfileController::showPetImage`        | Si            | `admin` o `superadmin`                           | `view_profile_images`            | Devuelve el archivo de imagen.                                                              |
| `PUT`    | `/admin/users/{user}/pets/{pet}`                               | `AdminProfileController::updatePet`           | Si            | `admin` o `superadmin`                           | `edit_profiles`                  | Actualiza un perfil `pet` del usuario.                                                      |
| `DELETE` | `/admin/users/{user}/pets/{pet}`                               | `AdminProfileController::deletePet`           | Si            | `admin` o `superadmin`                           | `delete_profiles`                | Elimina un perfil `pet` del usuario.                                                        |
| `POST`   | `/admin/users`                                                 | `AdminUserController::createAdmin`            | Si            | `admin` o `superadmin`                           | `manage_admins`                  | Crea un usuario con rol `admin` y permisos opcionales.                                      |
| `PUT`    | `/admin/users/{user}/permissions`                              | `AdminUserController::updateAdminPermissions` | Si            | `admin` o `superadmin`                           | `manage_admins`                  | Reemplaza los permisos de un usuario admin.                                                 |

## Detalle de acciones

### Listar usuarios

Ruta: `GET /admin/users`

Query params:

| Parametro | Reglas          | Descripcion                                 |
|-----------|-----------------|---------------------------------------------|
| `email`   | opcional, email | Si viene presente, filtra por email exacto. |

Reglas:

- Requiere rol `admin` o `superadmin`.
- Requiere permiso efectivo `view_users`.
- Devuelve maximo 50 usuarios ordenados por `id` descendente.
- Cada usuario incluye un campo calculado `permissions`.

### Ver sesiones de usuario

Ruta: `GET /admin/users/{user}/sessions`

Reglas:

- Requiere rol `admin` o `superadmin`.
- Requiere permiso efectivo `view_user_sessions`.
- Devuelve maximo 50 sesiones ordenadas por `logged_in_at` descendente.
- Cada sesion incluye `is_active`, calculado como sesion no revocada y no expirada.
- La respuesta incluye el usuario serializado con `permissions`.

### Crear admin

Ruta: `POST /admin/users`

Reglas:

- Requiere rol `admin` o `superadmin`.
- Requiere permiso efectivo `manage_admins`.
- Siempre crea el usuario con rol `admin`.
- Marca `email_verified_at` automaticamente.
- Acepta permisos opcionales, sin duplicados.
- Los permisos enviados deben estar dentro de `User::allowedAdminPermissions()`.
- Si el actor es `admin` con `manage_admins`, puede otorgar cualquier permiso permitido excepto `manage_admins`.
- Si el actor es `superadmin`, puede otorgar cualquier permiso permitido.

Body:

```json
{
  "name": "Support Admin",
  "email": "admin@example.com",
  "phone": "+56933333333",
  "password": "secret123",
  "password_confirmation": "secret123",
  "permissions": [
    "view_users",
    "view_user_sessions"
  ]
}
```

Validaciones:

| Campo           | Reglas                                                          |
|-----------------|-----------------------------------------------------------------|
| `name`          | requerido, string, entre 2 y 100 caracteres                     |
| `email`         | requerido, string, email, maximo 100, unico en `users`          |
| `phone`         | requerido, string, maximo 50                                    |
| `password`      | requerido, string, confirmado, minimo 6                         |
| `permissions`   | opcional, array                                                 |
| `permissions.*` | string, uno de los valores de `User::allowedAdminPermissions()` |

Respuesta exitosa: `201`.

```json
{
  "message": "Admin created successfully",
  "user": {
    "role": "admin",
    "permissions": [
      "view_users",
      "view_user_sessions"
    ]
  }
}
```

### Editar usuario

Ruta: `PUT /admin/users/{user}`

Reglas:

- Requiere permiso efectivo `edit_users`.
- Solo aplica a usuarios con rol `user`; si el objetivo es `admin` o `superadmin`, responde `404`.
- Acepta `name`, `phone` y `email` (mismas reglas que `/user/update`).
- Si cambia el email, limpia `email_verified_at` y envia codigo de verificacion.

### Eliminar usuario o admin

Ruta: `DELETE /admin/users/{user}`

Reglas:

- Para eliminar un `user`: requiere `delete_users` (o ser `superadmin`).
- Para eliminar un `admin`: requiere `manage_admins` (o ser `superadmin`).
- No elimina cuentas `superadmin` (`404 Not found`).
- No permite eliminar la propia cuenta (`403 Forbidden`).
- Elimina imagenes almacenadas, registros de escaneo y datos asociados (misma logica que borrado de cuenta).

Respuesta al eliminar admin: `{"message": "Admin deleted successfully"}`.

### Suspender usuario

Ruta: `POST /admin/users/{user}/suspend`

Reglas:

- Requiere permiso efectivo `suspend_users`.
- Solo aplica a usuarios con rol `user`.
- Si ya esta suspendido, responde `422` con `Account already suspended`.
- Marca `suspended_at`, guarda `suspension_reason` opcional, incrementa `token_version` y revoca todas las sesiones
  activas.
- El usuario no puede iniciar sesion (`403 Account suspended`) ni usar JWT previos (`401 Session expired`).

Body opcional:

```json
{
  "reason": "Policy violation"
}
```

| Campo    | Reglas                                  |
|----------|-----------------------------------------|
| `reason` | opcional, string, maximo 500 caracteres |

Respuesta exitosa: `200`.

```json
{
  "message": "User suspended successfully",
  "user": {
    "is_suspended": true,
    "suspended_at": "2026-05-16T12:00:00.000000Z",
    "suspension_reason": "Policy violation"
  }
}
```

### Reactivar usuario

Ruta: `POST /admin/users/{user}/unsuspend`

Reglas:

- Requiere permiso efectivo `suspend_users`.
- Solo aplica a usuarios con rol `user`.
- Si no esta suspendido, responde `422` con `Account is not suspended`.
- Limpia `suspended_at` y `suspension_reason`.

Respuesta exitosa: `200`.

```json
{
  "message": "User unsuspended successfully",
  "user": {
    "is_suspended": false,
    "suspended_at": null,
    "suspension_reason": null
  }
}
```

### Ver perfiles de usuario

Ruta: `GET /admin/users/{user}/profiles`

Reglas:

- Requiere permiso efectivo `view_profiles`.
- Solo aplica a usuarios con rol `user`.
- Devuelve hasta 50 registros de `people_info` y hasta 50 de `pets`.

Respuesta exitosa: `200`.

```json
{
  "user_id": 12,
  "people": [],
  "pets": []
}
```

### Ver fotografias de perfiles

Rutas:

- `GET /admin/users/{user}/people/{peopleInfo}/images` — requiere `view_profile_images`.
- `GET /admin/users/{user}/people/{peopleInfo}/images/{peopleImage}` — requiere `view_profile_images`; devuelve el JPEG
  almacenado.
- `GET /admin/users/{user}/pets/{pet}/images` — requiere `view_profile_images`.
- `GET /admin/users/{user}/pets/{pet}/images/{petImage}` — requiere `view_profile_images`; devuelve el JPEG almacenado.

Reglas:

- El perfil y la imagen deben pertenecer al `{user}` indicado; si no, `404`.
- Es independiente de `view_profiles`: un admin puede listar perfiles sin ver fotos si no tiene este permiso.

### Editar o eliminar perfiles

Rutas:

- `PUT /admin/users/{user}/people/{peopleInfo}` — requiere `edit_profiles`.
- `DELETE /admin/users/{user}/people/{peopleInfo}` — requiere `delete_profiles`.
- `PUT /admin/users/{user}/pets/{pet}` — requiere `edit_profiles`.
- `DELETE /admin/users/{user}/pets/{pet}` — requiere `delete_profiles`.

Reglas:

- El perfil debe pertenecer al `{user}` indicado; si no, `404`.
- Las validaciones de campos son las mismas que en las rutas `/people` y `/pet` de la app.

### Actualizar permisos de admin

Ruta: `PUT /admin/users/{user}/permissions`

Reglas:

- Requiere rol `admin` o `superadmin`.
- Requiere permiso efectivo `manage_admins`.
- Solo actualiza usuarios con rol `admin`.
- Si el usuario objetivo no es admin, responde `404` con `Not found`.
- Reemplaza todos los permisos actuales del admin objetivo.
- Acepta un array requerido de permisos, sin duplicados.
- Los permisos enviados deben estar dentro de `User::allowedAdminPermissions()`.
- Si el actor es `admin` con `manage_admins`, puede otorgar cualquier permiso permitido excepto `manage_admins`.
- Si el actor es `superadmin`, puede otorgar cualquier permiso permitido.

Body:

```json
{
  "permissions": [
    "view_users",
    "view_user_sessions",
    "manage_admins"
  ]
}
```

Validaciones:

| Campo           | Reglas                                                          |
|-----------------|-----------------------------------------------------------------|
| `permissions`   | requerido, array                                                |
| `permissions.*` | string, uno de los valores de `User::allowedAdminPermissions()` |

Nota: al actualizar permisos con un actor `admin`, si el admin objetivo tenia `manage_admins` y la nueva lista no lo
incluye, ese permiso se elimina (solo un superadmin puede volver a asignarlo).

Respuesta exitosa: `200`.

```json
{
  "message": "Admin permissions updated successfully",
  "user": {
    "role": "admin",
    "permissions": [
      "view_users",
      "view_user_sessions",
      "manage_admins"
    ]
  }
}
```

## Matriz de capacidades

| Accion                                 | `user`    | `admin` sin permiso | `admin` con permiso                                    | `superadmin`                                                     |
|----------------------------------------|-----------|---------------------|--------------------------------------------------------|------------------------------------------------------------------|
| Login en `/auth/login`                 | Si        | No                  | No                                                     | No                                                               |
| Login en `/admin/login`                | No        | Si                  | Si                                                     | Si                                                               |
| Crear primer superadmin                | No aplica | No aplica           | No aplica                                              | No aplica: se usa token bootstrap y solo si no existe superadmin |
| Listar usuarios                        | No        | No                  | Si, con `view_users`                                   | Si                                                               |
| Ver sesiones de usuario                | No        | No                  | Si, con `view_user_sessions`                           | Si                                                               |
| Editar usuario (`user`)                | No        | No                  | Si, con `edit_users`                                   | Si                                                               |
| Eliminar usuario (`user`)              | No        | No                  | Si, con `delete_users`                                 | Si                                                               |
| Eliminar admin                         | No        | No                  | Si, con `manage_admins`                                | Si                                                               |
| Suspender / reactivar usuario (`user`) | No        | No                  | Si, con `suspend_users`                                | Si                                                               |
| Ver perfiles de usuario                | No        | No                  | Si, con `view_profiles`                                | Si                                                               |
| Ver fotografias de perfiles            | No        | No                  | Si, con `view_profile_images`                          | Si                                                               |
| Editar perfiles de usuario             | No        | No                  | Si, con `edit_profiles`                                | Si                                                               |
| Eliminar perfiles de usuario           | No        | No                  | Si, con `delete_profiles`                              | Si                                                               |
| Crear admin                            | No        | No                  | Si, con `manage_admins`                                | Si                                                               |
| Otorgar permisos al crear admin        | No        | No                  | Si, con `manage_admins`, todos excepto `manage_admins` | Cualquier permiso permitido                                      |
| Actualizar permisos de admin           | No        | No                  | Si, con `manage_admins`, todos excepto `manage_admins` | Si                                                               |
| Actualizar permisos de superadmin      | No        | No                  | No                                                     | No por esta ruta; la ruta solo acepta objetivo con rol `admin`   |

## Errores esperados

| Caso                                                    | Codigo | Respuesta                                                         |
|---------------------------------------------------------|--------|-------------------------------------------------------------------|
| Sin JWT en ruta protegida                               | `401`  | `{"error": "Unauthorized"}`                                       |
| Rol incorrecto en ruta admin                            | `403`  | `{"error": "Forbidden"}`                                          |
| Permiso faltante                                        | `403`  | `{"error": "Forbidden"}`                                          |
| Admin intenta otorgar `manage_admins`                   | `403`  | `{"error": "Only superadmin can grant manage_admins permission"}` |
| Bootstrap sin token valido                              | `403`  | `{"error": "Forbidden"}`                                          |
| Bootstrap cuando ya existe superadmin                   | `403`  | `{"error": "Superadmin already exists"}`                          |
| Actualizar permisos de usuario que no es admin          | `404`  | `{"error": "Not found"}`                                          |
| Editar/eliminar usuario o perfil que no es `user`       | `404`  | `{"error": "Not found"}`                                          |
| Admin intenta eliminar su propia cuenta                 | `403`  | `{"error": "Forbidden"}`                                          |
| Login admin con usuario normal o credenciales invalidas | `401`  | `{"error": "Unauthorized"}`                                       |
| Login admin con email no verificado                     | `403`  | `{"error": "Email not verified"}`                                 |
| Login con cuenta suspendida                             | `403`  | `{"error": "Account suspended"}`                                  |
| JWT de cuenta suspendida (version vigente)              | `403`  | `{"error": "Account suspended"}`                                  |
| Suspender cuenta ya suspendida                          | `422`  | `{"error": "Account already suspended"}`                          |
| Reactivar cuenta no suspendida                          | `422`  | `{"error": "Account is not suspended"}`                           |

## Archivos relevantes

| Archivo                                                                          | Responsabilidad                                                              |
|----------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| `app/Models/User.php`                                                            | Define roles, permisos, relaciones y reglas `hasRole()` / `hasPermission()`. |
| `app/Models/AdminPermission.php`                                                 | Modelo de permisos admin.                                                    |
| `app/Http/Controllers/AuthController.php`                                        | Login normal y login admin.                                                  |
| `app/Http/Controllers/AdminUserController.php`                                   | Bootstrap superadmin, usuarios, sesiones, creacion de admins y permisos.     |
| `app/Http/Controllers/AdminProfileController.php`                                | Listado y gestion admin de perfiles `people_info` y `pets`.                  |
| `app/Http/Controllers/Concerns/DeletesUserAccounts.php`                          | Logica compartida de borrado de cuenta y archivos.                           |
| `app/Http/Middleware/EnsureRole.php`                                             | Middleware `role`.                                                           |
| `app/Http/Middleware/EnsurePermission.php`                                       | Middleware `permission`.                                                     |
| `routes/api.php`                                                                 | Definicion de rutas `/admin`.                                                |
| `database/migrations/2026_04_24_120000_add_role_to_users_table.php`              | Agrega columna `role` a `users`.                                             |
| `database/migrations/2026_04_24_130000_create_admin_permissions_table.php`       | Crea tabla `admin_permissions`.                                              |
| `database/migrations/2026_05_15_000001_verify_existing_privileged_users.php`     | Verifica usuarios privilegiados existentes.                                  |
| `database/migrations/2026_05_16_000001_add_suspension_fields_to_users_table.php` | Agrega `suspended_at` y `suspension_reason` a `users`.                       |
| `app/Http/Controllers/Concerns/SuspendsUserAccounts.php`                         | Logica de suspension y revocacion de sesiones.                               |
| `tests/Feature/ApiSecurityTest.php`                                              | Tests de bootstrap, login y permisos admin.                                  |

