@axiom-lattice/gateway 3.0.2 → 3.0.3

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 (155) hide show
  1. package/dist/index.js +31 -9
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +31 -9
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +9 -6
  6. package/.eslintrc.json +0 -22
  7. package/.turbo/turbo-build.log +0 -46
  8. package/AGENTS.md +0 -112
  9. package/CHANGELOG.md +0 -1190
  10. package/LOGGER_CONFIG.md +0 -135
  11. package/RESUME_STREAM_CONTENT_BASED.md +0 -326
  12. package/RESUME_STREAM_README.md +0 -388
  13. package/jest.config.js +0 -72
  14. package/public/sdk/README.md +0 -695
  15. package/public/sdk/dashboard-engine-skill.md +0 -1122
  16. package/public/sdk/dashboard-single-file-spec.md +0 -357
  17. package/public/sdk/data-query-sdk-skill.md +0 -307
  18. package/public/sdk/data-query-sdk.d.ts +0 -252
  19. package/public/sdk/data-query-sdk.js +0 -970
  20. package/public/sdk/occupancy-dashboard.html +0 -363
  21. package/public/sdk/test-dashboard.html +0 -690
  22. package/scripts/seed-lark-installation.ts +0 -54
  23. package/src/__tests__/__mocks__/e2b.ts +0 -1
  24. package/src/__tests__/a2a.test.ts +0 -428
  25. package/src/__tests__/channel-installations.test.ts +0 -199
  26. package/src/__tests__/data-query.test.ts +0 -77
  27. package/src/__tests__/sandbox-provider-registration.test.ts +0 -74
  28. package/src/__tests__/setup.ts +0 -5
  29. package/src/__tests__/workspace.test.ts +0 -400
  30. package/src/channels/__tests__/routes.test.ts +0 -50
  31. package/src/channels/lark/LarkChannelAdapter.ts +0 -217
  32. package/src/channels/lark/README.md +0 -187
  33. package/src/channels/lark/__tests__/controller.test.ts +0 -136
  34. package/src/channels/lark/__tests__/mapping-service.test.ts +0 -118
  35. package/src/channels/lark/__tests__/parser.test.ts +0 -72
  36. package/src/channels/lark/__tests__/sender.test.ts +0 -37
  37. package/src/channels/lark/__tests__/verification.test.ts +0 -157
  38. package/src/channels/lark/controller.ts +0 -48
  39. package/src/channels/lark/mapping-service.ts +0 -138
  40. package/src/channels/lark/parser.ts +0 -68
  41. package/src/channels/lark/routes.ts +0 -22
  42. package/src/channels/lark/sender.ts +0 -58
  43. package/src/channels/lark/types.ts +0 -20
  44. package/src/channels/lark/verification.ts +0 -32
  45. package/src/channels/registry.ts +0 -20
  46. package/src/channels/routes.ts +0 -30
  47. package/src/channels/wechat/WechatChannelAdapter.ts +0 -294
  48. package/src/channels/wechat/__tests__/context-store.test.ts +0 -148
  49. package/src/channels/wechat/context-store.ts +0 -54
  50. package/src/channels/wechat/controller.ts +0 -59
  51. package/src/channels/wechat/routes.ts +0 -7
  52. package/src/channels/wechat/types.ts +0 -62
  53. package/src/channels/wechat/wechat-client.ts +0 -162
  54. package/src/config/local-a2a-templates.ts +0 -59
  55. package/src/config.ts +0 -124
  56. package/src/controllers/__tests__/assistant-local-a2a.test.ts +0 -147
  57. package/src/controllers/__tests__/local-a2a-templates.test.ts +0 -112
  58. package/src/controllers/__tests__/mime.test.ts +0 -74
  59. package/src/controllers/__tests__/resources.test.ts +0 -122
  60. package/src/controllers/__tests__/run.test.ts +0 -115
  61. package/src/controllers/__tests__/tasks.test.ts +0 -215
  62. package/src/controllers/__tests__/workflow-tracking.test.ts +0 -113
  63. package/src/controllers/agent_task.ts +0 -72
  64. package/src/controllers/assistant.ts +0 -490
  65. package/src/controllers/auth.ts +0 -524
  66. package/src/controllers/channel-bindings.ts +0 -135
  67. package/src/controllers/channel-installations.ts +0 -409
  68. package/src/controllers/collections.ts +0 -176
  69. package/src/controllers/config.ts +0 -126
  70. package/src/controllers/connections.ts +0 -181
  71. package/src/controllers/data-query.ts +0 -236
  72. package/src/controllers/database-configs.ts +0 -440
  73. package/src/controllers/embeddings.ts +0 -22
  74. package/src/controllers/entries.ts +0 -167
  75. package/src/controllers/eval.ts +0 -513
  76. package/src/controllers/export-import.ts +0 -166
  77. package/src/controllers/health.ts +0 -36
  78. package/src/controllers/local-a2a-templates.ts +0 -18
  79. package/src/controllers/local-a2a.ts +0 -149
  80. package/src/controllers/mcp-configs.ts +0 -673
  81. package/src/controllers/memory.ts +0 -257
  82. package/src/controllers/menu-items.ts +0 -114
  83. package/src/controllers/metrics-configs.ts +0 -1061
  84. package/src/controllers/middleware-types.ts +0 -15
  85. package/src/controllers/models.ts +0 -199
  86. package/src/controllers/personal-assistant.ts +0 -191
  87. package/src/controllers/resources.ts +0 -477
  88. package/src/controllers/run.ts +0 -338
  89. package/src/controllers/sandbox.ts +0 -255
  90. package/src/controllers/schedules.ts +0 -336
  91. package/src/controllers/skills.ts +0 -256
  92. package/src/controllers/tasks.ts +0 -213
  93. package/src/controllers/tenants.ts +0 -121
  94. package/src/controllers/thread_status.ts +0 -66
  95. package/src/controllers/threads.ts +0 -260
  96. package/src/controllers/tools.ts +0 -139
  97. package/src/controllers/users.ts +0 -135
  98. package/src/controllers/workflow-tracking.ts +0 -693
  99. package/src/controllers/workspace.ts +0 -879
  100. package/src/export_registrations/a2a-api-key.registration.ts +0 -89
  101. package/src/export_registrations/agent.registration.ts +0 -80
  102. package/src/export_registrations/binding.registration.ts +0 -106
  103. package/src/export_registrations/channel-installation.registration.ts +0 -88
  104. package/src/export_registrations/collection.registration.ts +0 -85
  105. package/src/export_registrations/connection.registration.ts +0 -97
  106. package/src/export_registrations/database-config.registration.ts +0 -94
  107. package/src/export_registrations/eval.registration.ts +0 -334
  108. package/src/export_registrations/index.ts +0 -31
  109. package/src/export_registrations/mcp-config.registration.ts +0 -97
  110. package/src/export_registrations/menu.registration.ts +0 -91
  111. package/src/export_registrations/metrics-config.registration.ts +0 -94
  112. package/src/export_registrations/skill.registration.ts +0 -88
  113. package/src/export_registrations/task.registration.ts +0 -99
  114. package/src/index.ts +0 -497
  115. package/src/logger/Logger.ts +0 -186
  116. package/src/router/MessageContext.ts +0 -14
  117. package/src/router/MessageRouter.ts +0 -490
  118. package/src/router/middlewares/auditLogger.ts +0 -34
  119. package/src/router/middlewares/deduplication.ts +0 -38
  120. package/src/router/middlewares/index.ts +0 -3
  121. package/src/router/middlewares/rateLimit.ts +0 -46
  122. package/src/routes/__tests__/a2a-test-connection.test.ts +0 -177
  123. package/src/routes/a2a-bridge.ts +0 -266
  124. package/src/routes/a2a-test-connection.ts +0 -126
  125. package/src/routes/a2a.ts +0 -851
  126. package/src/routes/channel-bindings.ts +0 -11
  127. package/src/routes/channel-installations.ts +0 -33
  128. package/src/routes/index.ts +0 -640
  129. package/src/routes/menu-items.ts +0 -10
  130. package/src/routes/resource-routes.ts +0 -35
  131. package/src/routes/stt.ts +0 -102
  132. package/src/schemas/data-query.ts +0 -69
  133. package/src/schemas/index.ts +0 -852
  134. package/src/services/ExportImportService.ts +0 -296
  135. package/src/services/__tests__/ExportImportService.test.ts +0 -130
  136. package/src/services/__tests__/eval-runner.test.ts +0 -131
  137. package/src/services/__tests__/local-a2a.test.ts +0 -124
  138. package/src/services/agent_task_consumer.ts +0 -348
  139. package/src/services/collection_service.ts +0 -258
  140. package/src/services/eval-runner.ts +0 -283
  141. package/src/services/local-a2a.ts +0 -354
  142. package/src/services/queue_service.ts +0 -104
  143. package/src/services/sandbox_service.ts +0 -223
  144. package/src/services/skill_service.ts +0 -97
  145. package/src/services/supabase.ts +0 -60
  146. package/src/swagger.ts +0 -77
  147. package/src/types/index.ts +0 -118
  148. package/src/types/koa.d.ts +0 -7
  149. package/src/utils/__tests__/local-a2a-runtime.test.ts +0 -77
  150. package/src/utils/__tests__/path-containment.test.ts +0 -35
  151. package/src/utils/a2a-url.ts +0 -20
  152. package/src/utils/local-a2a-runtime.ts +0 -107
  153. package/src/utils/mime.ts +0 -44
  154. package/src/utils/path-containment.ts +0 -38
  155. package/tsconfig.json +0 -26
