Reportes manuales, bridge y relay
Separa la UI aislada, el adaptador instalado y la autorización del servidor. Un cambio remoto de interfaz no puede conceder capacidades nuevas al host.
En esta página
Primero confirma qué integración aplica
Hay dos caminos distintos: la fábrica gestionada del perfil manual autenticado vigente y el bootstrap local exportado para un host con transporte propio aprobado. La existencia de un export no habilita cualquier proyecto ni proporciona su autenticación.
El endpoint gestionado de configuración actual sirve un perfil específico aprobado y rechaza perfiles sensibles. No es onboarding universal. Las aplicaciones que usan mountFeedbackWidget con transporte propio deben conservar su adaptador aprobado; cualquier selección remota adicional requiere validar un contrato específico.
Si no existe un contrato aprobado para tu aplicación, acuerda con el responsable el transporte, orígenes, scope, límites y teardown antes de montar la UI. No copies claves, permisos o políticas de otro producto.
Qué vive en cada lugar
| Pieza | Responsabilidad |
|---|---|
| Host local | Versión instalada del bootstrap, sesión/organización actual, elegibilidad y techo de captura revisado. |
| Iframe remoto | Interfaz aislada y datos públicos permitidos. No recibe credenciales privadas del relay. |
| Backend propio / relay | Autenticación viva por intento, scope, cuotas, idempotencia y envío autorizado. |
| Configuración central | Selección revisada de versión compatible y políticas dentro del techo instalado; no JS remoto en la página host. |
host-bridge 0.2.1 / relay 0.2.0 · sh
# Bridge: dependencia de la aplicación host, nunca JS remoto en su página. npm install --ignore-scripts ./distribuciones/reks-host-bridge-0.2.1.tgz # Relay: sólo en el servidor que autentica a tus usuarios. npm install --ignore-scripts ./distribuciones/reks-relay-0.2.0.tgz
Fábrica gestionada: conectar los bindings reales
@reks/host-bridge 0.2.1 · typescript
import { mountFeedbackIntegration } from "@reks/host-bridge";
type Bindings = Pick<Parameters<typeof mountFeedbackIntegration>[0],
"currentToken" | "currentBoundary" | "subscribe" |
"configure" | "send" | "status">;
// bindings son funciones de TU adaptador, no helpers suministrados por Reks.
export function attachFeedback(target: HTMLElement, bindings: Bindings) {
const integration = mountFeedbackIntegration({
window,
target,
projectId: "TU_PROYECTO",
widgetOrigin: "https://reportes.example.test",
...bindings,
});
return () => integration.dispose();
}
// configure/send hablan con TU backend autenticado y respetan AbortSignal.
// subscribe debe notificar cambios reales de sesión, organización y elegibilidad.
// currentBoundary devuelve una clave local estable de esa identidad; no se envía
// como telemetría. No instales un captureCeiling que no haya sido aprobado.El ejemplo muestra una frontera de composición, no un backend completo. currentToken/currentBoundary/subscribe pertenecen a tu aplicación. Deben reflejar el límite real de sesión y organización de forma síncrona, también si cambias a un espacio personal con la misma ruta y token.
configure y send deben usar tu backend autenticado, respetar AbortSignal y devolver el contrato correcto. El servidor revisa permisos y estado en cada intento; un bearer del host no entra al iframe. Un callback que devuelve siempre true o una configuración estática no es una integración válida.
Bootstrap local con transporte aprobado
@reks/host-bridge 0.2.1 · typescript
import { mountFeedbackWidget, type WidgetBootstrapOptions } from "@reks/host-bridge";
// options procede del adaptador específico aprobado de TU aplicación.
export function attachApprovedWidget(options: WidgetBootstrapOptions) {
const widget = mountFeedbackWidget(options);
return { open: () => widget.open(), dispose: () => widget.destroy() };
}
// Este ejemplo es una función local, no una API nueva de Reks.
// Valida orígenes/configuración y conecta el teardown síncrono de identidad.
// No reenvíes tokens privados al iframe ni actives un perfil no aprobado.mountFeedbackWidget y WidgetBootstrapOptions están exportados por el paquete privado. El adaptador que los llama sigue siendo dueño de validar configuración/orígenes, fijar el transporte aprobado, limitar la captura y destruir el montaje al cambiar identidad.
No presentes el raw bootstrap como acceso automático a la fábrica gestionada ni como prueba de que un proyecto está activo. Los cambios del adaptador local y su adopción requieren un release de la aplicación.
Configuración y envío desde servidor
@reks/relay 0.2.0 · typescript
import { loadFeedbackIntegration, publicFeedbackConfiguration,
type RelayConnection } from "@reks/relay";
export async function readPublicConfiguration(connection: RelayConnection | null) {
// connection procede de TU servidor: no serializarla al navegador.
const config = await loadFeedbackIntegration(connection, {
projectId: "TU_PROYECTO",
widgetOrigin: "https://reportes.example.test",
});
return config ? publicFeedbackConfiguration(config) : null;
}
// Autentica y comprueba elegibilidad en TU endpoint antes de llamar esta función.
// El envío requiere FeedbackRelay + reserva durable de cuota/idempotencia.
// Este ejemplo de lectura no implementa un backend completo de reportes.FeedbackRelay necesita loadConfiguration y una reserva durable por emisor/reporte antes de enviar. La autenticación, elegibilidad, expiración, revocación, cuotas y conflictos de idempotencia no pueden resolverse con una bandera del navegador. No uses una reserva que siempre autoriza ni logs del cuerpo del reporte.
El texto original de un intento sin cambios conserva submissionId estable; requestId cambia por intento de UI. Un timeout es ambiguo: vuelve a comprobar la sesión antes de reintentar con el mismo contenido. Cambiar el texto no puede reutilizar una confirmación anterior.
Compatibilidad que debes comprobar
| Contrato | Edición verificada |
|---|---|
| Host bridge | @reks/host-bridge 0.2.1; ABI 2. La versión 0.2.0 es histórico, no el recomendado. |
| Relay / cliente API / CLI | 0.2.0, archivos privados separados. |
| Mensajes iframe | Versión neutral 4: host:* / widget:*. No renombrar campos de dominio. |
| Reporte manual | reportProtocol 1; perfiles manual-report-v1, display-context-v1, element-reference-v1, manual-breadcrumbs-v1. |
| Selector nuevo | Sólo X-Reks-Capabilities: host-bridge-v2; no es una credencial. |
| Config de producción | Revision y expiresAt válidos; horizonte máximo 65 s, comprobaciones frescas y teardown por expiración. |
| Widget remoto | 0.4.3 como artefacto verificado de esta edición. Comprueba selección y manifiesto de tu entorno; no lo confundas con activación. |
Headers duales, desconocidos o contradictorios fallan. Los adaptadores antiguos conservan únicamente sus shapes y ABI exactos aprobados. No combines un nombre de header nuevo con un valor legacy ni amplíes perfiles por inferencia.
Qué requiere otro release del consumidor
- Un cambio compatible de UI/selección remota puede usar un release revisado dentro del contrato ya instalado.
- Nueva capacidad host, ABI incompatible, techo de captura mayor o cambio del adaptador requieren revisión y adopción explícita de la aplicación.
- La apertura del footer fuera del iframe necesita el bootstrap con allow-popups; un iframe remoto no puede ampliar el sandbox del host antiguo.
- En logout/cambio de organización, invalida pendientes y drafts antes de volver a montar. dispose/destroy y stop del diagnóstico son responsabilidades distintas.
- La CLI se instala de forma independiente; no necesita redeploy de una aplicación consumidora.