---
name: ops_to_sigma_json
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: pure
signature: "def ops_to_sigma_json(db_path: str) -> dict"
description: "Convierte operations.db al formato JSON de sigma.js/graphology. Lee entities y relations, asigna colores por tipo y calcula tamanio de nodo combinando degree y risk_score."
tags: [graph, sigma, osint, visualization, operations, network]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [json, sqlite3]
params:
  - name: db_path
    desc: "path a operations.db (ej: 'apps/my_analysis/operations.db')"
output: "dict con estructura {nodes: [...], edges: [...]} compatible con sigma.js/graphology. Nodos tienen id, label, color, size, type."
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/datascience/ops_to_sigma_json.py"
---

## Ejemplo

```python
from datascience.ops_to_sigma_json import ops_to_sigma_json

graph = ops_to_sigma_json("apps/my_analysis/operations.db")
print(len(graph["nodes"]))  # numero de entidades
print(len(graph["edges"]))  # numero de relaciones
```

## Notas

Funcion pura en el sentido de que no escribe ningun archivo ni tiene efectos secundarios observables mas alla de abrir y cerrar la conexion SQLite en modo lectura.

COLOR_MAP cubre los tipos de entidad OSINT mas comunes. Tipos desconocidos reciben `#95a5a6` (gris).

El tamanio del nodo (`size`) se calcula en el rango [5, 20]:
- Si la entidad tiene `risk_score` en metadata: `(degree_norm + risk_norm) / 2`
- Si no: `degree_norm` puro
- degree_norm = `min(degree / 50, 1.0)`

La metadata se aplana como atributos adicionales del nodo, sin sobrescribir campos reservados (`label`, `type`, `color`, `size`, `domain`, `status`).
