CreaRack-SL

Blueprint · Modelo blueprints

Blueprint · Modelo blueprints

Propósito

Blueprint es el canvas infinito (floorplan o topología) sobre el que el Map Editor coloca racks, dibuja anotaciones y traza cables. Contenedor raíz multi-tenancy: cada instancia pertenece a una Organization y nunca cruza fronteras. Soporta soft delete (papelera) mediante deleted_at; los eliminados se ocultan de listados activos sin destruir datos ni relaciones. El campo mode distingue tres usos del mismo canvas: "map" (plano libre, default), "room" (Sala: coloca Filas vía RoomRowPlacement) y "row" (Fila: coloca Racks vía BlueprintPlacement) — el motor Konva es compartido, el modo solo cambia las restricciones de colocación y la UI.

Contrato

Campos:

CampoTipoDefaultNotas
nameCharField(100)—Nombre visible
image_pathCharField(200)""Ruta relativa fondo, con namespacing <org_id>/bp{id}_{slug}_{ts}{ext} desde el fix #252 (2026-08-23) — antes era plana con el nombre de fichero del usuario, lo que permitía colisión y borrado cruzado entre organizaciones. Ver [[incident—20260823—blueprint-fondos-cross-org]]
modeCharField(10)"map""map" (plano libre) / "room" (Sala) / "row" (Fila)
scaleFloatField1.0Factor de escala canvas
bg_opacityFloatField1.0Opacidad fondo (0-1)
show_bgBooleanFieldTrueMostrar/ocultar fondo
routing_modeCharField(20)"manhattan"Algoritmo enrutado cables
dark_modeBooleanFieldFalseTema oscuro
cable_spreadIntegerField12Separación cables paralelos (px)
cable_curvatureFloatField1.0Curvatura cables
cable_widthFloatField2.0Grosor línea cables (px)
sort_orderIntegerField(null)NoneOrden manual en el dashboard
organizationFK(Organization, CASCADE)—Tenant
created_atDateTimeField(auto_now_add)—Creación
deleted_atDateTimeField(null, db_index)—Soft-delete

Métodos:

  • soft_delete() — deleted_at = timezone.now(), persiste con update_fields.
  • restore() — deleted_at = None, persiste.
  • is_deleted (property) — True si deleted_at is not None.
  • __str__() — devuelve name.

Meta:

  • Índice compuesto idx_bp_org_deleted sobre (organization, deleted_at) para acelerar filtro deleted_at__isnull=True.

Borrado seguro del fondo (_remove_bg_file_if_unreferenced, task #252):

blueprints/api/blueprints.py expone _remove_bg_file_if_unreferenced(org, rel_path), usada al reemplazar fondo (update_blueprint_bg), al borrar fondo (delete_blueprint_bg) y al borrado definitivo (trash.py: permanent_delete_blueprint, empty_blueprint_trash). Solo borra un fichero si vive en el espacio de la organización actual (prefijo <org_id>/) y ningún otro Blueprint de esa organización lo referencia — con RLS activo no puede ver referencias de otras organizaciones, así que nunca borra fuera del propio espacio. El comando cleanup_blueprint_backgrounds (management command, ensayo en seco por defecto) limpia a mano los huérfanos legacy que este código no puede tocar. Detalle completo: [[incident—20260823—blueprint-fondos-cross-org]].

Clonado (clone_blueprint, task #253):

El clon conserva mode (antes se perdía, produciendo un “Mapa” vacío al clonar una Sala) y, si mode == "room", replica las RoomRowPlacement de las filas colocadas. Clonar un Blueprint en mode == "row" se rechaza con 400: compartiría los mismos racks en vez de copiarlos (los placements apuntan al mismo Rack); el clon real de una Fila vive en su propia página (clone_rack).

Dependencias entrantes

MóduloArchivoRol
BlueprintServiceblueprints/services/blueprints.pyCRUD: list, get, create, update_placement, bulk_update_placements, update_background
AutoPlanServiceblueprints/services/autoplan.pyCrea racks, placements y anotaciones desde análisis IA
API blueprintsblueprints/api/blueprints.pyREST: listar, crear, clonar, settings, borrar, imagen fondo
API trashblueprints/api/trash.pyPapelera: listar trashed, restaurar, eliminar permanente, vaciar
Backup/Restoreracks/api/export/backup.py, restore.pyExportación e importación de org
Searchcore/api/search.pyBúsqueda global por nombre en tenant
Data integritycore/tasks.pyValida que placements no crucen fronteras de tenant

Dependencias salientes

  • Organization (core.models) — FK CASCADE.
  • BlueprintPlacement (blueprints.models) — reverse placements; posiciona racks.
  • MapAnnotation (blueprints.models) — reverse annotations; paredes, textos, zonas, rack_connection.
  • RoomRowPlacement (blueprints.models) — reverse row_placements (como Sala) / placed_in_rooms (como Fila); posiciona Filas dentro de Salas.
  • Rack (racks.models) — indirecta vía BlueprintPlacement; también referenciado en AutoPlanService.create_blueprint_entities.

Ejemplos

# Crear blueprint nuevo
bp = BlueprintService.create_blueprint(
    organization=org,
    data={"name": "Sala CPD-1", "routing_mode": "manhattan", "dark_mode": True}
)

# Patrón estándar (excluye papelera)
Blueprint.objects.filter(organization=org, deleted_at__isnull=True)

# Mover a papelera y restaurar
bp.soft_delete()
bp.restore()
  • entity--blueprints--model--blueprintplacement — posición (x, y, rotation, style_props) de rack sobre el blueprint.
  • entity--blueprints--model--mapannotation — elementos gráficos: paredes, textos, símbolos, conexiones.
  • entity--racks--model--rack — entidad colocada vía BlueprintPlacement.
  • concept--blueprints--map-editor — frontend canvas infinito que consume los endpoints.
  • concept--blueprints--auto-plan — flujo IA que digitaliza imagen y puebla blueprint.
  • concept--saas--multi-tenancy — el aislamiento por organización que el fix #252 restauró también en el filesystem.
  • incident--20260823--blueprint-fondos-cross-org — incidente de fondos compartidos entre organizaciones y su fix.

Véase también

  • [[entity—blueprints—model—blueprintplacement]]
  • [[entity—blueprints—model—mapannotation]]
  • [[entity—racks—model—rack]]
  • [[concept—blueprints—map-editor]]
  • [[concept—blueprints—auto-plan]]
  • [[concept—saas—multi-tenancy]]
  • [[incident—20260823—blueprint-fondos-cross-org]]