Profile Management
| Campo | Valor |
|---|---|
| Handler | admin/handlers/profile.go |
| Ruta base | /admin/profile |
| Modelo | user_profiles, user_sessions |
| Estado | Implementado |
Descripción
El módulo de perfil permite a los usuarios administradores gestionar su información personal, avatar, cambio de contraseña, y revisar sesiones activas. Incluye middleware de sesión que actualiza last_seen en cada request.
Endpoints
| Método | Ruta | Acción |
|---|---|---|
| GET | /admin/profile | Ver perfil |
| PUT | /admin/profile | Actualizar perfil |
| POST | /admin/profile/avatar | Subir avatar |
| DELETE | /admin/profile/avatar | Eliminar avatar |
| PUT | /admin/profile/password | Cambiar contraseña |
| GET | /admin/profile/sessions | Listar sesiones activas |
| DELETE | /admin/profile/sessions/:id | Revocar sesión |
Campos
UserProfile
| Campo | Tipo | Descripción |
|---|---|---|
id | UUID | Identificador único |
user_id | UUID | Usuario asociado |
name | string | Nombre completo |
email | string | Email (read-only, viene de auth) |
avatar_url | string | URL del avatar |
phone | string | Teléfono |
timezone | string | Zona horaria |
language | string | Idioma preferido |
created_at | timestamp | Fecha de creación |
updated_at | timestamp | Última actualización |
UserSession
| Campo | Tipo | Descripción |
|---|---|---|
id | UUID | Identificador único |
user_id | UUID | Usuario propietario |
token_hash | string | SHA-256 del JWT |
device | string | Dispositivo detectado |
ip | string | Dirección IP |
last_seen | timestamp | Último request |
expires_at | timestamp | Expiración del token |
created_at | timestamp | Inicio de sesión |
Middleware de Sesión
El SessionMiddleware() se ejecuta en cada request autenticado:
func (h *ProfileHandler) SessionMiddleware() gin.HandlerFunc {
// 1. Extraer user_id del JWT
// 2. Calcular SHA-256 del token
// 3. Detectar dispositivo del User-Agent
// 4. Upsert session (actualiza last_seen)
// 5. Cargar avatar_url en contexto
}
Avatar
- Se almacena en ObjectStorage (S3/GCS)
- Se sirve a través de
/admin/media/proxy/{key} - El avatar_url se setea en el contexto para el header
- Se soportan formatos: JPG, PNG, WebP
- Tamaño máximo: 2MB
Notas
- El email es read-only (viene de la autenticación)
- Las sesiones se auto-actualizan con
last_seenen cada request - Revocar una sesión invalida el JWT (por token_hash)
- El middleware parsea el User-Agent para mostrar dispositivo legible
- La zona horaria y idioma se usan para formatear fechas en la UI