@hostwebhook/platform-contracts 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/servicios/almacenes-vectoriales.d.ts +105 -0
- package/dist/servicios/almacenes-vectoriales.js +26 -0
- package/dist/servicios/aprobaciones-pendientes.d.ts +207 -0
- package/dist/servicios/aprobaciones-pendientes.js +51 -0
- package/dist/servicios/avisos-en-vivo.d.ts +106 -0
- package/dist/servicios/avisos-en-vivo.js +60 -0
- package/dist/servicios/canal-de-stream.d.ts +78 -0
- package/dist/servicios/canal-de-stream.js +5 -0
- package/dist/servicios/conversaciones-del-chat.d.ts +139 -0
- package/dist/servicios/conversaciones-del-chat.js +51 -0
- package/dist/servicios/corridas-programadas.d.ts +29 -0
- package/dist/servicios/corridas-programadas.js +5 -0
- package/dist/servicios/credencial/permiso-sobre-credencial.d.ts +61 -0
- package/dist/servicios/credencial/permiso-sobre-credencial.js +42 -0
- package/dist/servicios/credenciales-del-gateway.d.ts +722 -0
- package/dist/servicios/credenciales-del-gateway.js +114 -0
- package/dist/servicios/cuentas-de-atlassian.d.ts +22 -0
- package/dist/servicios/cuentas-de-atlassian.js +5 -0
- package/dist/servicios/descarga-de-drive.d.ts +74 -0
- package/dist/servicios/descarga-de-drive.js +41 -0
- package/dist/servicios/ejecucion-de-ia.d.ts +81 -0
- package/dist/servicios/ejecucion-de-ia.js +39 -0
- package/dist/servicios/enlaces-de-flujo.d.ts +59 -0
- package/dist/servicios/enlaces-de-flujo.js +27 -0
- package/dist/servicios/ficheros-del-gateway.d.ts +210 -0
- package/dist/servicios/ficheros-del-gateway.js +8 -0
- package/dist/servicios/formas-compartidas.d.ts +57 -0
- package/dist/servicios/formas-compartidas.js +22 -0
- package/dist/servicios/historial-de-corridas.d.ts +75 -0
- package/dist/servicios/historial-de-corridas.js +7 -0
- package/dist/servicios/index.d.ts +57 -0
- package/dist/servicios/index.js +44 -0
- package/dist/servicios/limites-del-plan.d.ts +82 -0
- package/dist/servicios/limites-del-plan.js +41 -0
- package/dist/servicios/motor-de-ejecucion.d.ts +197 -0
- package/dist/servicios/motor-de-ejecucion.js +11 -0
- package/dist/servicios/plantillas-de-origen.d.ts +25 -0
- package/dist/servicios/plantillas-de-origen.js +5 -0
- package/dist/servicios/posts-sociales.d.ts +69 -0
- package/dist/servicios/posts-sociales.js +23 -0
- package/dist/servicios/registro-de-entregas.d.ts +93 -0
- package/dist/servicios/registro-de-entregas.js +46 -0
- package/dist/servicios/registro-de-eventos.d.ts +135 -0
- package/dist/servicios/registro-de-eventos.js +62 -0
- package/dist/servicios/restauracion-de-nodos.d.ts +53 -0
- package/dist/servicios/restauracion-de-nodos.js +4 -0
- package/dist/servicios/salud-del-webhook.d.ts +26 -0
- package/dist/servicios/salud-del-webhook.js +6 -0
- package/dist/servicios/secretos-de-firma.d.ts +26 -0
- package/dist/servicios/secretos-de-firma.js +5 -0
- package/dist/servicios/telemetria.d.ts +114 -0
- package/dist/servicios/telemetria.js +60 -0
- package/dist/servicios/trazas-de-llm.d.ts +79 -0
- package/dist/servicios/trazas-de-llm.js +23 -0
- package/dist/servicios/tuneles.d.ts +106 -0
- package/dist/servicios/tuneles.js +87 -0
- package/dist/servicios/workspace/acceso-al-recurso.d.ts +39 -0
- package/dist/servicios/workspace/acceso-al-recurso.js +5 -0
- package/dist/servicios/zona-horaria-del-usuario.d.ts +40 -0
- package/dist/servicios/zona-horaria-del-usuario.js +7 -0
- package/package.json +9 -3
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las conversaciones de un chat trigger, por repositorio.
|
|
3
|
+
*
|
|
4
|
+
* ## Por qué costó más que las otras trece
|
|
5
|
+
*
|
|
6
|
+
* Las demás costuras invertían un servicio. Ésta y la de entregas invierten el
|
|
7
|
+
* acceso directo a una COLECCIÓN, y ésta además **mutaba el documento vivo**:
|
|
8
|
+
*
|
|
9
|
+
* const existing = await this.conversationModel.findOne({...});
|
|
10
|
+
* existing.messages.push(userMsg);
|
|
11
|
+
* existing.expiresAt = expiresAt;
|
|
12
|
+
* await existing.save();
|
|
13
|
+
*
|
|
14
|
+
* Eso no es una consulta que se pueda mover: es un documento de Mongoose
|
|
15
|
+
* cambiando en memoria y guardándose. Por eso quedó fuera del lote del #468 —
|
|
16
|
+
* cerrarla obliga a decidir de quién es la colección.
|
|
17
|
+
*
|
|
18
|
+
* La respuesta, mirando lo que se hace con ella: es del gateway. El panel
|
|
19
|
+
* lista conversaciones, la retención se administra desde `plans/` con
|
|
20
|
+
* `chatConversationRetentionDays`, y el índice TTL vive en su entidad. El nodo
|
|
21
|
+
* escribe turnos y los vuelve a leer.
|
|
22
|
+
*
|
|
23
|
+
* ## Y de paso arregla algo que ya estaba anotado
|
|
24
|
+
*
|
|
25
|
+
* El llamante de `upsert` tenía este comentario:
|
|
26
|
+
*
|
|
27
|
+
* *«Plainify each entry so we don't leak Mongoose subdocument refs (parent,
|
|
28
|
+
* `$__`, `_doc`, …) into the payload — those circular refs blow up recursive
|
|
29
|
+
* walkers like extractAttachments / template renderers with "Maximum call
|
|
30
|
+
* stack size exceeded"».*
|
|
31
|
+
*
|
|
32
|
+
* O sea que ya se estaba aplanando a mano, después de recibir el documento,
|
|
33
|
+
* porque no hacerlo reventaba. El repositorio devuelve datos planos y ese
|
|
34
|
+
* peligro desaparece en origen en vez de esquivarse en cada llamante.
|
|
35
|
+
*
|
|
36
|
+
* ## ⚠️ Lo que no se puede perder
|
|
37
|
+
*
|
|
38
|
+
* - **`expiresAt` se refresca en CADA turno de usuario.** La ventana de
|
|
39
|
+
* retención rueda con la actividad; sin eso, una sesión larga caduca a mitad
|
|
40
|
+
* de conversación. `null` significa «no caduca» (plan enterprise).
|
|
41
|
+
* - **El dedupe de voz.** Los SDK de voz repiten la transcripción final, así
|
|
42
|
+
* que un turno idéntico al último —mismo rol y mismo contenido recortado— no
|
|
43
|
+
* se añade. Sin eso el transcript sale duplicado.
|
|
44
|
+
* - **Los borradores pendientes son la memoria entre turnos.** Es lo que deja
|
|
45
|
+
* al modelo entender un «confirma» que llega en el turno siguiente.
|
|
46
|
+
*/
|
|
47
|
+
/** Un turno del transcript. `mode` ausente significa texto. */
|
|
48
|
+
export interface MensajeDeConversacion {
|
|
49
|
+
role: string;
|
|
50
|
+
content: string;
|
|
51
|
+
mode?: 'voice';
|
|
52
|
+
}
|
|
53
|
+
/** Un borrador que quedó a medias y espera confirmación. */
|
|
54
|
+
export interface BorradorPendiente {
|
|
55
|
+
draftId: string;
|
|
56
|
+
operation: string;
|
|
57
|
+
subject?: string;
|
|
58
|
+
createdAt: Date;
|
|
59
|
+
}
|
|
60
|
+
/** Una conversación, plana. */
|
|
61
|
+
export interface Conversacion {
|
|
62
|
+
id: string;
|
|
63
|
+
sessionId: string;
|
|
64
|
+
title?: string;
|
|
65
|
+
messages: MensajeDeConversacion[];
|
|
66
|
+
pendingDrafts: BorradorPendiente[];
|
|
67
|
+
createdAt?: Date;
|
|
68
|
+
updatedAt?: Date;
|
|
69
|
+
}
|
|
70
|
+
export interface RepositorioDeConversaciones {
|
|
71
|
+
/** La lista paginada del panel, con su total. */
|
|
72
|
+
listarPorTrigger(triggerId: string, opts: {
|
|
73
|
+
offset: number;
|
|
74
|
+
limit: number;
|
|
75
|
+
}): Promise<{
|
|
76
|
+
datos: Conversacion[];
|
|
77
|
+
total: number;
|
|
78
|
+
}>;
|
|
79
|
+
/** ⚠️ `null` si no existe o no es de ese trigger; el llamante decide el 404. */
|
|
80
|
+
buscarPorId(conversationId: string, triggerId: string): Promise<Conversacion | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Un turno de usuario: lo añade a la sesión, o la crea.
|
|
83
|
+
*
|
|
84
|
+
* ⚠️ `expiresAt` se escribe SIEMPRE, exista ya la conversación o no: es lo
|
|
85
|
+
* que hace rodar la ventana de retención con la actividad.
|
|
86
|
+
*/
|
|
87
|
+
guardarTurnoDeUsuario(params: {
|
|
88
|
+
orgId: string;
|
|
89
|
+
chatTriggerId: string;
|
|
90
|
+
sessionId: string;
|
|
91
|
+
title?: string;
|
|
92
|
+
mensaje: MensajeDeConversacion;
|
|
93
|
+
/** `null` = no caduca. */
|
|
94
|
+
expiresAt: Date | null;
|
|
95
|
+
}): Promise<Conversacion>;
|
|
96
|
+
/**
|
|
97
|
+
* Un turno de voz.
|
|
98
|
+
*
|
|
99
|
+
* ⚠️ Devuelve `anadido: false` cuando el turno es idéntico al último —mismo
|
|
100
|
+
* rol y mismo contenido recortado—. Los SDK de voz repiten la transcripción
|
|
101
|
+
* final y sin eso el transcript sale duplicado.
|
|
102
|
+
*/
|
|
103
|
+
guardarTurnoDeVoz(params: {
|
|
104
|
+
orgId: string;
|
|
105
|
+
chatTriggerId: string;
|
|
106
|
+
sessionId: string;
|
|
107
|
+
title: string;
|
|
108
|
+
mensaje: MensajeDeConversacion;
|
|
109
|
+
expiresAt: Date | null;
|
|
110
|
+
}): Promise<{
|
|
111
|
+
conversationId: string;
|
|
112
|
+
anadido: boolean;
|
|
113
|
+
}>;
|
|
114
|
+
/** La respuesta del asistente, al final del transcript. */
|
|
115
|
+
anadirRespuesta(conversationId: string, content: string): Promise<void>;
|
|
116
|
+
/** Lo que el widget relee al recargar la página a mitad de sesión. */
|
|
117
|
+
historialDeSesion(chatTriggerId: string, sessionId: string): Promise<{
|
|
118
|
+
conversationId: string | null;
|
|
119
|
+
messages: MensajeDeConversacion[];
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Aplica lo que pasó con los borradores en un turno y devuelve cómo quedó.
|
|
123
|
+
*
|
|
124
|
+
* ⚠️ Se quitan los enviados y se añaden los nuevos EN ESE ORDEN, y devuelve
|
|
125
|
+
* los ids resultantes porque el llamante los registra: sin ese log no había
|
|
126
|
+
* forma de averiguar por qué el modelo vio el borrador equivocado en el
|
|
127
|
+
* turno siguiente.
|
|
128
|
+
*/
|
|
129
|
+
aplicarEventosDeBorrador(conversationId: string, cambios: {
|
|
130
|
+
quitar: string[];
|
|
131
|
+
anadir: Array<{
|
|
132
|
+
draftId: string;
|
|
133
|
+
operation: string;
|
|
134
|
+
subject?: string;
|
|
135
|
+
}>;
|
|
136
|
+
}): Promise<string[]>;
|
|
137
|
+
}
|
|
138
|
+
/** ⚠️ Cadena y no `Symbol`, igual que el resto de tokens de la Fase 2. */
|
|
139
|
+
export declare const CONVERSACIONES_DEL_CHAT = "CONVERSACIONES_DEL_CHAT";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Las conversaciones de un chat trigger, por repositorio.
|
|
4
|
+
*
|
|
5
|
+
* ## Por qué costó más que las otras trece
|
|
6
|
+
*
|
|
7
|
+
* Las demás costuras invertían un servicio. Ésta y la de entregas invierten el
|
|
8
|
+
* acceso directo a una COLECCIÓN, y ésta además **mutaba el documento vivo**:
|
|
9
|
+
*
|
|
10
|
+
* const existing = await this.conversationModel.findOne({...});
|
|
11
|
+
* existing.messages.push(userMsg);
|
|
12
|
+
* existing.expiresAt = expiresAt;
|
|
13
|
+
* await existing.save();
|
|
14
|
+
*
|
|
15
|
+
* Eso no es una consulta que se pueda mover: es un documento de Mongoose
|
|
16
|
+
* cambiando en memoria y guardándose. Por eso quedó fuera del lote del #468 —
|
|
17
|
+
* cerrarla obliga a decidir de quién es la colección.
|
|
18
|
+
*
|
|
19
|
+
* La respuesta, mirando lo que se hace con ella: es del gateway. El panel
|
|
20
|
+
* lista conversaciones, la retención se administra desde `plans/` con
|
|
21
|
+
* `chatConversationRetentionDays`, y el índice TTL vive en su entidad. El nodo
|
|
22
|
+
* escribe turnos y los vuelve a leer.
|
|
23
|
+
*
|
|
24
|
+
* ## Y de paso arregla algo que ya estaba anotado
|
|
25
|
+
*
|
|
26
|
+
* El llamante de `upsert` tenía este comentario:
|
|
27
|
+
*
|
|
28
|
+
* *«Plainify each entry so we don't leak Mongoose subdocument refs (parent,
|
|
29
|
+
* `$__`, `_doc`, …) into the payload — those circular refs blow up recursive
|
|
30
|
+
* walkers like extractAttachments / template renderers with "Maximum call
|
|
31
|
+
* stack size exceeded"».*
|
|
32
|
+
*
|
|
33
|
+
* O sea que ya se estaba aplanando a mano, después de recibir el documento,
|
|
34
|
+
* porque no hacerlo reventaba. El repositorio devuelve datos planos y ese
|
|
35
|
+
* peligro desaparece en origen en vez de esquivarse en cada llamante.
|
|
36
|
+
*
|
|
37
|
+
* ## ⚠️ Lo que no se puede perder
|
|
38
|
+
*
|
|
39
|
+
* - **`expiresAt` se refresca en CADA turno de usuario.** La ventana de
|
|
40
|
+
* retención rueda con la actividad; sin eso, una sesión larga caduca a mitad
|
|
41
|
+
* de conversación. `null` significa «no caduca» (plan enterprise).
|
|
42
|
+
* - **El dedupe de voz.** Los SDK de voz repiten la transcripción final, así
|
|
43
|
+
* que un turno idéntico al último —mismo rol y mismo contenido recortado— no
|
|
44
|
+
* se añade. Sin eso el transcript sale duplicado.
|
|
45
|
+
* - **Los borradores pendientes son la memoria entre turnos.** Es lo que deja
|
|
46
|
+
* al modelo entender un «confirma» que llega en el turno siguiente.
|
|
47
|
+
*/
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.CONVERSACIONES_DEL_CHAT = void 0;
|
|
50
|
+
/** ⚠️ Cadena y no `Symbol`, igual que el resto de tokens de la Fase 2. */
|
|
51
|
+
exports.CONVERSACIONES_DEL_CHAT = 'CONVERSACIONES_DEL_CHAT';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lo que el motor necesita del flujo programado. UN método.
|
|
3
|
+
*
|
|
4
|
+
* ## Por qué
|
|
5
|
+
*
|
|
6
|
+
* `pipeline-run` llama a `ScheduledWorkflowsService.recordRun(swId, run)` al
|
|
7
|
+
* terminar una corrida que arrancó en un flujo programado. Es la única
|
|
8
|
+
* llamada: medido.
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ Y NO es un `lastRunAt` que se pueda escribir a mano desde aquí. `recordRun`
|
|
11
|
+
* además archiva la fila en `scheduledworkflowruns` y poda a las últimas cien.
|
|
12
|
+
* Reimplementarlo del lado del motor sería una segunda copia de esa regla.
|
|
13
|
+
*
|
|
14
|
+
* ⚠️ Tiene que TERMINAR antes de que salga el marco `complete`: el panel
|
|
15
|
+
* relee el flujo cuando ese marco llega, así que apuntar después es una carrera
|
|
16
|
+
* que se pierde a veces. Por eso se espera, a diferencia de la salud del
|
|
17
|
+
* webhook.
|
|
18
|
+
*/
|
|
19
|
+
export interface CorridasProgramadas {
|
|
20
|
+
apuntarCorrida(swId: string, corrida: {
|
|
21
|
+
startedAt: Date;
|
|
22
|
+
completedAt: Date;
|
|
23
|
+
durationMs: number;
|
|
24
|
+
status: 'success' | 'partial' | 'failure';
|
|
25
|
+
errorMessage?: string | null;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/** ⚠️ Cadena y no `Symbol`. */
|
|
29
|
+
export declare const CORRIDAS_PROGRAMADAS = "CORRIDAS_PROGRAMADAS";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ¿Puede este usuario poner esta credencial? — la pregunta, sin la respuesta.
|
|
3
|
+
*
|
|
4
|
+
* ## Por qué existe
|
|
5
|
+
*
|
|
6
|
+
* Costura de la Fase 2. `node-controller.factory` aplicaba
|
|
7
|
+
* `@UseGuards(CredentialFolderGuard)` a los ~30 tipos de nodo, y ese guardia
|
|
8
|
+
* vive en `credentials/`: consulta la colección de credenciales y resuelve
|
|
9
|
+
* permisos de carpeta. Con eso, el factory —y con él todos los controladores
|
|
10
|
+
* de nodo— no se puede mudar a `hw-nodes` sin llevarse el dominio entero de
|
|
11
|
+
* credenciales, que es la Fase 4.
|
|
12
|
+
*
|
|
13
|
+
* ## Lo que NO se hace, y por qué
|
|
14
|
+
*
|
|
15
|
+
* Lo fácil era quitar el guardia y decir «ya autoriza el gateway al proxear».
|
|
16
|
+
* Y es defendible: la autenticación va EN el gateway por diseño.
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ Pero este guardia existe **porque la comprobación se olvidó trece
|
|
19
|
+
* veces**. Su propio docblock cuenta el agujero: bastaba con leerle el id de
|
|
20
|
+
* credencial a un nodo que sí se pudiera ver, ponérselo a un nodo propio y
|
|
21
|
+
* ejecutarlo, y la credencial de la carpeta negada se descifraba igual. Y un
|
|
22
|
+
* id de Mongo no es un secreto: sale en el lienzo y en la barra del navegador.
|
|
23
|
+
*
|
|
24
|
+
* Dejar esa garantía viviendo SÓLO en el proxy es apostar a que nada alcance
|
|
25
|
+
* nunca `hw-nodes` por otro camino — una mala configuración, un servicio
|
|
26
|
+
* nuevo, una prueba. Cuando pase, el agujero vuelve, y vuelve callado.
|
|
27
|
+
*
|
|
28
|
+
* Así que la pregunta se queda y lo que se va es la RESPUESTA: `hw-nodes`
|
|
29
|
+
* preguntará por la red privada a quien tenga el dato. Una llamada por
|
|
30
|
+
* escritura de nodo que lleve credencial —crear o editar—, no por ejecución.
|
|
31
|
+
* Un salto interno es ~1 ms contra los 100-500 ms que el nodo gasta llamando
|
|
32
|
+
* a Slack o a Gmail.
|
|
33
|
+
*/
|
|
34
|
+
/** Los tres papeles sobre una carpeta, de menos a más. */
|
|
35
|
+
export type RolDeCarpeta = 'viewer' | 'editor' | 'owner';
|
|
36
|
+
export interface PreguntaDePermiso {
|
|
37
|
+
credentialId: string;
|
|
38
|
+
userId: string;
|
|
39
|
+
orgId: string;
|
|
40
|
+
rolMinimo: RolDeCarpeta;
|
|
41
|
+
}
|
|
42
|
+
export interface PermisoSobreCredencial {
|
|
43
|
+
/**
|
|
44
|
+
* ⚠️ Devuelve `true` cuando la credencial NO EXISTE, y eso no es un
|
|
45
|
+
* descuido: es la semántica que hay que conservar.
|
|
46
|
+
*
|
|
47
|
+
* Negar aquí daría un 403 sobre algo inexistente, y un 403 dice «existe
|
|
48
|
+
* pero no es tuya». Dejando pasar, el manejador contesta 404 como siempre y
|
|
49
|
+
* no se filtra qué ids existen — que es justo lo que este guardia protege,
|
|
50
|
+
* porque los ids circulan.
|
|
51
|
+
*
|
|
52
|
+
* O sea: `false` significa «existe y NO puedes», nunca «no la encuentro».
|
|
53
|
+
*/
|
|
54
|
+
puedeUsar(pregunta: PreguntaDePermiso): Promise<boolean>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* ⚠️ Cadena y no `Symbol`. Un `Symbol` no sobrevive a una frontera de módulo
|
|
58
|
+
* duplicada ni a una serialización, y esto está pensado para acabar cruzando
|
|
59
|
+
* una red.
|
|
60
|
+
*/
|
|
61
|
+
export declare const PERMISO_SOBRE_CREDENCIAL = "PERMISO_SOBRE_CREDENCIAL";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ¿Puede este usuario poner esta credencial? — la pregunta, sin la respuesta.
|
|
4
|
+
*
|
|
5
|
+
* ## Por qué existe
|
|
6
|
+
*
|
|
7
|
+
* Costura de la Fase 2. `node-controller.factory` aplicaba
|
|
8
|
+
* `@UseGuards(CredentialFolderGuard)` a los ~30 tipos de nodo, y ese guardia
|
|
9
|
+
* vive en `credentials/`: consulta la colección de credenciales y resuelve
|
|
10
|
+
* permisos de carpeta. Con eso, el factory —y con él todos los controladores
|
|
11
|
+
* de nodo— no se puede mudar a `hw-nodes` sin llevarse el dominio entero de
|
|
12
|
+
* credenciales, que es la Fase 4.
|
|
13
|
+
*
|
|
14
|
+
* ## Lo que NO se hace, y por qué
|
|
15
|
+
*
|
|
16
|
+
* Lo fácil era quitar el guardia y decir «ya autoriza el gateway al proxear».
|
|
17
|
+
* Y es defendible: la autenticación va EN el gateway por diseño.
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ Pero este guardia existe **porque la comprobación se olvidó trece
|
|
20
|
+
* veces**. Su propio docblock cuenta el agujero: bastaba con leerle el id de
|
|
21
|
+
* credencial a un nodo que sí se pudiera ver, ponérselo a un nodo propio y
|
|
22
|
+
* ejecutarlo, y la credencial de la carpeta negada se descifraba igual. Y un
|
|
23
|
+
* id de Mongo no es un secreto: sale en el lienzo y en la barra del navegador.
|
|
24
|
+
*
|
|
25
|
+
* Dejar esa garantía viviendo SÓLO en el proxy es apostar a que nada alcance
|
|
26
|
+
* nunca `hw-nodes` por otro camino — una mala configuración, un servicio
|
|
27
|
+
* nuevo, una prueba. Cuando pase, el agujero vuelve, y vuelve callado.
|
|
28
|
+
*
|
|
29
|
+
* Así que la pregunta se queda y lo que se va es la RESPUESTA: `hw-nodes`
|
|
30
|
+
* preguntará por la red privada a quien tenga el dato. Una llamada por
|
|
31
|
+
* escritura de nodo que lleve credencial —crear o editar—, no por ejecución.
|
|
32
|
+
* Un salto interno es ~1 ms contra los 100-500 ms que el nodo gasta llamando
|
|
33
|
+
* a Slack o a Gmail.
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PERMISO_SOBRE_CREDENCIAL = void 0;
|
|
37
|
+
/**
|
|
38
|
+
* ⚠️ Cadena y no `Symbol`. Un `Symbol` no sobrevive a una frontera de módulo
|
|
39
|
+
* duplicada ni a una serialización, y esto está pensado para acabar cruzando
|
|
40
|
+
* una red.
|
|
41
|
+
*/
|
|
42
|
+
exports.PERMISO_SOBRE_CREDENCIAL = 'PERMISO_SOBRE_CREDENCIAL';
|