Volver a la wiki

Módulo core/api_help.py — Proxy Help Widget hacia Workspace

Descripción

core/api_help.py es el módulo Django que implementa el proxy HTTP del Help Widget de CreaRack Pro. Actúa como intermediario entre el frontend (panel de ayuda IA) y los servicios externos alojados en workspace.crearack.com:


Funciones clave

_workspace_headers() (helper privado)

Construye los headers HTTP necesarios para llamar a workspace.crearack.com. Desde s58 (commit 881f96f) inyecta también los headers CF Access Service Token cuando están configurados:

def _workspace_headers():
    token = getattr(settings, "WORKSPACE_MCP_TOKEN", "")
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }
    cf_id = getattr(settings, "CF_ACCESS_CLIENT_ID", "")
    cf_secret = getattr(settings, "CF_ACCESS_CLIENT_SECRET", "")
    if cf_id and cf_secret:
        headers["CF-Access-Client-Id"] = cf_id
        headers["CF-Access-Client-Secret"] = cf_secret
    return headers

Comportamiento:

_mcp_call(tool_name, arguments)

Ejecuta una llamada MCP a workspace.crearack.com/api/mcp usando _workspace_headers().

Desde v1.82.1 (#254): el workspace MCP puede responder con HTTP 200 y cuerpo {"error": "..."} cuando la tool falla (p.ej. artículo no encontrado) — resp.raise_for_status() no detecta eso porque el status code es 200. _mcp_call ahora desenvuelve el body, y si es un JSON con clave "error", lanza RuntimeError(f"workspace MCP error: {...}") en vez de devolver el texto tal cual. Cada caller del Help Widget ya sabía convertir esa excepción en un 502 honesto; antes de este fix, el JSON de error viajaba íntegro y se pintaba como si fuera contenido legítimo (ver [[incident—20260823—help-es-json-error-como-articulo]]). Aplica a las 3 llamadas del módulo por igual — blinda el puente MCP entero, no solo el camino de artículos.

_apply_language(data, lang)

Introducida en sesión 137 (2026-06-14). Para lang=es, traduce los títulos de la lista de artículos vía el mapa EN→ES (wiki-es/titles.json) y reescribe los paths wiki/ → wiki-es/ para servir el corpus español; para el resto de idiomas (EN canónico) solo normaliza los category_label legacy que quedan en español.

Desde v1.82.1 (#254): la reescritura de ruta wiki/ → wiki-es/ solo ocurre para un artículo cuyo título está en el mapa de traducción (es decir, que tiene gemelo español confirmado). Antes reescribía la ruta de TODO artículo incondicionalmente, asumiendo una “simetría total” entre corpus EN y ES que dejó de ser cierta en cuanto nacieron artículos EN nuevos sin traducir — el rewrite ciego producía una ruta wiki-es/ inexistente, que el workspace respondía con el payload de error de arriba. Un artículo sin gemelo español ahora se sirve en inglés (degradación elegante) en vez de una ruta rota. Detalle completo del incidente: [[incident—20260823—help-es-json-error-como-articulo]].

help_article(request, path) — endpoint GET /api/help/article

Desde v1.100.0 (T9): solo sirve rutas que casan _HELP_ARTICLE_RE (prefijo wiki/ o, desde v1.132.3, también wiki-es/, seguido de crearack--*.md) — antes de ese filtro, un usuario autenticado podía leer cualquier doc interna del workspace (ADRs, concept--/decision--/incident--, claude-method) pasando su ruta directamente. El filtro original solo contemplaba wiki/ y dejó sin abrir los 69 artículos de la Ayuda en español durante 13 días, porque _apply_language entrega rutas wiki-es/ — ver [[incident—20260914—help-es-whitelist-rechaza-articulos]].


Settings requeridas

SettingEnv varDescripciónDefault
WORKSPACE_MCP_TOKENWORKSPACE_MCP_TOKENBearer token para autenticación MCP""
CF_ACCESS_CLIENT_IDCF_ACCESS_CLIENT_IDCF Access Service Token ID""
CF_ACCESS_CLIENT_SECRETCF_ACCESS_CLIENT_SECRETCF Access Service Token Secret""

Definidas en config/settings/base.py. Propagadas al contenedor web via compose.yml y compose.prod.yml.


Callers del Help Widget (inventario completo)

Endpoint destinoMétodoPropósitoHeaders requeridos
workspace.crearack.com/api/mcpPOSTProxy bib_ask (IA)Bearer + CF Access
workspace.crearack.com/api/biblioteca/wiki-titlesGETTraducciones ENBearer + CF Access
workspace.crearack.com/api/biblioteca/wikiGETLista artículosBearer + CF Access

⚠️ Importante: Todos los callers pasan por _workspace_headers() y, desde v1.82.1, por el guard de payload de error de _mcp_call(). Cualquier cambio de autenticación o de formato de error en workspace.crearack.com debe actualizarse en esos dos puntos únicos.


Historial relevante

VersiónSesiónCambio
v1.132.3ronda 13-09 (task #308, #533)_HELP_ARTICLE_RE acepta también wiki-es/: el filtro T9 solo aceptaba wiki/ y dejaba sin abrir los 69 artículos de la Ayuda en español (13 días). Test de contrato “lo que listo, lo puedo abrir” en EN+ES — ver [[incident—20260914—help-es-whitelist-rechaza-articulos]].
v1.82.1ronda 23-08 (#254)_mcp_call detecta payload {"error": ...} con HTTP 200 y lo convierte en excepción; _apply_language solo reescribe rutas wiki-es/ con gemelo confirmado. Fix de incidente de 9 semanas — ver [[incident—20260823—help-es-json-error-como-articulo]].
Sesión 137 (2026-06-14)—_apply_english → _apply_language(data, lang): nace el soporte de corpus en español (wiki-es/).
v1.0.73 (hotfix)s58_workspace_headers() inyecta CF Access headers. Fix incidente 403 post-s57.
v1.0.73s56Implementación del Informante del Help Widget (+806 LOC)

Relación con CF Access

Desde s57, los endpoints de workspace.crearack.com están protegidos por Cloudflare Access (sin bypass-everyone). Todos los callers — incluidos los Django runtime como este módulo — deben presentar un CF Access Service Token válido (CF-Access-Client-Id + CF-Access-Client-Secret).

Ver el incidente de referencia: [[incident—20260512—cf-access-help-widget-403]].


Véase también

Subir