# `application/normalizer.py` ## Propósito Normaliza un JSON de entrada al esquema canónico basado en rutas (paths) seleccionado por el usuario, utilizando un LLM. ## API pública ### `build_canonical_template(paths: list[str]) -> dict` Convierte rutas del tipo `a/b/*/c` en un objeto anidado con listas y `null`, siempre incluyendo `radicado` en la raíz. ### `normalize_to_schema(data: dict, paths: list[str], profile_name: str, model: str | None = None) -> dict | None` Usa un LLM para mapear `data` al template canónico generado por `build_canonical_template`. Retorna `None` si no hay API Key o si el LLM falla. ## Consideraciones - Control de reintentos y timeouts vía `settings.retry` y `settings.api`. - Mantiene `radicado` si estaba presente en el `data` original. - Registra métricas (duración, modelo, base_url) sin exponer contenido sensible. ## Ejemplo ```python from application.normalizer import build_canonical_template, normalize_to_schema paths = ["radicado", "items/*/codigo", "items/*/cantidad"] template = build_canonical_template(paths) normalized = normalize_to_schema({"radicado": "R-1", "items": [{"codigo": "A", "cantidad": 2}]}, paths, profile_name="invoice") ```