@qcobro/common 1.11.3 → 1.11.4

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 (173) hide show
  1. package/dist/config.d.ts +307 -0
  2. package/dist/config.d.ts.map +1 -0
  3. package/{src/config.ts → dist/config.js} +123 -154
  4. package/dist/config.js.map +1 -0
  5. package/dist/errors/ValidationError.d.ts +27 -0
  6. package/dist/errors/ValidationError.d.ts.map +1 -0
  7. package/dist/errors/ValidationError.js +52 -0
  8. package/dist/errors/ValidationError.js.map +1 -0
  9. package/{src/errors/index.ts → dist/errors/index.d.ts} +1 -0
  10. package/dist/errors/index.d.ts.map +1 -0
  11. package/dist/errors/index.js +2 -0
  12. package/dist/errors/index.js.map +1 -0
  13. package/dist/index.d.ts +19 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/{src/index.ts → dist/index.js} +2 -5
  16. package/dist/index.js.map +1 -0
  17. package/dist/schemas/agentTemplates.d.ts +73 -0
  18. package/dist/schemas/agentTemplates.d.ts.map +1 -0
  19. package/dist/schemas/agentTemplates.js +90 -0
  20. package/dist/schemas/agentTemplates.js.map +1 -0
  21. package/dist/schemas/apiKeys.d.ts +17 -0
  22. package/dist/schemas/apiKeys.d.ts.map +1 -0
  23. package/{src/schemas/apiKeys.ts → dist/schemas/apiKeys.js} +11 -16
  24. package/dist/schemas/apiKeys.js.map +1 -0
  25. package/dist/schemas/auth.d.ts +74 -0
  26. package/dist/schemas/auth.d.ts.map +1 -0
  27. package/dist/schemas/auth.js +53 -0
  28. package/dist/schemas/auth.js.map +1 -0
  29. package/dist/schemas/campaigns.d.ts +61 -0
  30. package/dist/schemas/campaigns.d.ts.map +1 -0
  31. package/{src/schemas/campaigns.ts → dist/schemas/campaigns.js} +20 -32
  32. package/dist/schemas/campaigns.js.map +1 -0
  33. package/dist/schemas/contactLog.d.ts +121 -0
  34. package/dist/schemas/contactLog.d.ts.map +1 -0
  35. package/dist/schemas/contactLog.js +83 -0
  36. package/dist/schemas/contactLog.js.map +1 -0
  37. package/dist/schemas/dispatch.d.ts +51 -0
  38. package/dist/schemas/dispatch.d.ts.map +1 -0
  39. package/{src/schemas/dispatch.ts → dist/schemas/dispatch.js} +55 -61
  40. package/dist/schemas/dispatch.js.map +1 -0
  41. package/dist/schemas/email.d.ts +38 -0
  42. package/dist/schemas/email.d.ts.map +1 -0
  43. package/dist/schemas/email.js +34 -0
  44. package/dist/schemas/email.js.map +1 -0
  45. package/dist/schemas/index.d.ts +16 -0
  46. package/dist/schemas/index.d.ts.map +1 -0
  47. package/{src/schemas/index.ts → dist/schemas/index.js} +1 -0
  48. package/dist/schemas/index.js.map +1 -0
  49. package/dist/schemas/insight.d.ts +25 -0
  50. package/dist/schemas/insight.d.ts.map +1 -0
  51. package/{src/schemas/insight.ts → dist/schemas/insight.js} +6 -9
  52. package/dist/schemas/insight.js.map +1 -0
  53. package/dist/schemas/portfolios.d.ts +65 -0
  54. package/dist/schemas/portfolios.d.ts.map +1 -0
  55. package/dist/schemas/portfolios.js +40 -0
  56. package/dist/schemas/portfolios.js.map +1 -0
  57. package/dist/schemas/userSettings.d.ts +25 -0
  58. package/dist/schemas/userSettings.d.ts.map +1 -0
  59. package/{src/schemas/userSettings.ts → dist/schemas/userSettings.js} +4 -9
  60. package/dist/schemas/userSettings.js.map +1 -0
  61. package/dist/schemas/users.d.ts +7 -0
  62. package/dist/schemas/users.d.ts.map +1 -0
  63. package/dist/schemas/users.js +6 -0
  64. package/dist/schemas/users.js.map +1 -0
  65. package/dist/schemas/voiceEvent.d.ts +37 -0
  66. package/dist/schemas/voiceEvent.d.ts.map +1 -0
  67. package/dist/schemas/voiceEvent.js +35 -0
  68. package/dist/schemas/voiceEvent.js.map +1 -0
  69. package/dist/schemas/whatsApp.d.ts +76 -0
  70. package/dist/schemas/whatsApp.d.ts.map +1 -0
  71. package/dist/schemas/whatsApp.js +85 -0
  72. package/dist/schemas/whatsApp.js.map +1 -0
  73. package/dist/schemas/workspaceSettings.d.ts +27 -0
  74. package/dist/schemas/workspaceSettings.d.ts.map +1 -0
  75. package/{src/schemas/workspaceSettings.ts → dist/schemas/workspaceSettings.js} +6 -11
  76. package/dist/schemas/workspaceSettings.js.map +1 -0
  77. package/dist/schemas/workspaces.d.ts +50 -0
  78. package/dist/schemas/workspaces.d.ts.map +1 -0
  79. package/dist/schemas/workspaces.js +36 -0
  80. package/dist/schemas/workspaces.js.map +1 -0
  81. package/dist/types/agentTemplates.d.ts +119 -0
  82. package/dist/types/agentTemplates.d.ts.map +1 -0
  83. package/dist/types/agentTemplates.js +2 -0
  84. package/dist/types/agentTemplates.js.map +1 -0
  85. package/dist/types/campaigns.d.ts +257 -0
  86. package/dist/types/campaigns.d.ts.map +1 -0
  87. package/dist/types/campaigns.js +2 -0
  88. package/dist/types/campaigns.js.map +1 -0
  89. package/dist/types/dispatch.d.ts +168 -0
  90. package/dist/types/dispatch.d.ts.map +1 -0
  91. package/dist/types/dispatch.js +8 -0
  92. package/dist/types/dispatch.js.map +1 -0
  93. package/dist/types/email.d.ts +65 -0
  94. package/dist/types/email.d.ts.map +1 -0
  95. package/dist/types/email.js +7 -0
  96. package/dist/types/email.js.map +1 -0
  97. package/{src/types/engine.ts → dist/types/engine.d.ts} +23 -46
  98. package/dist/types/engine.d.ts.map +1 -0
  99. package/dist/types/engine.js +10 -0
  100. package/dist/types/engine.js.map +1 -0
  101. package/dist/types/index.d.ts +12 -0
  102. package/dist/types/index.d.ts.map +1 -0
  103. package/{src/types/index.ts → dist/types/index.js} +1 -0
  104. package/dist/types/index.js.map +1 -0
  105. package/{src/types/insight.ts → dist/types/insight.d.ts} +10 -8
  106. package/dist/types/insight.d.ts.map +1 -0
  107. package/dist/types/insight.js +2 -0
  108. package/dist/types/insight.js.map +1 -0
  109. package/dist/types/portfolios.d.ts +153 -0
  110. package/dist/types/portfolios.d.ts.map +1 -0
  111. package/dist/types/portfolios.js +2 -0
  112. package/dist/types/portfolios.js.map +1 -0
  113. package/dist/types/userSettings.d.ts +25 -0
  114. package/dist/types/userSettings.d.ts.map +1 -0
  115. package/dist/types/userSettings.js +2 -0
  116. package/dist/types/userSettings.js.map +1 -0
  117. package/dist/types/voiceApplication.d.ts +32 -0
  118. package/dist/types/voiceApplication.d.ts.map +1 -0
  119. package/dist/types/voiceApplication.js +7 -0
  120. package/dist/types/voiceApplication.js.map +1 -0
  121. package/dist/types/whatsApp.d.ts +97 -0
  122. package/dist/types/whatsApp.d.ts.map +1 -0
  123. package/dist/types/whatsApp.js +2 -0
  124. package/dist/types/whatsApp.js.map +1 -0
  125. package/dist/types/workspaceSettings.d.ts +26 -0
  126. package/dist/types/workspaceSettings.d.ts.map +1 -0
  127. package/dist/types/workspaceSettings.js +2 -0
  128. package/dist/types/workspaceSettings.js.map +1 -0
  129. package/dist/utils/index.d.ts +4 -0
  130. package/dist/utils/index.d.ts.map +1 -0
  131. package/dist/utils/index.js +4 -0
  132. package/dist/utils/index.js.map +1 -0
  133. package/{src/utils/outreach.ts → dist/utils/outreach.d.ts} +7 -32
  134. package/dist/utils/outreach.d.ts.map +1 -0
  135. package/dist/utils/outreach.js +49 -0
  136. package/dist/utils/outreach.js.map +1 -0
  137. package/dist/utils/time.d.ts +25 -0
  138. package/dist/utils/time.d.ts.map +1 -0
  139. package/dist/utils/time.js +52 -0
  140. package/dist/utils/time.js.map +1 -0
  141. package/dist/utils/withErrorHandlingAndValidation.d.ts +18 -0
  142. package/dist/utils/withErrorHandlingAndValidation.d.ts.map +1 -0
  143. package/{src/utils/withErrorHandlingAndValidation.ts → dist/utils/withErrorHandlingAndValidation.js} +9 -15
  144. package/dist/utils/withErrorHandlingAndValidation.js.map +1 -0
  145. package/package.json +4 -1
  146. package/CHANGELOG.md +0 -115
  147. package/src/config.test.ts +0 -19
  148. package/src/errors/ValidationError.test.ts +0 -38
  149. package/src/errors/ValidationError.ts +0 -68
  150. package/src/schemas/agentTemplates.ts +0 -100
  151. package/src/schemas/apiKeys.test.ts +0 -38
  152. package/src/schemas/auth.ts +0 -76
  153. package/src/schemas/contactLog.ts +0 -96
  154. package/src/schemas/email.ts +0 -37
  155. package/src/schemas/portfolios.ts +0 -49
  156. package/src/schemas/users.ts +0 -7
  157. package/src/schemas/voiceEvent.ts +0 -45
  158. package/src/schemas/whatsApp.ts +0 -101
  159. package/src/schemas/workspaces.ts +0 -53
  160. package/src/types/agentTemplates.ts +0 -104
  161. package/src/types/campaigns.ts +0 -210
  162. package/src/types/dispatch.ts +0 -160
  163. package/src/types/email.ts +0 -66
  164. package/src/types/portfolios.ts +0 -128
  165. package/src/types/userSettings.ts +0 -21
  166. package/src/types/voiceApplication.ts +0 -29
  167. package/src/types/whatsApp.ts +0 -82
  168. package/src/types/workspaceSettings.ts +0 -22
  169. package/src/utils/index.ts +0 -14
  170. package/src/utils/outreach.test.ts +0 -83
  171. package/src/utils/time.ts +0 -66
  172. package/src/utils/withErrorHandlingAndValidation.test.ts +0 -33
  173. package/tsconfig.json +0 -9