@@ -1,409 +0,0 @@
1
- import { FastifyRequest, FastifyReply } from "fastify";
2
- import { randomUUID } from "crypto";
3
- import {
4
- ChannelInstallationStore,
5
- ChannelInstallation,
6
- CreateChannelInstallationRequest,
7
- UpdateChannelInstallationRequest,
8
- ChannelInstallationType,
9
- } from "@axiom-lattice/protocols";
10
- import type { ChannelAdapterRegistry } from "../channels/registry";
11
-
12
- /**
13
- * Controller-scoped deps for channel lifecycle management.
14
- * Set by the gateway during route registration so that
15
- * enable/disable/deletion can start/stop live connections.
16
- */
17
- let _adapterRegistry: ChannelAdapterRegistry | undefined;
18
- let _router: { dispatch(msg: unknown): Promise<unknown> } | undefined;
19
-
20
- export function setChannelControllerDeps(deps: {
21
- adapterRegistry: ChannelAdapterRegistry;
22
- router: { dispatch(msg: unknown): Promise<unknown> };
23
- }): void {
24
- _adapterRegistry = deps.adapterRegistry;
25
- _router = deps.router;
26
- }
27
-
28
- /**
29
- * Channel Installation Controller
30
- * Handles channel installation CRUD operations for Lark/Feishu and future channels
31
- * All operations are scoped to a tenant ID
32
- */
33
-
34
- /**
35
- * Get tenant ID from authenticated user context
36
- * Falls back to request headers for backward compatibility
37
- */
38
- function getTenantId(request: FastifyRequest): string {
39
- // First try to get from authenticated user context
40
- const userTenantId = (request as any).user?.tenantId;
41
- if (userTenantId) {
42
- return userTenantId;
43
- }
44
-
45
- // Fallback to request headers for backward compatibility
46
- return (request.headers["x-tenant-id"] as string) || "default";
47
- }
48
-
49
- /**
50
- * Channel installation list response
51
- */
52
- interface ChannelInstallationListResponse {
53
- success: boolean;
54
- message: string;
55
- data: {
56
- records: ChannelInstallation[];
57
- total: number;
58
- };
59
- }
60
-
61
- /**
62
- * Channel installation response
63
- */
64
- interface ChannelInstallationResponse {
65
- success: boolean;
66
- message: string;
67
- data?: ChannelInstallation;
68
- }
69
-
70
- /**
71
- * Get channel installation store
72
- */
73
- async function getInstallationStore(): Promise<ChannelInstallationStore> {
74
- // Use registered store from StoreLatticeManager (supports both PG and in-memory)
75
- const { getStoreLattice } = await import("@axiom-lattice/core");
76
- const store = getStoreLattice("default", "channelInstallation").store as ChannelInstallationStore | undefined;
77
- if (store) return store;
78
-
79
- // Fallback: create PG store directly (legacy path)
80
- const { PostgreSQLChannelInstallationStore } = await import("@axiom-lattice/pg-stores");
81
- const databaseUrl = process.env.DATABASE_URL;
82
- if (!databaseUrl) {
83
- throw new Error("DATABASE_URL is required for channel installation store");
84
- }
85
- return new PostgreSQLChannelInstallationStore({
86
- poolConfig: databaseUrl,
87
- });
88
- }
89
-
90
- /**
91
- * Get all channel installations for a tenant
92
- */
93
- export async function getChannelInstallationList(
94
- request: FastifyRequest<{
95
- Querystring: { channel?: ChannelInstallationType };
96
- }>,
97
- reply: FastifyReply,
98
- ): Promise<ChannelInstallationListResponse> {
99
- const tenantId = getTenantId(request);
100
- const { channel } = request.query;
101
-
102
- try {
103
- const store = await getInstallationStore();
104
- const installations = await store.getInstallationsByTenant(tenantId, channel);
105
-
106
- return {
107
- success: true,
108
- message: "Channel installations retrieved successfully",
109
- data: {
110
- records: installations,
111
- total: installations.length,
112
- },
113
- };
114
- } catch (error) {
115
- console.error("Failed to get channel installations:", error);
116
- return {
117
- success: false,
118
- message: "Failed to retrieve channel installations",
119
- data: {
120
- records: [],
121
- total: 0,
122
- },
123
- };
124
- }
125
- }
126
-
127
- /**
128
- * Get a single channel installation by ID
129
- */
130
- export async function getChannelInstallation(
131
- request: FastifyRequest<{
132
- Params: { installationId: string };
133
- }>,
134
- reply: FastifyReply,
135
- ): Promise<ChannelInstallationResponse> {
136
- const tenantId = getTenantId(request);
137
- const { installationId } = request.params;
138
-
139
- try {
140
- const store = await getInstallationStore();
141
- const installation = await store.getInstallationById(installationId);
142
-
143
- if (!installation) {
144
- reply.code(404);
145
- return {
146
- success: false,
147
- message: "Channel installation not found",
148
- };
149
- }
150
-
151
- // Verify tenant access
152
- if (installation.tenantId !== tenantId) {
153
- reply.code(403);
154
- return {
155
- success: false,
156
- message: "Access denied",
157
- };
158
- }
159
-
160
- return {
161
- success: true,
162
- message: "Channel installation retrieved successfully",
163
- data: installation,
164
- };
165
- } catch (error) {
166
- console.error("Failed to get channel installation:", error);
167
- return {
168
- success: false,
169
- message: "Failed to retrieve channel installation",
170
- };
171
- }
172
- }
173
-
174
- /**
175
- * Create new channel installation
176
- */
177
- export async function createChannelInstallation(
178
- request: FastifyRequest<{
179
- Body: CreateChannelInstallationRequest & { id?: string };
180
- }>,
181
- reply: FastifyReply,
182
- ): Promise<ChannelInstallationResponse> {
183
- const tenantId = getTenantId(request);
184
- const body = request.body;
185
-
186
- try {
187
- // Validate required fields
188
- if (!body.channel) {
189
- reply.code(400);
190
- return {
191
- success: false,
192
- message: "Channel type is required",
193
- };
194
- }
195
-
196
- if (!body.config) {
197
- reply.code(400);
198
- return {
199
- success: false,
200
- message: "Configuration is required",
201
- };
202
- }
203
-
204
- // Validate Lark-specific config
205
- if (body.channel === "lark") {
206
- const larkConfig = body.config;
207
- if (!larkConfig.appId || !larkConfig.appSecret) {
208
- reply.code(400);
209
- return {
210
- success: false,
211
- message: "appId and appSecret are required for Lark installations",
212
- };
213
- }
214
- if (!larkConfig.assistantId) {
215
- reply.code(400);
216
- return {
217
- success: false,
218
- message: "assistantId is required for Lark installations",
219
- };
220
- }
221
- }
222
-
223
- const store = await getInstallationStore();
224
- const installationId = body.id || randomUUID();
225
-
226
- const installation = await store.createInstallation(
227
- tenantId,
228
- installationId,
229
- body,
230
- );
231
-
232
- // Start live connection for channels that need it (e.g. WeChat polling, Lark WS)
233
- if (body.enabled !== false && _adapterRegistry) {
234
- const adapter = _adapterRegistry.get(body.channel);
235
- if (adapter?.connect) {
236
- try {
237
- await adapter.connect(installation, { router: _router });
238
- } catch (err) {
239
- console.error("Failed to start channel connection after creation:", err);
240
- }
241
- }
242
- }
243
-
244
- reply.code(201);
245
- return {
246
- success: true,
247
- message: "Channel installation created successfully",
248
- data: installation,
249
- };
250
- } catch (error: any) {
251
- console.error("Failed to create channel installation:", error);
252
-
253
- // Check for duplicate key error
254
- if (error.message?.includes("duplicate") || error.code === "23505") {
255
- reply.code(409);
256
- return {
257
- success: false,
258
- message: "Channel installation with this ID already exists",
259
- };
260
- }
261
-
262
- return {
263
- success: false,
264
- message: "Failed to create channel installation",
265
- };
266
- }
267
- }
268
-
269
- /**
270
- * Update channel installation
271
- */
272
- export async function updateChannelInstallation(
273
- request: FastifyRequest<{
274
- Params: { installationId: string };
275
- Body: UpdateChannelInstallationRequest;
276
- }>,
277
- reply: FastifyReply,
278
- ): Promise<ChannelInstallationResponse> {
279
- const tenantId = getTenantId(request);
280
- const { installationId } = request.params;
281
- const body = request.body;
282
-
283
- try {
284
- const store = await getInstallationStore();
285
-
286
- // Verify installation exists and belongs to tenant
287
- const existing = await store.getInstallationById(installationId);
288
- if (!existing) {
289
- reply.code(404);
290
- return {
291
- success: false,
292
- message: "Channel installation not found",
293
- };
294
- }
295
-
296
- if (existing.tenantId !== tenantId) {
297
- reply.code(403);
298
- return {
299
- success: false,
300
- message: "Access denied",
301
- };
302
- }
303
-
304
- const installation = await store.updateInstallation(
305
- tenantId,
306
- installationId,
307
- body,
308
- );
309
-
310
- if (!installation) {
311
- reply.code(404);
312
- return {
313
- success: false,
314
- message: "Channel installation not found",
315
- };
316
- }
317
-
318
- // Handle enable/disable — start/stop live connections
319
- if (body.enabled !== undefined && body.enabled !== existing.enabled) {
320
- const adapter = _adapterRegistry?.get(existing.channel);
321
- if (body.enabled && adapter?.connect) {
322
- // Re-connect: pass router deps so the adapter can dispatch messages
323
- await adapter.connect(installation, { router: _router });
324
- } else if (!body.enabled && adapter?.disconnect) {
325
- await adapter.disconnect(installationId);
326
- }
327
- }
328
-
329
- return {
330
- success: true,
331
- message: "Channel installation updated successfully",
332
- data: installation,
333
- };
334
- } catch (error) {
335
- console.error("Failed to update channel installation:", error);
336
- return {
337
- success: false,
338
- message: "Failed to update channel installation",
339
- };
340
- }
341
- }
342
-
343
- /**
344
- * Delete channel installation
345
- */
346
- export async function deleteChannelInstallation(
347
- request: FastifyRequest<{
348
- Params: { installationId: string };
349
- }>,
350
- reply: FastifyReply,
351
- ): Promise<{ success: boolean; message: string }> {
352
- const tenantId = getTenantId(request);
353
- const { installationId } = request.params;
354
-
355
- try {
356
- const store = await getInstallationStore();
357
-
358
- // Verify installation exists and belongs to tenant
359
- const existing = await store.getInstallationById(installationId);
360
- if (!existing) {
361
- reply.code(404);
362
- return {
363
- success: false,
364
- message: "Channel installation not found",
365
- };
366
- }
367
-
368
- if (existing.tenantId !== tenantId) {
369
- reply.code(403);
370
- return {
371
- success: false,
372
- message: "Access denied",
373
- };
374
- }
375
-
376
- // Disconnect live connection before removing from DB
377
- if (_adapterRegistry) {
378
- const adapter = _adapterRegistry.get(existing.channel);
379
- if (adapter?.disconnect) {
380
- try {
381
- await adapter.disconnect(installationId);
382
- } catch (err) {
383
- console.error("Failed to disconnect channel adapter:", err);
384
- }
385
- }
386
- }
387
-
388
- const deleted = await store.deleteInstallation(tenantId, installationId);
389
-
390
- if (!deleted) {
391
- reply.code(404);
392
- return {
393
- success: false,
394
- message: "Channel installation not found",
395
- };
396
- }
397
-
398
- return {
399
- success: true,
400
- message: "Channel installation deleted successfully",
401
- };
402
- } catch (error) {
403
- console.error("Failed to delete channel installation:", error);
404
- return {
405
- success: false,
406
- message: "Failed to delete channel installation",
407
- };
408
- }
409
- }
@@ -1,176 +0,0 @@
1
- import { FastifyRequest, FastifyReply } from "fastify";
2
- import { CollectionService } from "../services/collection_service";
3
- import type {
4
- Collection,
5
- CreateCollectionRequest,
6
- UpdateCollectionRequest,
7
- } from "@axiom-lattice/protocols";
8
-
9
- const collectionService = new CollectionService();
10
-
11
- function serializeCollection(collection: Collection): any {
12
- return {
13
- id: collection.id,
14
- name: collection.name,
15
- label: collection.label,
16
- embeddingKey: collection.embeddingKey,
17
- schema: collection.schema,
18
- entryCount: (collection as any)._entryCount ?? 0,
19
- createdAt:
20
- collection.createdAt instanceof Date
21
- ? collection.createdAt.toISOString()
22
- : new Date().toISOString(),
23
- updatedAt:
24
- collection.updatedAt instanceof Date
25
- ? collection.updatedAt.toISOString()
26
- : new Date().toISOString(),
27
- };
28
- }
29
-
30
- export async function getCollectionList(
31
- request: FastifyRequest,
32
- reply: FastifyReply
33
- ): Promise<any> {
34
- try {
35
- const collections = await collectionService.getAllCollections(request);
36
- return {
37
- success: true,
38
- message: "Successfully retrieved collection list",
39
- data: {
40
- records: collections.map(serializeCollection),
41
- total: collections.length,
42
- },
43
- };
44
- } catch (error: any) {
45
- return reply.status(500).send({
46
- success: false,
47
- message: `Failed to retrieve collections: ${error.message}`,
48
- data: { records: [], total: 0 },
49
- });
50
- }
51
- }
52
-
53
- export async function getCollection(
54
- request: FastifyRequest<{ Params: { name: string } }>,
55
- reply: FastifyReply
56
- ): Promise<any> {
57
- try {
58
- const { name } = request.params;
59
- const collection = await collectionService.getCollectionByName(request, name);
60
-
61
- if (!collection) {
62
- return reply
63
- .status(404)
64
- .send({ success: false, message: "Collection not found" });
65
- }
66
-
67
- return {
68
- success: true,
69
- message: "Successfully retrieved collection",
70
- data: serializeCollection(collection),
71
- };
72
- } catch (error: any) {
73
- return reply.status(500).send({
74
- success: false,
75
- message: `Failed to retrieve collection: ${error.message}`,
76
- });
77
- }
78
- }
79
-
80
- export async function createCollection(
81
- request: FastifyRequest<{ Body: CreateCollectionRequest }>,
82
- reply: FastifyReply
83
- ): Promise<any> {
84
- try {
85
- const data = request.body;
86
- if (!data.name) {
87
- return reply
88
- .status(400)
89
- .send({ success: false, message: "name is required" });
90
- }
91
- if (!data.label) {
92
- return reply
93
- .status(400)
94
- .send({ success: false, message: "label is required" });
95
- }
96
- if (!data.embeddingKey) {
97
- return reply
98
- .status(400)
99
- .send({ success: false, message: "embeddingKey is required" });
100
- }
101
-
102
- const collection = await collectionService.createCollection(request, data);
103
- return reply.status(201).send({
104
- success: true,
105
- message: "Successfully created collection",
106
- data: serializeCollection(collection),
107
- });
108
- } catch (error: any) {
109
- if (error.message?.includes("already exists")) {
110
- return reply.status(409).send({ success: false, message: error.message });
111
- }
112
- return reply.status(500).send({
113
- success: false,
114
- message: `Failed to create collection: ${error.message}`,
115
- });
116
- }
117
- }
118
-
119
- export async function updateCollection(
120
- request: FastifyRequest<{
121
- Params: { name: string };
122
- Body: UpdateCollectionRequest;
123
- }>,
124
- reply: FastifyReply
125
- ): Promise<any> {
126
- try {
127
- const { name } = request.params;
128
- const updates = request.body;
129
-
130
- const collection = await collectionService.updateCollection(
131
- request,
132
- name,
133
- updates
134
- );
135
-
136
- if (!collection) {
137
- return reply
138
- .status(404)
139
- .send({ success: false, message: "Collection not found" });
140
- }
141
-
142
- return {
143
- success: true,
144
- message: "Successfully updated collection",
145
- data: serializeCollection(collection),
146
- };
147
- } catch (error: any) {
148
- return reply.status(500).send({
149
- success: false,
150
- message: `Failed to update collection: ${error.message}`,
151
- });
152
- }
153
- }
154
-
155
- export async function deleteCollection(
156
- request: FastifyRequest<{ Params: { name: string } }>,
157
- reply: FastifyReply
158
- ): Promise<any> {
159
- try {
160
- const { name } = request.params;
161
- const result = await collectionService.deleteCollection(request, name);
162
-
163
- if (!result) {
164
- return reply
165
- .status(404)
166
- .send({ success: false, message: "Collection not found" });
167
- }
168
-
169
- return { success: true, message: "Successfully deleted collection" };
170
- } catch (error: any) {
171
- return reply.status(500).send({
172
- success: false,
173
- message: `Failed to delete collection: ${error.message}`,
174
- });
175
- }
176
- }
@@ -1,126 +0,0 @@
1
- import { FastifyRequest, FastifyReply } from "fastify";
2
- import { configService } from "../config";
3
- import {
4
- setQueueServiceType,
5
- QueueServiceType,
6
- } from "../services/queue_service";
7
-
8
- /**
9
- * Configuration Controller
10
- * Handles configuration updates from frontend
11
- */
12
-
13
- interface UpdateConfigRequest {
14
- Body: {
15
- config: Record<string, any>;
16
- };
17
- }
18
-
19
- /**
20
- * Update gateway configuration
21
- * Accepts JSON config and loads it into environment variables
22
- */
23
- export async function updateConfig(
24
- request: FastifyRequest<UpdateConfigRequest>,
25
- reply: FastifyReply
26
- ) {
27
- try {
28
- const { config: jsonConfig } = request.body;
29
-
30
- if (!jsonConfig || typeof jsonConfig !== "object") {
31
- return reply.status(400).send({
32
- success: false,
33
- error: "Invalid configuration: config must be an object",
34
- });
35
- }
36
-
37
- // Update configuration service
38
- configService.updateConfig(jsonConfig);
39
-
40
- const warnings: string[] = [];
41
- const requiresRestart: string[] = [];
42
-
43
- // Check if port is being changed (requires restart)
44
- if (jsonConfig.port !== undefined) {
45
- requiresRestart.push("PORT");
46
- warnings.push("Port change requires server restart to take effect");
47
- }
48
-
49
- // If queue service type is being updated, reconfigure the queue service
50
- if (jsonConfig.queueServiceType) {
51
- setQueueServiceType(jsonConfig.queueServiceType as QueueServiceType);
52
- }
53
-
54
- // If Redis configuration is being updated and queue service is Redis, reconfigure
55
- if (
56
- (jsonConfig.redisUrl || jsonConfig.redisPassword) &&
57
- (process.env.QUEUE_SERVICE_TYPE === "redis" ||
58
- jsonConfig.queueServiceType === "redis")
59
- ) {
60
- // Reconfigure queue service to pick up new Redis settings
61
- const currentType =
62
- (jsonConfig.queueServiceType as QueueServiceType) ||
63
- (process.env.QUEUE_SERVICE_TYPE as QueueServiceType) ||
64
- "memory";
65
- if (currentType === "redis") {
66
- setQueueServiceType("redis");
67
- }
68
- }
69
-
70
- // Get updated config (without sensitive data)
71
- const updatedConfig = configService.getConfig();
72
- const safeConfig = {
73
- ...updatedConfig,
74
- redisPassword: updatedConfig.redisPassword
75
- ? "***"
76
- : updatedConfig.redisPassword,
77
- };
78
-
79
- return reply.send({
80
- success: true,
81
- message: "Configuration updated successfully",
82
- data: safeConfig,
83
- warnings: warnings.length > 0 ? warnings : undefined,
84
- requiresRestart: requiresRestart.length > 0 ? requiresRestart : undefined,
85
- });
86
- } catch (error: any) {
87
- console.error("Failed to update configuration", {
88
- error: error.message,
89
- stack: error.stack,
90
- });
91
- return reply.status(500).send({
92
- success: false,
93
- error: error.message || "Failed to update configuration",
94
- });
95
- }
96
- }
97
-
98
- /**
99
- * Get current gateway configuration
100
- * Returns current configuration (with sensitive data masked)
101
- */
102
- export async function getConfig(request: FastifyRequest, reply: FastifyReply) {
103
- try {
104
- const currentConfig = configService.getConfig();
105
- const safeConfig = {
106
- ...currentConfig,
107
- redisPassword: currentConfig.redisPassword
108
- ? "***"
109
- : currentConfig.redisPassword,
110
- };
111
-
112
- return reply.send({
113
- success: true,
114
- data: safeConfig,
115
- });
116
- } catch (error: any) {
117
- console.error("Failed to get configuration", {
118
- error: error.message,
119
- stack: error.stack,
120
- });
121
- return reply.status(500).send({
122
- success: false,
123
- error: error.message || "Failed to get configuration",
124
- });
125
- }
126
- }