@hostwebhook/platform-contracts 0.2.0 → 0.3.0

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.
Files changed (63) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +1 -0
  3. package/dist/servicios/almacenes-vectoriales.d.ts +105 -0
  4. package/dist/servicios/almacenes-vectoriales.js +26 -0
  5. package/dist/servicios/aprobaciones-pendientes.d.ts +207 -0
  6. package/dist/servicios/aprobaciones-pendientes.js +51 -0
  7. package/dist/servicios/avisos-en-vivo.d.ts +106 -0
  8. package/dist/servicios/avisos-en-vivo.js +60 -0
  9. package/dist/servicios/canal-de-stream.d.ts +78 -0
  10. package/dist/servicios/canal-de-stream.js +5 -0
  11. package/dist/servicios/conversaciones-del-chat.d.ts +139 -0
  12. package/dist/servicios/conversaciones-del-chat.js +51 -0
  13. package/dist/servicios/corridas-programadas.d.ts +29 -0
  14. package/dist/servicios/corridas-programadas.js +5 -0
  15. package/dist/servicios/credencial/permiso-sobre-credencial.d.ts +61 -0
  16. package/dist/servicios/credencial/permiso-sobre-credencial.js +42 -0
  17. package/dist/servicios/credenciales-del-gateway.d.ts +722 -0
  18. package/dist/servicios/credenciales-del-gateway.js +114 -0
  19. package/dist/servicios/cuentas-de-atlassian.d.ts +22 -0
  20. package/dist/servicios/cuentas-de-atlassian.js +5 -0
  21. package/dist/servicios/descarga-de-drive.d.ts +74 -0
  22. package/dist/servicios/descarga-de-drive.js +41 -0
  23. package/dist/servicios/ejecucion-de-ia.d.ts +81 -0
  24. package/dist/servicios/ejecucion-de-ia.js +39 -0
  25. package/dist/servicios/enlaces-de-flujo.d.ts +59 -0
  26. package/dist/servicios/enlaces-de-flujo.js +27 -0
  27. package/dist/servicios/ficheros-del-gateway.d.ts +210 -0
  28. package/dist/servicios/ficheros-del-gateway.js +8 -0
  29. package/dist/servicios/formas-compartidas.d.ts +57 -0
  30. package/dist/servicios/formas-compartidas.js +22 -0
  31. package/dist/servicios/historial-de-corridas.d.ts +75 -0
  32. package/dist/servicios/historial-de-corridas.js +7 -0
  33. package/dist/servicios/index.d.ts +57 -0
  34. package/dist/servicios/index.js +44 -0
  35. package/dist/servicios/limites-del-plan.d.ts +82 -0
  36. package/dist/servicios/limites-del-plan.js +41 -0
  37. package/dist/servicios/motor-de-ejecucion.d.ts +197 -0
  38. package/dist/servicios/motor-de-ejecucion.js +11 -0
  39. package/dist/servicios/plantillas-de-origen.d.ts +25 -0
  40. package/dist/servicios/plantillas-de-origen.js +5 -0
  41. package/dist/servicios/posts-sociales.d.ts +69 -0
  42. package/dist/servicios/posts-sociales.js +23 -0
  43. package/dist/servicios/registro-de-entregas.d.ts +93 -0
  44. package/dist/servicios/registro-de-entregas.js +46 -0
  45. package/dist/servicios/registro-de-eventos.d.ts +135 -0
  46. package/dist/servicios/registro-de-eventos.js +62 -0
  47. package/dist/servicios/restauracion-de-nodos.d.ts +53 -0
  48. package/dist/servicios/restauracion-de-nodos.js +4 -0
  49. package/dist/servicios/salud-del-webhook.d.ts +26 -0
  50. package/dist/servicios/salud-del-webhook.js +6 -0
  51. package/dist/servicios/secretos-de-firma.d.ts +26 -0
  52. package/dist/servicios/secretos-de-firma.js +5 -0
  53. package/dist/servicios/telemetria.d.ts +114 -0
  54. package/dist/servicios/telemetria.js +60 -0
  55. package/dist/servicios/trazas-de-llm.d.ts +79 -0
  56. package/dist/servicios/trazas-de-llm.js +23 -0
  57. package/dist/servicios/tuneles.d.ts +106 -0
  58. package/dist/servicios/tuneles.js +87 -0
  59. package/dist/servicios/workspace/acceso-al-recurso.d.ts +39 -0
  60. package/dist/servicios/workspace/acceso-al-recurso.js +5 -0
  61. package/dist/servicios/zona-horaria-del-usuario.d.ts +40 -0
  62. package/dist/servicios/zona-horaria-del-usuario.js +7 -0
  63. 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,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CORRIDAS_PROGRAMADAS = void 0;
4
+ /** ⚠️ Cadena y no `Symbol`. */
5
+ exports.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';