@@ -1,5 +1,4 @@
1
1
  import { z } from "zod";
2
-
3
2
  /**
4
3
  * QCobro service configuration — the shape of `qcobro.json`.
5
4
  *
@@ -12,27 +11,23 @@ import { z } from "zod";
12
11
  * issuer, SMTP, …) lives with that service, not here.
13
12
  */
14
13
  export const identityConfigSchema = z.object({
15
- /** host:port the apiserver uses to reach the external Identity gRPC service. */
16
- endpoint: z.string().default("localhost:50051"),
17
- /** Base URL of the Identity HTTP bridge (accepts invite tokens). */
18
- httpBridgeUrl: z.string().default("http://localhost:9110")
14
+ /** host:port the apiserver uses to reach the external Identity gRPC service. */
15
+ endpoint: z.string().default("localhost:50051"),
16
+ /** Base URL of the Identity HTTP bridge (accepts invite tokens). */
17
+ httpBridgeUrl: z.string().default("http://localhost:9110")
19
18
  });
20
-
21
19
  /**
22
20
  * A selectable voice in the deployment's catalog. Voice agent templates pick a
23
21
  * voice by `id` (the provider's voice identifier, e.g. an ElevenLabs voice id);
24
22
  * the console renders the picker from this catalog rather than free text.
25
23
  */
