Modelo: ScanSession
Descripción
network.ScanSession es el modelo de persistencia para las búsquedas guardadas de Auto-Provision. Reemplaza el almacenamiento en localStorage del navegador, que se perdía al limpiar la caché del navegador o en ciertos reloads.
Atributos
| Campo | Tipo | Descripción |
|---|---|---|
id | BigAutoField (PK) | Identificador único |
organization | FK(Organization) | Referencia a la org propietaria (on_delete=CASCADE) |
created_by | FK(User, nullable) | Usuario que guardó la búsqueda (NULL para Agent JWT). Set to NULL si se elimina el usuario. |
name | CharField(255) | Etiqueta legible del escaneo (p.ej. “10.0.0.0/24”, “Prod-Network”). Requerido. |
profiles | M2M(DeviceProfile) | Perfiles de dispositivo capturados en el escaneo. Blank=True. Si se borra un perfil, desaparece automáticamente de la sesión. |
created_at | DateTimeField(auto_now_add) | Timestamp de creación (UTC). Índice: ["organization", "-created_at"] |
Restricciones y Lógica
Ámbito de Organización
- Todas las búsquedas son privadas a nivel org: un usuario no puede ver búsquedas de otra org.
- Compartida dentro de la org: cualquier miembro con permiso
network.viewve todas las búsquedas de su org (sin filtros porcreated_by).
Límite de 20 por Organización
- Al crear una nueva sesión, se podan automáticamente las más de 20 sesiones antiguas de la org.
- Orden: descendente por
created_at(más recientes primero). - Responsable: lógica en el handler POST (no DBMS trigger).
Integridad Referencial M2M
- Si un
DeviceProfilese borra, se desvincula automáticamente sin eliminar la sesión (gracias aManyToManyFieldestándar). - El recuento (
device_count) se calcula en vivo a partir deprofiles.all().
Metadata de Django
db_table = "scan_sessions"
ordering = ["-created_at"]
indexes = [models.Index(fields=["organization", "-created_at"], name="idx_scansession_org_date")]
verbose_name = "Scan Session"
verbose_name_plural = "Scan Sessions"
Sub-componentes
Representación Serializada (ScanSessionOut)
- Endpoint:
GET/POST /auto-provision/scans - Campos:
id,name,created_at,device_count(calculado en vivo),profile_ids(lista) - Propósito: exposición en API REST
Prefetch en Listados
- El router
GETusaprefetch_related("profiles")para evitar N+1 queries. - El cálculo de
device_countlee de la caché de prefetch, no toca BD.
Migración
Archivo: network/migrations/0048_scansession.py
Fecha: 2026-06-08 13:54
Cambios:
- Crea tabla
scan_sessionscon columnas:id,name,created_at,organization_id,created_by_id, índice compuesto. - Crea tabla de unión M2M
scan_sessions_profiles(scan_session_id,deviceprofile_id).
Historial
- s115 (2026-06-08): Introducido como reemplazo de
localStorage. Cierra Parte 4 de Auto-Provision.
Véase también
- [[entity—network—endpoint—auto-provision-scans]]
- [[entity—network—model—device-profile]]
- [[feature—auto-provision—sesion-115-busquedas-persistidas]]
- [[concept—saas—multi-tenancy]]
- [[concept—auto-provision—ciclo-escaneo]]