Autenticación + RBAC
JWT con refresh tokens · 5 roles diferenciados · permisos por yard (multi-yard nativo, ADR-008).
Autenticación + RBAC
JWT con refresh tokens · 5 roles diferenciados · permisos por yard (multi-yard nativo, ADR-008).
Auditoría inmutable
AuditLog con append-only · timestamp, usuario, IP, payload completo · base para resolución de disputas.
Cumplimiento LFPDPPP
Datos personales del chofer (nombre, licencia) con consentimiento; fotos de inspección con retención controlada.
Despliegue dedicado
Sin multi-tenancy · los datos del cliente viven en su infraestructura · cumple políticas internas del cliente.
El sistema usa JWT (JSON Web Tokens) con refresh tokens. Cada usuario tiene roles por yard — un usuario puede ser Yard Manager en Dulces Nombres y solo Viewer en Saltillo.
Cada acción del sistema se autoriza contra:
Admin o no).UserYardAccess).No se permite ninguna escritura sin un rol explícito en el yard al que pertenece la operación.
Mecánica:
AuthorizationBehavior de MediatR (pipeline behavior) intercepta cada command y valida permiso.UserYardAccess se carga en cada request desde el JWT claims (no DB lookup por request).RevokedTokens table.Roles definidos:
| Rol | Scope | Resumen |
|---|---|---|
Admin | Global | Configuración, catálogos, usuarios |
YardManager | Por yard | Layout, anomalías, fuerza cierres |
Operator | Por yard | Captura entrada/salida, rondín |
GateOperator | Por yard | Vista de caseta, registro rápido |
Viewer | Por yard | Solo lectura |
Cada acción significativa del sistema queda registrada en un AuditLog que no permite borrar ni modificar. Si surge una disputa (“¿quién movió mi trailer?”, “¿desde cuándo está aquí?”, “¿alguien forzó este cierre?”) hay evidencia objetiva inmediata.
Qué se audita:
MovementEvent (entrada, salida, confirmación, corrección, cierre forzado).Política: retención 5 años, alineada con compliance aduanal.
Modelo:
public class AuditLog : IEntity { public Guid Id { get; init; } // immutable public DateTime OccurredAt { get; init; } public Guid UserId { get; init; } public string IpAddress { get; init; } public string ActionType { get; init; } // ej. "MovementEvent.EntryRegistered" public string EntityType { get; init; } public Guid EntityId { get; init; } public string PayloadJson { get; init; } // antes y después public string? Reason { get; init; } // requerido para operaciones sensibles}Garantías:
UPDATE y DELETE sobre la tabla (excepto vía rotación programada al cumplir retención).AuditBehavior de MediatR escribe en la misma transacción del command — atómico.El YMS maneja datos personales del chofer del tractor: nombre y número de licencia. Para esto:
Datos personales identificados:
ShipmentDocument.DriverName, DriverLicense.Controles implementados:
[PersonalData].DELETE /api/admin/personal-data/{userId} para ejercer derecho ARCO (Acceso, Rectificación, Cancelación, Oposición) — rectifica o anonimiza datos del chofer manteniendo el evento operativo.Retención:
| Tipo de dato | Retención |
|---|---|
| Fotos de daños (anomalías) | 5 años — soporte legal ante disputas |
| Fotos de inspección 360° normales | 1 año |
| Audit log | 5 años |
| Datos personales del chofer | 5 años desde último movimiento, después anonimización |
| Canal | Mecanismo |
|---|---|
| Webhook entrante de Samsara | Firma HMAC con secret compartido + idempotencia por EventId |
| Webhook saliente al cliente | Firma HMAC + reintentos con backoff exponencial |
| API REST de consulta | JWT con scope Viewer mínimo + rate limiting por token |
| Tráfico cliente→servidor | HTTPS obligatorio · HSTS · cipher suites modernas |
| Almacenamiento BD | Encryption at rest (TDE de SQL Server) si el cliente lo activa |