26
24
  export const voiceCatalogEntrySchema = z.object({
27
- id: z.string().min(1),
28
- name: z.string().min(1),
29
- language: z.string().min(1),
30
- gender: z.enum(["female", "male"]),
31
- provider: z.string().min(1).default("elevenlabs")
25
+ id: z.string().min(1),
26
+ name: z.string().min(1),
27
+ language: z.string().min(1),
28
+ gender: z.enum(["female", "male"]),
29
+ provider: z.string().min(1).default("elevenlabs")
32
30
  });
33
-
34
- export type VoiceCatalogEntry = z.infer<typeof voiceCatalogEntrySchema>;
35
-
36
31
  /**
37
32
  * Fonoster connection + Autopilot defaults. VOICE_AI agent templates are synced to
38
33
  * Fonoster as AUTOPILOT applications; the apiserver authenticates with a workspace
@@ -40,7 +35,7 @@ export type VoiceCatalogEntry = z.infer<typeof voiceCatalogEntrySchema>;
40
35
  * and stay unsynced (the console offers a manual re-sync).
41
36
  */
42
37
  export const fonosterConfigSchema = z
43
- .object({
38
+ .object({
44
39
  accessKeyId: z.string().min(1),
45
40
  apiKey: z.string().min(1),
46
41
  apiSecret: z.string().min(1),
@@ -50,7 +45,7 @@ export const fonosterConfigSchema = z
50
45
  * TTS product is NOT set here — it is derived per voice (see `voices`) since
51
46
  * both Voz IA and pre-recorded voice use it. */
52
47
  autopilot: z
53
- .object({
48
+ .object({
54
49
  sttProductRef: z.string().default("stt.deepgram"),
55
50
  sttModel: z.string().default("nova-3"),
56
51
  llmProductRef: z.string().default("llm.google"),
@@ -58,8 +53,8 @@ export const fonosterConfigSchema = z
58
53
  llmModel: z.string().default("gemini-2.0-flash"),
59
54
  maxTokens: z.number().default(300),
60
55
  temperature: z.number().default(0)
61
- })
62
- .default({
56
+ })
57
+ .default({
63
58
  sttProductRef: "stt.deepgram",
64
59
  sttModel: "nova-3",
65
60
  llmProductRef: "llm.google",
@@ -67,7 +62,7 @@ export const fonosterConfigSchema = z
67
62
  llmModel: "gemini-2.0-flash",
68
63
  maxTokens: 300,
69
64
  temperature: 0
70
- }),
65
+ }),
71
66
  /**
72
67
  * Selectable voice catalog for voice agent templates (Voz IA + pre-recorded).
73
68
  * Voices are Fonoster-only, so they live here. Seeded with three Spanish
@@ -104,27 +99,23 @@ export const fonosterConfigSchema = z
104
99
  * size and typical call duration. Reserve `0` to pause voice dispatch.
105
100
  */
106
101
  maxCallsPerMinute: z.number().int().nonnegative().default(6)
107
- })
108
- .optional();
109
-
110
- export type FonosterConfig = z.infer<typeof fonosterConfigSchema>;
111
-
102
+ })
103
+ .optional();
112
104
  /**
113
105
  * Derives the TTS product ref for a voice from its provider (e.g. an `elevenlabs`
114
106
  * voice → `tts.elevenlabs`). Used by both Voz IA (Autopilot) and pre-recorded
115
107
  * voice. Falls back to `tts.elevenlabs` when the voice isn't in the catalog.
116
108
  */
