Resumen
Plan completado en 3 entregas (v1.52.0, v1.53.0, v1.54.0 · 2026-07): importación moderna de stencils Visio directamente en el editor de racks, con soporte a ficheros de fabricante reales (Cisco, Dell, Eaton, MikroTik) y calidad de renderizado mejorada.
Cambio arquitectónico principal (PR 3: v1.54.0)
Históricamente los ficheros .vss (binary OLE2, stencils antiguos de fabricante) se convertían a través de una cadena legacy EMF → LibreOffice → PNG que dejaba shapes casi vacíos. El QA de fabricante (Eaton-Racks.vss) reveló que un rack 42U solo renderizaba taladros y logo.
Solución: Los .vss ahora usan el mismo conversor libvisio-ng que los modernos .vsdx/.vsd, con metadatos de calidad (nombre real del master, altura en U, media anchura) extraídos en paralelo mediante vss2raw. La conversión es asíncrona (worker Huey), con indicador de progreso en el UI modal.
Artefactos retirados: convert_vss_masters() (~150 LOC de cadena EMF/LibreOffice) y flujo diferido vss_index del confirm endpoint.
Entregas (v1.52.0 → v1.54.0)
PR 1: v1.52.0 — Motor de conversión Visio
- Integración de libvisio-ng (Visio moderno a SVG).
- Soporte a
.vsdx,.vsd,.vsd2003(ZIP-based). - Motor de extracción de masters con sanitización SVG (sin scripts,
onload, path traversal). - Tests del motor: 18/18 en verde.
PR 2: v1.53.0 — UI del preview y renombrado
- Modal de importación: preview de masters en grid.
- Renombrado y categorización por shape (estante, PDU, switch, etc.).
- Conversión síncrona (acceso inmediato, ficheros pequeños).
- Tests: 18/18 del motor + integración con preview.
PR 3: v1.54.0 — QA con ficheros reales + modernización de .vss
- Suite QA en Docker (
tests/qa/test_visio_real_vendor_files.py): 8/8 en verde.- Cisco UCS Servers (.vssx 47 MB / .vss 87 MB).
- Eaton Racks/UPS (.vss).
- Dell IO Cards (.vssx).
- MikroTik CRS312, diagramas de red (.vsdx).
- Conversión asíncrona para
.vss(worker Huey): imágenes perfectas + spinner + previews. - Metadatos vss2raw casados por número de página.
- Fix de orden numérico (página10 antes de página2 con ≥10 páginas).
- Retiro de cadena EMF/LibreOffice.
Impacto usuario
| Antes | Después |
|---|---|
.vsdx/.vsd convertidos pero .vss casi vacíos | Todos los formatos renderizados perfectamente |
| Conversión síncrona (bloquea UI con ficheros grandes) | Conversión asíncrona con spinner y previews vivos |
| Nombres genéricos “page N” | Nombres reales de master desde el stencil (Eaton: “42U Std 42D Rack”) |
| Metadata = 1U por defecto | Altura en U estimada desde dimensiones de pulgadas |
Criterio de fabricante / Límites honestos
El QA detectó que ficheros reales de servidor (Cisco UCS .vss) superan el límite de 50 MB:
.vssde Cisco UCS: 87 MB (rechazado con error claro).- Alternativa:
.vssxequivalente (47 MB) — la ayuda lo recomienda.
Decisión arquitectónica: El límite se mantiene; el mensaje es transparente. La mayoría de fabricantes modernos publican ambos formatos.
Técnica
Endpoints públicos
POST /api/racks/visio/analyze
- Acepta ficheros
.vsdx,.vsd,.vss. - Límite: 50 MB.
- Devuelve
session_id+ lista de masters (nombre, u_height, preview SVG si disponible).
GET /api/racks/visio/session/{session_id}
- Polling para conversiones asincrónicas.
- Estados:
processing,done,error. - Una vez
done, devuelve masters finales con SVGs sanitizados.
POST /api/racks/visio/confirm
- Importa masters seleccionados a la librería del tenant.
- Crea
Stencilrecords con FK aOrganization.
Servicio: convert_visio_async (racks/tasks.py)
Tarea Huey que realiza:
- Invocación de libvisio-ng:
.vss/.vsdx/.vsd→ carpeta temporal con SVGs (1 por página). - Extracción de metadatos (solo
.vss): llama aVisioParser.extract_vss_metadata()para extraer nombre real de master + dimensiones. - Orden numérico de páginas: sortea SVG por página_number (no lexicográfico) para mantener alineación con metadatos.
- Sanitización SVG: elimina scripts,
onload, path traversal; válida geometría real (no solo root<svg>). - Persistencia de sesión: escribe masters en estado JSON temporal; limpia carpeta tras confirm.
Parser: VisioParser.extract_vss_metadata() (racks/utils/visio_parser.py)
- Llama a
vss2raw(libvisio-tools): extrae metadatos de stencil (página = master). - Devuelve lista:
[{"name": "42U Rack", "u_height": 5, "half_width": False, ...}, ...]. - Orden: mismo que libvisio-ng pagina los SVG → alineado automático.
- Rápido: ~1s, sin renderizado de imágenes.
Integraciones
- Modelo
Stencil(racks/models.py):image_path→ SVG en MEDIA_ROOT/uploads/stencils. - Task queue: Huey en modo
db_task()(immediate en tests, async en prod). - Almacenamiento: sesiones temporales en MEDIA_ROOT/temp/{session_id}; librería persistente en MEDIA_ROOT/uploads/stencils.
- Seguridad: RLS en Stencil (FK
organization); path-traversal fix s220.
Testing
Unit tests (tests/api/test_visio_import_v2.py): 18/18
- Motor de conversión
.vsdx/.vsd/.vss. - Metadatos vss2raw casados por página.
- Orden numérico con ≥10 páginas.
- Sanitización SVG (no scripts, no XSS).
QA funcional (tests/qa/test_visio_real_vendor_files.py): 8/8
- Ficheros REALES de Cisco, Dell, Eaton, MikroTik.
- Conversión async + confirmación.
- Skip automático sin ficheros (no en CI).
- Validación de contenido SVG post-sanitización.
Documentación
- Técnica: [[entity—racks—service—convert-visio-async]] (cómo funciona el worker y el parser).
- Usuario: [[crearack—racks—importar-visio]] (pasos en UI para importar, formato recomendado).
- CHANGELOG.md + RELEASE_NOTES.md (v1.54.0).
Véase también
- [[entity—racks—service—convert-visio-async]]
- [[crearack—racks—importar-visio]]
- [[concept—saas—multi-tenancy]]
- [[entity—racks—model—stencil]]
- [[concept—architecture—background-tasks]]