117
- export function ttsProductRefForVoice(voiceId: string, voices: VoiceCatalogEntry[]): string {
118
- const voice = voices.find((v) => v.id === voiceId);
119
- return voice ? `tts.${voice.provider}` : "tts.elevenlabs";
109
+ export function ttsProductRefForVoice(voiceId, voices) {
110
+ const voice = voices.find((v) => v.id === voiceId);
111
+ return voice ? `tts.${voice.provider}` : "tts.elevenlabs";
120
112
  }
121
-
122
113
  /**
123
114
  * Twilio connection for SMS dispatch. Optional — when absent, SMS dispatch fails
124
115
  * with a clear error. `fromNumbers` (E.164) are rotated through per message.
125
116
  */
126
117
  export const twilioConfigSchema = z
127
- .object({
118
+ .object({
128
119
  accountSid: z.string().min(1),
129
120
  authToken: z.string().min(1),
130
121
  fromNumbers: z.array(z.string().min(1)).default([]),
@@ -134,11 +125,8 @@ export const twilioConfigSchema = z
134
125
  * Reserve `0` to pause SMS dispatch.
135
126
  */
136
127
  maxSmsPerMinute: z.number().int().nonnegative().default(60)
137
- })
138
- .optional();
139
-
140
- export type TwilioConfig = z.infer<typeof twilioConfigSchema>;
141
-
128
+ })
129
+ .optional();
142
130
  /**
143
131
  * Resend connection for the bidirectional EMAIL channel. Optional — when absent, EMAIL
144
132
  * dispatch is inert (the engine reports EMAIL campaigns as not-configured) and the inbound
@@ -147,7 +135,7 @@ export type TwilioConfig = z.infer<typeof twilioConfigSchema>;
147
135
  * `inboundSigningSecret`. The per-attempt reply cap defaults to `maxRepliesDefault`.
148
136
  */
149
137
  export const resendConfigSchema = z
150
- .object({
138
+ .object({
151
139
  apiKey: z.string().min(1),
152
140
  fromEmail: z.string().email(),
153
141
  fromName: z.string().min(1).optional(),
@@ -166,11 +154,8 @@ export const resendConfigSchema = z
166
154
  * keep the AI talking indefinitely.
167
155
  */
168
156
  maxRepliesDefault: z.number().int().nonnegative().default(3)
169
- })
170
- .optional();
171
-
172
- export type ResendConfig = z.infer<typeof resendConfigSchema>;
173
-
157
+ })
158
+ .optional();
174
159
  /**
175
160
  * AI-insight generation. Produces a gestión's structured analysis from its
176
161
  * conversation transcript. Optional — when absent or `enabled:false`, no LLM is
@@ -182,18 +167,15 @@ export type ResendConfig = z.infer<typeof resendConfigSchema>;
182
167
  * demos, and tests, with no key and no network/cost.
183
168
  */
184
169
  export const aiProviderSchema = z.enum(["mock", "google", "openai", "anthropic"]);
185
- export type AiProvider = z.infer<typeof aiProviderSchema>;
186
-
187
170
  /** Valid models per provider; used to reject misconfiguration at load. */
188
- export const AI_MODELS: Record<AiProvider, string[]> = {
189
- mock: ["mock"],
190
- google: ["gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-2.5-pro", "gemini-2.0-flash"],
191
- openai: ["gpt-4o", "gpt-4o-mini", "gpt-4.1"],
192
- anthropic: ["claude-3-5-sonnet-latest", "claude-3-5-haiku-latest"]
171
+ export const AI_MODELS = {
172
+ mock: ["mock"],
173
+ google: ["gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-2.5-pro", "gemini-2.0-flash"],
174
+ openai: ["gpt-4o", "gpt-4o-mini", "gpt-4.1"],
175
+ anthropic: ["claude-3-5-sonnet-latest", "claude-3-5-haiku-latest"]
193
176
  };
194
-
195
177
  export const aiConfigSchema = z
196
- .object({
178
+ .object({
197
179
  enabled: z.boolean().default(false),
198
180
  provider: aiProviderSchema.default("mock"),
199
181
  apiKey: z.string().optional(),
@@ -203,23 +185,20 @@ export const aiConfigSchema = z
203
185
  /** When the analysis is produced. `onDemand` = on first detail open (then
204
186
  * cached); `onIngestion` = when the transcript is first stored. */
205
187
  generation: z.enum(["onDemand", "onIngestion"]).default("onDemand")
206
- })
207
- .superRefine((cfg, ctx) => {
188
+ })
189
+ .superRefine((cfg, ctx) => {
208
190
  if (!AI_MODELS[cfg.provider].includes(cfg.model)) {
209
- ctx.addIssue({
210
- code: z.ZodIssueCode.custom,
211
- path: ["model"],
212
- message: `Invalid model "${cfg.model}" for provider "${cfg.provider}". Valid: ${AI_MODELS[cfg.provider].join(", ")}`
213
- });
191
+ ctx.addIssue({
192
+ code: z.ZodIssueCode.custom,
193
+ path: ["model"],
194
+ message: `Invalid model "${cfg.model}" for provider "${cfg.provider}". Valid: ${AI_MODELS[cfg.provider].join(", ")}`
195
+ });
214
196
  }
215
197
  // apiKey is optional here: it may be omitted and supplied via an environment
216
198
  // variable instead (the adapter resolves it and errors clearly if none is found
217
199
  // at call time).
218
- })
219
- .optional();
220
-
221
- export type AiConfig = z.infer<typeof aiConfigSchema>;
222
-
200
+ })
201
+ .optional();
223
202
  /**
224
203
  * Text-to-speech for previewing pre-recorded agent scripts in the console (the
225
204
  * Pre-grabada gestión detail plays the script as audio). Optional — when absent, the
@@ -227,15 +206,12 @@ export type AiConfig = z.infer<typeof aiConfigSchema>;
227
206
  * unavailable. Voices come from `fonoster.voices`.
228
207
  */
229
208
  export const ttsConfigSchema = z
230
- .object({
209
+ .object({
231
210
  provider: z.literal("elevenlabs").default("elevenlabs"),
232
211
  apiKey: z.string().optional(),
233
212
  model: z.string().default("eleven_multilingual_v2")
234
- })
235
- .optional();
236
-
237
- export type TtsConfig = z.infer<typeof ttsConfigSchema>;
238
-
213
+ })
214
+ .optional();
239
215
  /**
240
216
  * A piece of user-facing copy that may be localized. Either a single string
241
217
  * (same text for every language) or a map of language code → string
@@ -243,11 +219,9 @@ export type TtsConfig = z.infer<typeof ttsConfigSchema>;
243
219
  * resolves it against the active UI language, falling back to any available value.
244
220
  */
245
221
  export const localizedStringSchema = z.union([
246
- z.string().min(1),
247
- z.record(z.string(), z.string().min(1))
222
+ z.string().min(1),
223
+ z.record(z.string(), z.string().min(1))
248
224
  ]);
249
- export type LocalizedString = z.infer<typeof localizedStringSchema>;
250
-
251
225
  /**
252
226
  * A deployment-wide announcement rendered as a dismissible banner across the
253
227
  * console (and the workspace picker). Optional — when absent, no banner shows.
@@ -257,102 +231,97 @@ export type LocalizedString = z.infer<typeof localizedStringSchema>;
257
231
  * `title` and `message` are localizable (see {@link localizedStringSchema}).
258
232
  */
259
233
  export const announcementConfigSchema = z
260
- .object({
234
+ .object({
261
235
  enabled: z.boolean().default(true),
262
236
  /** Color scheme: `announcement` (blue), `alert` (amber), `success` (green), `danger` (red). */
263
237
  variant: z.enum(["announcement", "alert", "success", "danger"]).default("announcement"),
264
238
  /** Leading icon from a curated set. */
265
239
  icon: z
266
- .enum(["megaphone", "info", "alert-triangle", "sparkles", "rocket", "bell"])
267
- .default("megaphone"),
240
+ .enum(["megaphone", "info", "alert-triangle", "sparkles", "rocket", "bell"])
241
+ .default("megaphone"),
268
242
  /** Whether the user can dismiss the banner. */
269
243
  dismissible: z.boolean().default(true),
270
244
  title: localizedStringSchema.optional(),
271
245
  message: localizedStringSchema
272
- })
273
- .optional();
274
-
275
- export type AnnouncementConfig = z.infer<typeof announcementConfigSchema>;
276
-
246
+ })
247
+ .optional();
277
248
  export const qcobroConfigSchema = z.object({
278
- /** Application (apiserver) database. */
279
- database: z.object({ url: z.string().min(1) }),
280
- identity: identityConfigSchema,
281
- apiserver: z
282
- .object({
283
- port: z.number().default(3000),
284
- /**
285
- * Port for the embedded Fonoster VoiceServer (external voice application).
286
- * Pre-recorded voice agents are EXTERNAL Fonoster apps that call back into
287
- * this server; it answers and plays the rendered script via the Say verb.
288
- */
289
- voicePort: z.number().default(50061),
290
- /** External contact-log ingress (`POST /api/contact-logs`) auth gate. */
291
- contactLogAuth: z.object({ enabled: z.boolean().default(false) }).default({ enabled: false })
249
+ /** Application (apiserver) database. */
250
+ database: z.object({ url: z.string().min(1) }),
251
+ identity: identityConfigSchema,
252
+ apiserver: z
253
+ .object({
254
+ port: z.number().default(3000),
255
+ /**
256
+ * Port for the embedded Fonoster VoiceServer (external voice application).
257
+ * Pre-recorded voice agents are EXTERNAL Fonoster apps that call back into
258
+ * this server; it answers and plays the rendered script via the Say verb.
259
+ */
260
+ voicePort: z.number().default(50061),
261
+ /** External contact-log ingress (`POST /api/contact-logs`) auth gate. */
262
+ contactLogAuth: z.object({ enabled: z.boolean().default(false) }).default({ enabled: false })
292
263
  })
293
- .default({
294
- port: 3000,
295
- voicePort: 50061,
296
- contactLogAuth: { enabled: false }
264
+ .default({
265
+ port: 3000,
266
+ voicePort: 50061,
267
+ contactLogAuth: { enabled: false }
297
268
  }),
298
- fonoster: fonosterConfigSchema,
299
- twilio: twilioConfigSchema,
300
- resend: resendConfigSchema,
301
- ai: aiConfigSchema,
302
- tts: ttsConfigSchema,
303
- announcement: announcementConfigSchema,
304
- /**
305
- * Secret-at-rest. `cloakEncryptionKey` is a versioned AES-GCM-256 key
306
- * (`k1.aesgcm256.<base64-32-byte>`) used by `prisma-field-encryption` (the Fonoster/Routr
307
- * "cloak" pattern) to encrypt tenant-provided secrets — today the WhatsApp WABA access
308
- * token. Optional: when absent, features that store tenant secrets (the Workspace
309
- * Integrations area) are disabled rather than crashing boot. Only the *key* is global; the
310
- * *secret* is per-workspace in the DB.
311
- */
312
- security: z.object({ cloakEncryptionKey: z.string().min(1).optional() }).optional(),
313
- /**
314
- * WhatsApp (Meta Cloud API) connection defaults. Per-workspace credentials (WABA id +
315
- * access token) live in the DB, not here — only the shared Graph API base/version are
316
- * deployment config.
317
- */
318
- whatsapp: z
319
- .object({
320
- apiBaseUrl: z.string().url().default("https://graph.facebook.com"),
321
- apiVersion: z.string().default("v18.0"),
322
- /** Engine pacing: max template messages the engine may dispatch per minute. */
323
- maxMessagesPerMinute: z.number().int().positive().default(60),
324
- /**
325
- * Meta App Secret — used to verify the `X-Hub-Signature-256` on inbound webhook
326
- * events. Optional: when absent, signature verification is skipped (not recommended
327
- * in production).
328
- */
329
- appSecret: z.string().min(1).optional(),
330
- /**
331
- * Default cap on autopilot replies per collection attempt (per gestión) when a
332
- * WHATSAPP agent does not set its own `maxReplies`. Mirrors `resend.maxRepliesDefault`.
333
- */
334
- maxRepliesDefault: z.number().int().nonnegative().default(3)
269
+ fonoster: fonosterConfigSchema,
270
+ twilio: twilioConfigSchema,
271
+ resend: resendConfigSchema,
272
+ ai: aiConfigSchema,
273
+ tts: ttsConfigSchema,
274
+ announcement: announcementConfigSchema,
275
+ /**
276
+ * Secret-at-rest. `cloakEncryptionKey` is a versioned AES-GCM-256 key
277
+ * (`k1.aesgcm256.<base64-32-byte>`) used by `prisma-field-encryption` (the Fonoster/Routr
278
+ * "cloak" pattern) to encrypt tenant-provided secrets — today the WhatsApp WABA access
279
+ * token. Optional: when absent, features that store tenant secrets (the Workspace
280
+ * Integrations area) are disabled rather than crashing boot. Only the *key* is global; the
281
+ * *secret* is per-workspace in the DB.
282
+ */
283
+ security: z.object({ cloakEncryptionKey: z.string().min(1).optional() }).optional(),
284
+ /**
285
+ * WhatsApp (Meta Cloud API) connection defaults. Per-workspace credentials (WABA id +
286
+ * access token) live in the DB, not here — only the shared Graph API base/version are
287
+ * deployment config.
288
+ */
289
+ whatsapp: z
290
+ .object({
291
+ apiBaseUrl: z.string().url().default("https://graph.facebook.com"),
292
+ apiVersion: z.string().default("v18.0"),
293
+ /** Engine pacing: max template messages the engine may dispatch per minute. */
294
+ maxMessagesPerMinute: z.number().int().positive().default(60),
295
+ /**
296
+ * Meta App Secret — used to verify the `X-Hub-Signature-256` on inbound webhook
297
+ * events. Optional: when absent, signature verification is skipped (not recommended
298
+ * in production).
299
+ */
300
+ appSecret: z.string().min(1).optional(),
301
+ /**
302
+ * Default cap on autopilot replies per collection attempt (per gestión) when a
303
+ * WHATSAPP agent does not set its own `maxReplies`. Mirrors `resend.maxRepliesDefault`.
304
+ */
305
+ maxRepliesDefault: z.number().int().nonnegative().default(3)
335
306
  })
336
- .default({
337
- apiBaseUrl: "https://graph.facebook.com",
338
- apiVersion: "v18.0",
339
- maxMessagesPerMinute: 60,
340
- maxRepliesDefault: 3
307
+ .default({
308
+ apiBaseUrl: "https://graph.facebook.com",
309
+ apiVersion: "v18.0",
310
+ maxMessagesPerMinute: 60,
311
+ maxRepliesDefault: 3
341
312
  }),
342
- /**
343
- * Campaigns engine. The autonomous in-process loop that originates campaign
344
- * outreach. Disabled by default so it never auto-dials in local development;
345
- * enable it in production. Per-channel pacing lives in the `fonoster`/`twilio`
346
- * blocks (the provider pools they configure are deployment-wide).
347
- */
348
- engine: z
349
- .object({
350
- enabled: z.boolean().default(false),
351
- /** Seconds between engine ticks. */
352
- tickSeconds: z.number().int().positive().default(60)
313
+ /**
314
+ * Campaigns engine. The autonomous in-process loop that originates campaign
315
+ * outreach. Disabled by default so it never auto-dials in local development;
316
+ * enable it in production. Per-channel pacing lives in the `fonoster`/`twilio`
317
+ * blocks (the provider pools they configure are deployment-wide).
318
+ */
319
+ engine: z
320
+ .object({
321
+ enabled: z.boolean().default(false),
322
+ /** Seconds between engine ticks. */
323
+ tickSeconds: z.number().int().positive().default(60)
353
324
  })
354
- .default({ enabled: false, tickSeconds: 60 })
325
+ .default({ enabled: false, tickSeconds: 60 })
355
326
  });
356
-
357
- export type IdentityConfig = z.infer<typeof identityConfigSchema>;
358
- export type QCobroConfig = z.infer<typeof qcobroConfigSchema>;
327
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { z } from "zod";
2
+ export interface FieldError {
3
+ field: string;
4
+ message: string;
5
+ code: string;
6
+ }
7
+ /**
8
+ * Wraps a Zod validation error with structured, field-level details suitable
9
+ * for API responses.
10
+ */
11
+ export declare class ValidationError extends Error {
12
+ readonly code = "VALIDATION_ERROR";
13
+ readonly fieldErrors: FieldError[];
14
+ readonly zodError: z.ZodError;
15
+ constructor(zodError: z.ZodError);
16
+ private static extractFieldErrors;
17
+ private static formatMessage;
18
+ /**
19
+ * Returns a JSON-serializable representation for API responses.
20
+ */
21
+ toJSON(): {
22
+ code: string;
23
+ message: string;
24
+ fieldErrors: FieldError[];
25
+ };
26
+ }
27
+ //# sourceMappingURL=ValidationError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationError.d.ts","sourceRoot":"","sources":["../../src/errors/ValidationError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAgB,IAAI,sBAAsB;IAC1C,SAAgB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1C,SAAgB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;gBAEzB,QAAQ,EAAE,CAAC,CAAC,QAAQ;IAehC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAQjC,OAAO,CAAC,MAAM,CAAC,aAAa;IAiB5B;;OAEG;IACH,MAAM;;;;;CAOP"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Wraps a Zod validation error with structured, field-level details suitable
3
+ * for API responses.
4
+ */
5
+ export class ValidationError extends Error {
6
+ code = "VALIDATION_ERROR";
7
+ fieldErrors;
8
+ zodError;
9
+ constructor(zodError) {
10
+ const fieldErrors = ValidationError.extractFieldErrors(zodError);
11
+ const message = ValidationError.formatMessage(fieldErrors);
12
+ super(message);
13
+ this.name = "ValidationError";
14
+ this.zodError = zodError;
15
+ this.fieldErrors = fieldErrors;
16
+ // Maintains proper stack trace for where the error was thrown (V8 engines).
17
+ if (Error.captureStackTrace) {
18
+ Error.captureStackTrace(this, ValidationError);
19
+ }
20
+ }
21
+ static extractFieldErrors(zodError) {
22
+ return zodError.issues.map((issue) => ({
23
+ field: issue.path.join(".") || "root",
24
+ message: issue.message,
25
+ code: issue.code
26
+ }));
27
+ }
28
+ static formatMessage(fieldErrors) {
29
+ if (fieldErrors.length === 0) {
30
+ return "Validation failed";
31
+ }
32
+ if (fieldErrors.length === 1) {
33
+ const { field, message } = fieldErrors[0];
34
+ return field === "root" ? message : `${field}: ${message}`;
35
+ }
36
+ const details = fieldErrors
37
+ .map(({ field, message }) => (field === "root" ? message : `${field}: ${message}`))
38
+ .join("; ");
39
+ return `Validation failed: ${details}`;
40
+ }
41
+ /**
42
+ * Returns a JSON-serializable representation for API responses.
43
+ */
44
+ toJSON() {
45
+ return {
46
+ code: this.code,
47
+ message: this.message,
48
+ fieldErrors: this.fieldErrors
49
+ };
50
+ }
51
+ }
52
+ //# sourceMappingURL=ValidationError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationError.js","sourceRoot":"","sources":["../../src/errors/ValidationError.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxB,IAAI,GAAG,kBAAkB,CAAC;IAC1B,WAAW,CAAe;IAC1B,QAAQ,CAAa;IAErC,YAAY,QAAoB;QAC9B,MAAM,WAAW,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,eAAe,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAE3D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE/B,4EAA4E;QAC5E,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,kBAAkB,CAAC,QAAoB;QACpD,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACrC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM;YACrC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAC,CAAC;IACN,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,WAAyB;QACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC1C,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,OAAO,EAAE,CAAC;QAC7D,CAAC;QAED,MAAM,OAAO,GAAG,WAAW;aACxB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,OAAO,EAAE,CAAC,CAAC;aAClF,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO,sBAAsB,OAAO,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;CACF"}
@@ -1 +1,2 @@
1
1
  export { ValidationError, type FieldError } from "./ValidationError.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ValidationError } from "./ValidationError.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAmB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ export * from "./errors/index.js";
3
+ export * from "./utils/index.js";
4
+ export * from "./schemas/index.js";
5
+ export * from "./types/index.js";
6
+ export * from "./config.js";
7
+ /**
8
+ * Placeholder contract proving the shared-schema pattern.
9
+ *
10
+ * `common` is the single source of truth for domain types and Zod schemas,
11
+ * imported by both the apiserver (input validation) and the webapp (forms/types).
12
+ * Real domain schemas (portfolios, accounts, Objectives, ...) arrive in a later
13
+ * change; this entry exists so the contract pattern is wired end to end.
14
+ */
15
+ export declare const PingInput: z.ZodObject<{
16
+ message: z.ZodString;
17
+ }, z.core.$strip>;
18
+ export type PingInput = z.infer<typeof PingInput>;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAE5B;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS;;iBAEpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC"}
@@ -1,11 +1,9 @@
1
1
  import { z } from "zod";
2
-
3
2
  export * from "./errors/index.js";
4
3
  export * from "./utils/index.js";
5
4
  export * from "./schemas/index.js";
6
5
  export * from "./types/index.js";
7
6
  export * from "./config.js";
8
-
9
7
  /**
10
8
  * Placeholder contract proving the shared-schema pattern.
11
9
  *
@@ -15,7 +13,6 @@ export * from "./config.js";
15
13
  * change; this entry exists so the contract pattern is wired end to end.
16
14
  */
17
15
  export const PingInput = z.object({
18
- message: z.string().min(1).max(280)
16
+ message: z.string().min(1).max(280)
19
17
  });
20
-
21
- export type PingInput = z.infer<typeof PingInput>;
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;CACpC,CAAC,CAAC"}