@superatomai/sdk-node 0.0.19 → 0.0.21

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.mjs CHANGED
@@ -411,7 +411,8 @@ var UserPromptRequestMessageSchema = z3.object({
411
411
  });
412
412
  var UserPromptSuggestionsPayloadSchema = z3.object({
413
413
  prompt: z3.string(),
414
- limit: z3.number().int().positive().default(5)
414
+ limit: z3.number().int().positive().default(5),
415
+ similarityThreshold: z3.number().min(0).max(1).default(0.4)
415
416
  });
416
417
  var UserPromptSuggestionsMessageSchema = z3.object({
417
418
  id: z3.string(),
@@ -454,14 +455,25 @@ var ToolSchema = z3.object({
454
455
  params: z3.record(z3.string()),
455
456
  fn: z3.function().args(z3.any()).returns(z3.any())
456
457
  });
458
+ var UserQueryFiltersSchema = z3.object({
459
+ username: z3.string().optional(),
460
+ email: z3.string().optional(),
461
+ role: z3.string().optional(),
462
+ fullname: z3.string().optional()
463
+ });
457
464
  var UsersRequestPayloadSchema = z3.object({
458
- operation: z3.enum(["create", "update", "delete", "getAll", "getOne"]),
465
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
459
466
  data: z3.object({
467
+ id: z3.number().optional(),
460
468
  username: z3.string().optional(),
461
469
  email: z3.string().email("Invalid email format").optional(),
462
470
  password: z3.string().optional(),
463
471
  fullname: z3.string().optional(),
464
- role: z3.string().optional()
472
+ role: z3.string().optional(),
473
+ // Query operation fields
474
+ filters: UserQueryFiltersSchema.optional(),
475
+ limit: z3.number().optional(),
476
+ sort: z3.enum(["ASC", "DESC"]).optional()
465
477
  }).optional()
466
478
  });
467
479
  var UsersRequestMessageSchema = z3.object({
@@ -498,11 +510,28 @@ var ActionsRequestMessageSchema = z3.object({
498
510
  type: z3.literal("ACTIONS"),
499
511
  payload: ActionsRequestPayloadSchema
500
512
  });
513
+ var DashboardQueryFiltersSchema = z3.object({
514
+ dashboardId: z3.string().optional(),
515
+ projectId: z3.string().optional(),
516
+ createdBy: z3.number().optional(),
517
+ updatedBy: z3.number().optional(),
518
+ name: z3.string().optional()
519
+ });
501
520
  var DashboardsRequestPayloadSchema = z3.object({
502
- operation: z3.enum(["create", "update", "delete", "getAll", "getOne"]),
521
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
503
522
  data: z3.object({
523
+ id: z3.number().optional(),
504
524
  dashboardId: z3.string().optional(),
505
- dashboard: DSLRendererPropsSchema.optional()
525
+ projectId: z3.string().optional(),
526
+ name: z3.string().optional(),
527
+ description: z3.string().optional(),
528
+ createdBy: z3.number().optional(),
529
+ updatedBy: z3.number().optional(),
530
+ dashboard: DSLRendererPropsSchema.optional(),
531
+ // Query operation fields
532
+ filters: DashboardQueryFiltersSchema.optional(),
533
+ limit: z3.number().optional(),
534
+ sort: z3.enum(["ASC", "DESC"]).optional()
506
535
  }).optional()
507
536
  });
508
537
  var DashboardsRequestMessageSchema = z3.object({
@@ -511,11 +540,28 @@ var DashboardsRequestMessageSchema = z3.object({
511
540
  type: z3.literal("DASHBOARDS"),
512
541
  payload: DashboardsRequestPayloadSchema
513
542
  });
543
+ var ReportQueryFiltersSchema = z3.object({
544
+ reportId: z3.string().optional(),
545
+ projectId: z3.string().optional(),
546
+ createdBy: z3.number().optional(),
547
+ updatedBy: z3.number().optional(),
548
+ name: z3.string().optional()
549
+ });
514
550
  var ReportsRequestPayloadSchema = z3.object({
515
- operation: z3.enum(["create", "update", "delete", "getAll", "getOne"]),
551
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
516
552
  data: z3.object({
553
+ id: z3.number().optional(),
517
554
  reportId: z3.string().optional(),
518
- report: DSLRendererPropsSchema2.optional()
555
+ projectId: z3.string().optional(),
556
+ name: z3.string().optional(),
557
+ description: z3.string().optional(),
558
+ createdBy: z3.number().optional(),
559
+ updatedBy: z3.number().optional(),
560
+ report: DSLRendererPropsSchema2.optional(),
561
+ // Query operation fields
562
+ filters: ReportQueryFiltersSchema.optional(),
563
+ limit: z3.number().optional(),
564
+ sort: z3.enum(["ASC", "DESC"]).optional()
519
565
  }).optional()
520
566
  });
521
567
  var ReportsRequestMessageSchema = z3.object({
@@ -524,6 +570,36 @@ var ReportsRequestMessageSchema = z3.object({
524
570
  type: z3.literal("REPORTS"),
525
571
  payload: ReportsRequestPayloadSchema
526
572
  });
573
+ var UIQueryFiltersSchema = z3.object({
574
+ uiId: z3.string().optional(),
575
+ projectId: z3.string().optional(),
576
+ createdBy: z3.number().optional(),
577
+ updatedBy: z3.number().optional(),
578
+ name: z3.string().optional()
579
+ });
580
+ var UIsRequestPayloadSchema = z3.object({
581
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
582
+ data: z3.object({
583
+ id: z3.number().optional(),
584
+ uiId: z3.string().optional(),
585
+ projectId: z3.string().optional(),
586
+ name: z3.string().optional(),
587
+ description: z3.string().optional(),
588
+ createdBy: z3.number().optional(),
589
+ updatedBy: z3.number().optional(),
590
+ ui: DSLRendererPropsSchema.optional(),
591
+ // Query operation fields
592
+ filters: UIQueryFiltersSchema.optional(),
593
+ limit: z3.number().optional(),
594
+ sort: z3.enum(["ASC", "DESC"]).optional()
595
+ }).optional()
596
+ });
597
+ var UIsRequestMessageSchema = z3.object({
598
+ id: z3.string(),
599
+ from: MessageParticipantSchema,
600
+ type: z3.literal("UIS"),
601
+ payload: UIsRequestPayloadSchema
602
+ });
527
603
  var UIBlockSchema = z3.object({
528
604
  id: z3.string().optional(),
529
605
  userQuestion: z3.string().optional(),
@@ -547,20 +623,37 @@ var UIBlockSchema = z3.object({
547
623
  similarity: z3.number().optional()
548
624
  }).optional()
549
625
  });
626
+ var DBUIBlockSchema = z3.object({
627
+ id: z3.string(),
628
+ component: z3.record(z3.string(), z3.any()).nullable(),
629
+ analysis: z3.string().nullable(),
630
+ user_prompt: z3.string()
631
+ });
550
632
  var BookmarkDataSchema = z3.object({
551
633
  id: z3.number().optional(),
552
- uiblock: z3.any(),
553
- // JSON object
634
+ uiblock: DBUIBlockSchema,
635
+ // Typed JSON object
554
636
  created_at: z3.string().optional(),
555
637
  updated_at: z3.string().optional()
556
638
  });
639
+ var BookmarkQueryFiltersSchema = z3.object({
640
+ userId: z3.number().optional(),
641
+ threadId: z3.string().optional(),
642
+ name: z3.string().optional()
643
+ });
557
644
  var BookmarksRequestPayloadSchema = z3.object({
558
- operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "getByUser", "getByThread"]),
645
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "getByUser", "getByThread", "query"]),
559
646
  data: z3.object({
560
647
  id: z3.number().optional(),
561
648
  userId: z3.number().optional(),
562
649
  threadId: z3.string().optional(),
563
- uiblock: z3.any().optional()
650
+ name: z3.string().optional(),
651
+ description: z3.string().optional(),
652
+ uiblock: DBUIBlockSchema.optional(),
653
+ // Query operation fields
654
+ filters: BookmarkQueryFiltersSchema.optional(),
655
+ limit: z3.number().optional(),
656
+ sort: z3.enum(["ASC", "DESC"]).optional()
564
657
  }).optional()
565
658
  });
566
659
  var BookmarksRequestMessageSchema = z3.object({
@@ -5586,12 +5679,13 @@ function sendDataResponse4(id, res, sendMessage, clientId) {
5586
5679
  }
5587
5680
 
5588
5681
  // src/handlers/user-prompt-suggestions.ts
5589
- async function handleUserPromptSuggestions(data, components, sendMessage) {
5682
+ async function handleUserPromptSuggestions(data, components, sendMessage, collections, userId) {
5590
5683
  try {
5591
5684
  const request = UserPromptSuggestionsMessageSchema.parse(data);
5592
5685
  const { id, payload, from } = request;
5593
5686
  const { prompt, limit = 5 } = payload;
5594
5687
  const wsId = from.id;
5688
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Processing user prompt suggestions: ${prompt}`);
5595
5689
  if (!prompt || prompt.trim().length === 0) {
5596
5690
  sendResponse(id, {
5597
5691
  success: false,
@@ -5599,7 +5693,73 @@ async function handleUserPromptSuggestions(data, components, sendMessage) {
5599
5693
  }, sendMessage, wsId);
5600
5694
  return;
5601
5695
  }
5696
+ const componentSearchHandler = collections?.["components"]?.["search"];
5697
+ const bookmarkSearchHandler = collections?.["bookmarks"]?.["search"];
5698
+ let componentSuggestions = [];
5699
+ let bookmarkSuggestions = [];
5700
+ let useEmbeddingSearch = false;
5701
+ const searchPromises = [];
5702
+ if (componentSearchHandler) {
5703
+ searchPromises.push(
5704
+ (async () => {
5705
+ try {
5706
+ logger.info("Using embedding-based search for components");
5707
+ const result = await componentSearchHandler({ prompt, limit });
5708
+ if (result.success && result.suggestions) {
5709
+ componentSuggestions = result.suggestions.map((s) => ({
5710
+ ...s,
5711
+ suggestionType: "component"
5712
+ }));
5713
+ useEmbeddingSearch = true;
5714
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Found ${componentSuggestions.length} component suggestions`);
5715
+ }
5716
+ } catch (embeddingError) {
5717
+ logger.warn("Component embedding search failed:", embeddingError);
5718
+ }
5719
+ })()
5720
+ );
5721
+ }
5722
+ if (bookmarkSearchHandler && userId && userId !== "anonymous") {
5723
+ searchPromises.push(
5724
+ (async () => {
5725
+ try {
5726
+ logger.info(`Using embedding-based search for bookmarks (user: ${userId})`);
5727
+ const result = await bookmarkSearchHandler({ prompt, userId, limit });
5728
+ if (result.success && result.suggestions) {
5729
+ bookmarkSuggestions = result.suggestions.map((s) => ({
5730
+ ...s,
5731
+ suggestionType: "bookmark"
5732
+ }));
5733
+ useEmbeddingSearch = true;
5734
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Found ${bookmarkSuggestions.length} bookmark suggestions`);
5735
+ }
5736
+ } catch (embeddingError) {
5737
+ logger.warn("Bookmark embedding search failed:", embeddingError);
5738
+ }
5739
+ })()
5740
+ );
5741
+ }
5742
+ if (searchPromises.length > 0) {
5743
+ await Promise.all(searchPromises);
5744
+ }
5745
+ if (useEmbeddingSearch && (componentSuggestions.length > 0 || bookmarkSuggestions.length > 0)) {
5746
+ const allSuggestions = [...componentSuggestions, ...bookmarkSuggestions].sort((a, b) => (b.similarity || 0) - (a.similarity || 0)).slice(0, limit);
5747
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Returning all suggestions: ${componentSuggestions.length} components, ${bookmarkSuggestions.length} bookmarks`);
5748
+ sendResponse(id, {
5749
+ success: true,
5750
+ data: {
5751
+ prompt,
5752
+ suggestions: allSuggestions,
5753
+ count: allSuggestions.length,
5754
+ componentCount: componentSuggestions.length,
5755
+ bookmarkCount: bookmarkSuggestions.length,
5756
+ message: `Found ${allSuggestions.length} suggestions (${componentSuggestions.length} components, ${bookmarkSuggestions.length} bookmarks)`
5757
+ }
5758
+ }, sendMessage, wsId);
5759
+ return;
5760
+ }
5602
5761
  const displayComponents = components.filter((c) => c.isDisplayComp === true);
5762
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Using token-based approach. Display components: ${displayComponents.length}`);
5603
5763
  if (!displayComponents || displayComponents.length === 0) {
5604
5764
  sendResponse(id, {
5605
5765
  success: true,
@@ -5937,10 +6097,10 @@ function sendResponse2(id, res, sendMessage, clientId) {
5937
6097
  }
5938
6098
 
5939
6099
  // src/handlers/components-list-response.ts
5940
- async function handleComponentListResponse(data, storeComponents) {
6100
+ async function handleComponentListResponse(data, storeComponents, collections) {
5941
6101
  try {
5942
6102
  const componentListResponse = ComponentListResponseMessageSchema.parse(data);
5943
- const { id, payload } = componentListResponse;
6103
+ const { payload } = componentListResponse;
5944
6104
  const componentsList = payload.components;
5945
6105
  if (!componentsList) {
5946
6106
  logger.error("Components list not found in the response");
@@ -5948,6 +6108,20 @@ async function handleComponentListResponse(data, storeComponents) {
5948
6108
  }
5949
6109
  const components = ComponentsSchema.parse(componentsList);
5950
6110
  storeComponents(components);
6111
+ const embedHandler = collections?.["components"]?.["embed"];
6112
+ if (embedHandler) {
6113
+ try {
6114
+ logger.info("Embedding display components for semantic search...");
6115
+ const result = await embedHandler({ components });
6116
+ if (result.success) {
6117
+ logger.info(`Successfully embedded ${result.count} display components`);
6118
+ } else {
6119
+ logger.warn("Failed to embed components:", result.error);
6120
+ }
6121
+ } catch (embedError) {
6122
+ logger.warn("Failed to embed components:", embedError);
6123
+ }
6124
+ }
5951
6125
  return;
5952
6126
  } catch (error) {
5953
6127
  logger.error("Failed to handle user prompt request:", error);
@@ -5955,17 +6129,28 @@ async function handleComponentListResponse(data, storeComponents) {
5955
6129
  }
5956
6130
 
5957
6131
  // src/handlers/users.ts
5958
- async function handleUsersRequest(data, sendMessage) {
6132
+ async function handleUsersRequest(data, collections, sendMessage) {
6133
+ const executeCollection = async (collection, op, params) => {
6134
+ const handler = collections[collection]?.[op];
6135
+ if (!handler) {
6136
+ return null;
6137
+ }
6138
+ return await handler(params);
6139
+ };
5959
6140
  try {
5960
6141
  const request = UsersRequestMessageSchema.parse(data);
5961
6142
  const { id, payload, from } = request;
5962
6143
  const { operation, data: requestData } = payload;
6144
+ const numericId = requestData?.id;
5963
6145
  const username = requestData?.username;
5964
6146
  const email = requestData?.email;
5965
6147
  const password = requestData?.password;
5966
6148
  const fullname = requestData?.fullname;
5967
6149
  const role = requestData?.role;
5968
- if (from.type !== "admin") {
6150
+ const filters = requestData?.filters;
6151
+ const limit = requestData?.limit;
6152
+ const sort = requestData?.sort;
6153
+ if (from.type !== "admin" && operation !== "getOne" && operation !== "getAll" && operation !== "query") {
5969
6154
  sendResponse3(id, {
5970
6155
  success: false,
5971
6156
  error: "Unauthorized: Only admin can manage users"
@@ -5976,19 +6161,22 @@ async function handleUsersRequest(data, sendMessage) {
5976
6161
  const userManager = getUserManager();
5977
6162
  switch (operation) {
5978
6163
  case "create":
5979
- await handleCreate(id, { username, email, password, fullname, role }, userManager, sendMessage, from.id);
6164
+ await handleCreate(id, { username, email, password, fullname, role }, executeCollection, userManager, sendMessage, from.id);
5980
6165
  break;
5981
6166
  case "update":
5982
- await handleUpdate(id, { username, email, password, fullname, role }, userManager, sendMessage, from.id);
6167
+ await handleUpdate(id, numericId, { username, email, password, fullname, role }, executeCollection, userManager, sendMessage, from.id);
5983
6168
  break;
5984
6169
  case "delete":
5985
- await handleDelete(id, username, userManager, sendMessage, from.id);
6170
+ await handleDelete(id, numericId, username, executeCollection, userManager, sendMessage, from.id);
5986
6171
  break;
5987
6172
  case "getAll":
5988
- await handleGetAll(id, userManager, sendMessage, from.id);
6173
+ await handleGetAll(id, executeCollection, userManager, sendMessage, from.id);
5989
6174
  break;
5990
6175
  case "getOne":
5991
- await handleGetOne(id, username, userManager, sendMessage, from.id);
6176
+ await handleGetOne(id, numericId, username, executeCollection, userManager, sendMessage, from.id);
6177
+ break;
6178
+ case "query":
6179
+ await handleQuery(id, filters, limit, sort, executeCollection, userManager, sendMessage, from.id);
5992
6180
  break;
5993
6181
  default:
5994
6182
  sendResponse3(id, {
@@ -6004,7 +6192,7 @@ async function handleUsersRequest(data, sendMessage) {
6004
6192
  }, sendMessage);
6005
6193
  }
6006
6194
  }
6007
- async function handleCreate(id, userData, userManager, sendMessage, clientId) {
6195
+ async function handleCreate(id, userData, executeCollection, userManager, sendMessage, clientId) {
6008
6196
  const { username, email, password, fullname, role } = userData;
6009
6197
  if (!username || username.trim().length === 0) {
6010
6198
  sendResponse3(id, {
@@ -6030,52 +6218,121 @@ async function handleCreate(id, userData, userManager, sendMessage, clientId) {
6030
6218
  return;
6031
6219
  }
6032
6220
  }
6033
- if (userManager.userExists(username)) {
6221
+ try {
6222
+ const result = await executeCollection("users", "create", {
6223
+ username,
6224
+ email: email || void 0,
6225
+ password,
6226
+ fullname: fullname || void 0,
6227
+ role: role || void 0
6228
+ });
6229
+ if (result && result.success) {
6230
+ logger.info(`[DB] User created successfully: ${username}`);
6231
+ sendResponse3(id, {
6232
+ success: true,
6233
+ data: {
6234
+ id: result.data?.id,
6235
+ username: result.data?.username,
6236
+ email: result.data?.email,
6237
+ fullname: result.data?.fullname,
6238
+ role: result.data?.role,
6239
+ message: `User '${username}' created successfully (DB)`
6240
+ }
6241
+ }, sendMessage, clientId);
6242
+ return;
6243
+ }
6244
+ } catch (dbError) {
6245
+ logger.warn(`[DB] Failed to create user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6246
+ }
6247
+ try {
6248
+ if (userManager.userExists(username)) {
6249
+ sendResponse3(id, {
6250
+ success: false,
6251
+ error: `User '${username}' already exists`
6252
+ }, sendMessage, clientId);
6253
+ return;
6254
+ }
6255
+ if (email && userManager.getUserByEmail(email)) {
6256
+ sendResponse3(id, {
6257
+ success: false,
6258
+ error: `User with email '${email}' already exists`
6259
+ }, sendMessage, clientId);
6260
+ return;
6261
+ }
6262
+ const newUserData = {
6263
+ username,
6264
+ password
6265
+ };
6266
+ if (email && email.trim().length > 0) {
6267
+ newUserData.email = email.trim();
6268
+ }
6269
+ if (fullname && fullname.trim().length > 0) {
6270
+ newUserData.fullname = fullname.trim();
6271
+ }
6272
+ if (role && role.trim().length > 0) {
6273
+ newUserData.role = role.trim();
6274
+ }
6275
+ const newUser = userManager.createUser(newUserData);
6276
+ logger.info(`[FILE] User '${username}' created successfully`);
6277
+ sendResponse3(id, {
6278
+ success: true,
6279
+ data: {
6280
+ username: newUser.username,
6281
+ email: newUser.email,
6282
+ fullname: newUser.fullname,
6283
+ role: newUser.role,
6284
+ message: `User '${username}' created successfully (File)`
6285
+ }
6286
+ }, sendMessage, clientId);
6287
+ } catch (error) {
6034
6288
  sendResponse3(id, {
6035
6289
  success: false,
6036
- error: `User '${username}' already exists`
6290
+ error: error instanceof Error ? error.message : "Failed to create user"
6037
6291
  }, sendMessage, clientId);
6038
- return;
6039
6292
  }
6040
- if (email && userManager.getUserByEmail(email)) {
6293
+ }
6294
+ async function handleUpdate(id, numericId, userData, executeCollection, userManager, sendMessage, clientId) {
6295
+ const { username, email, password, fullname, role } = userData;
6296
+ if (!numericId && !username) {
6041
6297
  sendResponse3(id, {
6042
6298
  success: false,
6043
- error: `User with email '${email}' already exists`
6299
+ error: "User ID or username is required"
6044
6300
  }, sendMessage, clientId);
6045
6301
  return;
6046
6302
  }
6047
- const newUserData = {
6048
- username,
6049
- password
6050
- };
6051
- if (email && email.trim().length > 0) {
6052
- newUserData.email = email.trim();
6053
- }
6054
- if (fullname && fullname.trim().length > 0) {
6055
- newUserData.fullname = fullname.trim();
6056
- }
6057
- if (role && role.trim().length > 0) {
6058
- newUserData.role = role.trim();
6059
- }
6060
- const newUser = userManager.createUser(newUserData);
6061
- logger.info(`User created by admin: ${username}${email ? ` (${email})` : ""}`);
6062
- sendResponse3(id, {
6063
- success: true,
6064
- data: {
6065
- username: newUser.username,
6066
- email: newUser.email,
6067
- fullname: newUser.fullname,
6068
- role: newUser.role,
6069
- message: `User '${username}' created successfully`
6303
+ if (numericId) {
6304
+ try {
6305
+ const result = await executeCollection("users", "update", {
6306
+ id: numericId,
6307
+ username,
6308
+ email,
6309
+ password,
6310
+ fullname,
6311
+ role
6312
+ });
6313
+ if (result && result.success) {
6314
+ logger.info(`[DB] User updated successfully, ID: ${numericId}`);
6315
+ sendResponse3(id, {
6316
+ success: true,
6317
+ data: {
6318
+ id: result.data?.id,
6319
+ username: result.data?.username,
6320
+ email: result.data?.email,
6321
+ fullname: result.data?.fullname,
6322
+ role: result.data?.role,
6323
+ message: `User updated successfully (DB)`
6324
+ }
6325
+ }, sendMessage, clientId);
6326
+ return;
6327
+ }
6328
+ } catch (dbError) {
6329
+ logger.warn(`[DB] Failed to update user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6070
6330
  }
6071
- }, sendMessage, clientId);
6072
- }
6073
- async function handleUpdate(id, userData, userManager, sendMessage, clientId) {
6074
- const { username, email, password, fullname, role } = userData;
6331
+ }
6075
6332
  if (!username || username.trim().length === 0) {
6076
6333
  sendResponse3(id, {
6077
6334
  success: false,
6078
- error: "Username is required and cannot be empty"
6335
+ error: "Username is required for file-based storage update"
6079
6336
  }, sendMessage, clientId);
6080
6337
  return;
6081
6338
  }
@@ -6126,24 +6383,57 @@ async function handleUpdate(id, userData, userManager, sendMessage, clientId) {
6126
6383
  }, sendMessage, clientId);
6127
6384
  return;
6128
6385
  }
6129
- const updatedUser = userManager.updateUser(username, updates);
6130
- logger.info(`User updated by admin: ${username}`);
6131
- sendResponse3(id, {
6132
- success: true,
6133
- data: {
6134
- username: updatedUser.username,
6135
- email: updatedUser.email,
6136
- fullname: updatedUser.fullname,
6137
- role: updatedUser.role,
6138
- message: `User '${username}' updated successfully`
6139
- }
6140
- }, sendMessage, clientId);
6386
+ try {
6387
+ const updatedUser = userManager.updateUser(username, updates);
6388
+ logger.info(`[FILE] User '${username}' updated successfully`);
6389
+ sendResponse3(id, {
6390
+ success: true,
6391
+ data: {
6392
+ username: updatedUser.username,
6393
+ email: updatedUser.email,
6394
+ fullname: updatedUser.fullname,
6395
+ role: updatedUser.role,
6396
+ message: `User '${username}' updated successfully (File)`
6397
+ }
6398
+ }, sendMessage, clientId);
6399
+ } catch (error) {
6400
+ sendResponse3(id, {
6401
+ success: false,
6402
+ error: error instanceof Error ? error.message : "Failed to update user"
6403
+ }, sendMessage, clientId);
6404
+ }
6141
6405
  }
6142
- async function handleDelete(id, username, userManager, sendMessage, clientId) {
6406
+ async function handleDelete(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
6407
+ if (!numericId && !username) {
6408
+ sendResponse3(id, {
6409
+ success: false,
6410
+ error: "User ID or username is required"
6411
+ }, sendMessage, clientId);
6412
+ return;
6413
+ }
6414
+ if (numericId) {
6415
+ try {
6416
+ const result = await executeCollection("users", "delete", { id: numericId });
6417
+ if (result && result.success) {
6418
+ logger.info(`[DB] User deleted successfully, ID: ${numericId}`);
6419
+ sendResponse3(id, {
6420
+ success: true,
6421
+ data: {
6422
+ id: numericId,
6423
+ username: result.data?.username,
6424
+ message: `User deleted successfully (DB)`
6425
+ }
6426
+ }, sendMessage, clientId);
6427
+ return;
6428
+ }
6429
+ } catch (dbError) {
6430
+ logger.warn(`[DB] Failed to delete user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6431
+ }
6432
+ }
6143
6433
  if (!username || username.trim().length === 0) {
6144
6434
  sendResponse3(id, {
6145
6435
  success: false,
6146
- error: "Username is required and cannot be empty"
6436
+ error: "Username is required for file-based storage delete"
6147
6437
  }, sendMessage, clientId);
6148
6438
  return;
6149
6439
  }
@@ -6162,16 +6452,42 @@ async function handleDelete(id, username, userManager, sendMessage, clientId) {
6162
6452
  }, sendMessage, clientId);
6163
6453
  return;
6164
6454
  }
6165
- logger.info(`User deleted by admin: ${username}`);
6455
+ logger.info(`[FILE] User '${username}' deleted successfully`);
6166
6456
  sendResponse3(id, {
6167
6457
  success: true,
6168
6458
  data: {
6169
6459
  username,
6170
- message: `User '${username}' deleted successfully`
6460
+ message: `User '${username}' deleted successfully (File)`
6171
6461
  }
6172
6462
  }, sendMessage, clientId);
6173
6463
  }
6174
- async function handleGetAll(id, userManager, sendMessage, clientId) {
6464
+ async function handleGetAll(id, executeCollection, userManager, sendMessage, clientId) {
6465
+ try {
6466
+ const result = await executeCollection("users", "getAll", {});
6467
+ if (result && result.success) {
6468
+ const sanitizedUsers2 = result.data.map((user) => ({
6469
+ id: user.id,
6470
+ username: user.username,
6471
+ email: user.email,
6472
+ fullname: user.fullname,
6473
+ role: user.role,
6474
+ createdAt: user.createdAt,
6475
+ updatedAt: user.updatedAt
6476
+ }));
6477
+ logger.info(`[DB] Retrieved ${result.count} users`);
6478
+ sendResponse3(id, {
6479
+ success: true,
6480
+ data: {
6481
+ users: sanitizedUsers2,
6482
+ count: result.count,
6483
+ message: `Retrieved ${result.count} users (DB)`
6484
+ }
6485
+ }, sendMessage, clientId);
6486
+ return;
6487
+ }
6488
+ } catch (dbError) {
6489
+ logger.warn(`[DB] Failed to get all users, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6490
+ }
6175
6491
  const users = userManager.getAllUsers();
6176
6492
  const sanitizedUsers = users.map((user) => ({
6177
6493
  username: user.username,
@@ -6180,21 +6496,55 @@ async function handleGetAll(id, userManager, sendMessage, clientId) {
6180
6496
  role: user.role,
6181
6497
  wsIds: user.wsIds || []
6182
6498
  }));
6183
- logger.info(`Admin retrieved all users (count: ${sanitizedUsers.length})`);
6499
+ logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users`);
6184
6500
  sendResponse3(id, {
6185
6501
  success: true,
6186
6502
  data: {
6187
6503
  users: sanitizedUsers,
6188
6504
  count: sanitizedUsers.length,
6189
- message: `Retrieved ${sanitizedUsers.length} users`
6505
+ message: `Retrieved ${sanitizedUsers.length} users (File)`
6190
6506
  }
6191
6507
  }, sendMessage, clientId);
6192
6508
  }
6193
- async function handleGetOne(id, username, userManager, sendMessage, clientId) {
6509
+ async function handleGetOne(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
6510
+ if (!numericId && !username) {
6511
+ sendResponse3(id, {
6512
+ success: false,
6513
+ error: "User ID or username is required"
6514
+ }, sendMessage, clientId);
6515
+ return;
6516
+ }
6517
+ if (numericId) {
6518
+ try {
6519
+ const result = await executeCollection("users", "getOne", { id: numericId });
6520
+ if (result && result.success) {
6521
+ const sanitizedUser2 = {
6522
+ id: result.data?.id,
6523
+ username: result.data?.username,
6524
+ email: result.data?.email,
6525
+ fullname: result.data?.fullname,
6526
+ role: result.data?.role,
6527
+ createdAt: result.data?.createdAt,
6528
+ updatedAt: result.data?.updatedAt
6529
+ };
6530
+ logger.info(`[DB] Retrieved user ID: ${numericId}`);
6531
+ sendResponse3(id, {
6532
+ success: true,
6533
+ data: {
6534
+ user: sanitizedUser2,
6535
+ message: `Retrieved user (DB)`
6536
+ }
6537
+ }, sendMessage, clientId);
6538
+ return;
6539
+ }
6540
+ } catch (dbError) {
6541
+ logger.warn(`[DB] Failed to get user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6542
+ }
6543
+ }
6194
6544
  if (!username || username.trim().length === 0) {
6195
6545
  sendResponse3(id, {
6196
6546
  success: false,
6197
- error: "Username is required and cannot be empty"
6547
+ error: "Username is required for file-based storage lookup"
6198
6548
  }, sendMessage, clientId);
6199
6549
  return;
6200
6550
  }
@@ -6213,12 +6563,61 @@ async function handleGetOne(id, username, userManager, sendMessage, clientId) {
6213
6563
  role: user.role,
6214
6564
  wsIds: user.wsIds || []
6215
6565
  };
6216
- logger.info(`Admin retrieved user: ${username}`);
6566
+ logger.info(`[FILE] Retrieved user: ${username}`);
6217
6567
  sendResponse3(id, {
6218
6568
  success: true,
6219
6569
  data: {
6220
6570
  user: sanitizedUser,
6221
- message: `Retrieved user '${username}'`
6571
+ message: `Retrieved user '${username}' (File)`
6572
+ }
6573
+ }, sendMessage, clientId);
6574
+ }
6575
+ async function handleQuery(id, filters, limit, sort, executeCollection, userManager, sendMessage, clientId) {
6576
+ try {
6577
+ const result = await executeCollection("users", "query", {
6578
+ filters: filters || {},
6579
+ limit,
6580
+ sort
6581
+ });
6582
+ if (result && result.success) {
6583
+ const sanitizedUsers2 = result.data.map((user) => ({
6584
+ id: user.id,
6585
+ username: user.username,
6586
+ email: user.email,
6587
+ fullname: user.fullname,
6588
+ role: user.role,
6589
+ createdAt: user.createdAt,
6590
+ updatedAt: user.updatedAt
6591
+ }));
6592
+ logger.info(`[DB] Query returned ${result.count} users`);
6593
+ sendResponse3(id, {
6594
+ success: true,
6595
+ data: {
6596
+ users: sanitizedUsers2,
6597
+ count: result.count,
6598
+ message: `Query returned ${result.count} users (DB)`
6599
+ }
6600
+ }, sendMessage, clientId);
6601
+ return;
6602
+ }
6603
+ } catch (dbError) {
6604
+ logger.warn(`[DB] Failed to query users: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6605
+ }
6606
+ const users = userManager.getAllUsers();
6607
+ const sanitizedUsers = users.map((user) => ({
6608
+ username: user.username,
6609
+ email: user.email,
6610
+ fullname: user.fullname,
6611
+ role: user.role,
6612
+ wsIds: user.wsIds || []
6613
+ }));
6614
+ logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users (all - no query filter)`);
6615
+ sendResponse3(id, {
6616
+ success: true,
6617
+ data: {
6618
+ users: sanitizedUsers,
6619
+ count: sanitizedUsers.length,
6620
+ message: `Retrieved ${sanitizedUsers.length} users (File - no query filter)`
6222
6621
  }
6223
6622
  }, sendMessage, clientId);
6224
6623
  }
@@ -6252,13 +6651,29 @@ function getDashboardManager() {
6252
6651
  }
6253
6652
 
6254
6653
  // src/handlers/dashboards.ts
6255
- async function handleDashboardsRequest(data, sendMessage) {
6654
+ async function handleDashboardsRequest(data, collections, sendMessage) {
6655
+ const executeCollection = async (collection, op, params) => {
6656
+ const handler = collections[collection]?.[op];
6657
+ if (!handler) {
6658
+ return null;
6659
+ }
6660
+ return await handler(params);
6661
+ };
6256
6662
  try {
6257
6663
  const request = DashboardsRequestMessageSchema.parse(data);
6258
6664
  const { id, payload, from } = request;
6259
6665
  const { operation, data: requestData } = payload;
6260
6666
  const dashboardId = requestData?.dashboardId;
6261
6667
  const dashboard = requestData?.dashboard;
6668
+ const projectId = requestData?.projectId;
6669
+ const name = requestData?.name;
6670
+ const description = requestData?.description;
6671
+ const createdBy = requestData?.createdBy;
6672
+ const updatedBy = requestData?.updatedBy;
6673
+ const numericId = requestData?.id;
6674
+ const filters = requestData?.filters;
6675
+ const limit = requestData?.limit;
6676
+ const sort = requestData?.sort;
6262
6677
  if (from.type !== "admin") {
6263
6678
  sendResponse4(id, {
6264
6679
  success: false,
@@ -6270,19 +6685,22 @@ async function handleDashboardsRequest(data, sendMessage) {
6270
6685
  const dashboardManager2 = getDashboardManager();
6271
6686
  switch (operation) {
6272
6687
  case "create":
6273
- await handleCreate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, from.id);
6688
+ await handleCreate2(id, dashboardId, dashboard, projectId, name, description, createdBy, executeCollection, dashboardManager2, sendMessage, from.id);
6274
6689
  break;
6275
6690
  case "update":
6276
- await handleUpdate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, from.id);
6691
+ await handleUpdate2(id, numericId, dashboardId, dashboard, name, description, updatedBy, executeCollection, dashboardManager2, sendMessage, from.id);
6277
6692
  break;
6278
6693
  case "delete":
6279
- await handleDelete2(id, dashboardId, dashboardManager2, sendMessage, from.id);
6694
+ await handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, from.id);
6280
6695
  break;
6281
6696
  case "getAll":
6282
- await handleGetAll2(id, dashboardManager2, sendMessage, from.id);
6697
+ await handleGetAll2(id, executeCollection, dashboardManager2, sendMessage, from.id);
6283
6698
  break;
6284
6699
  case "getOne":
6285
- await handleGetOne2(id, dashboardId, dashboardManager2, sendMessage, from.id);
6700
+ await handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, from.id);
6701
+ break;
6702
+ case "query":
6703
+ await handleQuery2(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, from.id);
6286
6704
  break;
6287
6705
  default:
6288
6706
  sendResponse4(id, {
@@ -6298,7 +6716,7 @@ async function handleDashboardsRequest(data, sendMessage) {
6298
6716
  }, sendMessage);
6299
6717
  }
6300
6718
  }
6301
- async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, clientId) {
6719
+ async function handleCreate2(id, dashboardId, dashboard, projectId, name, description, createdBy, executeCollection, dashboardManager2, sendMessage, clientId) {
6302
6720
  if (!dashboardId || dashboardId.trim().length === 0) {
6303
6721
  sendResponse4(id, {
6304
6722
  success: false,
@@ -6306,21 +6724,50 @@ async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, send
6306
6724
  }, sendMessage, clientId);
6307
6725
  return;
6308
6726
  }
6309
- if (!dashboard) {
6727
+ if (!projectId) {
6310
6728
  sendResponse4(id, {
6311
6729
  success: false,
6312
- error: "Dashboard data is required"
6730
+ error: "Project ID is required"
6313
6731
  }, sendMessage, clientId);
6314
6732
  return;
6315
6733
  }
6316
6734
  try {
6735
+ const result = await executeCollection("dashboards", "create", {
6736
+ dashboardId,
6737
+ projectId,
6738
+ name: name || "",
6739
+ description,
6740
+ dashboard,
6741
+ createdBy
6742
+ });
6743
+ if (result && result.success) {
6744
+ logger.info(`[DB] Dashboard created successfully, ID: ${result.data?.id}`);
6745
+ sendResponse4(id, {
6746
+ success: true,
6747
+ data: {
6748
+ id: result.data?.id,
6749
+ dashboardId: result.data?.dashboardId,
6750
+ dashboard: result.data?.dashboard || dashboard,
6751
+ message: `Dashboard created successfully (DB)`
6752
+ }
6753
+ }, sendMessage, clientId);
6754
+ return;
6755
+ }
6756
+ } catch (dbError) {
6757
+ logger.warn(`[DB] Failed to create dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6758
+ }
6759
+ try {
6760
+ if (!dashboard) {
6761
+ dashboard = {};
6762
+ }
6317
6763
  const createdDashboard = dashboardManager2.createDashboard(dashboardId, dashboard);
6764
+ logger.info(`[FILE] Dashboard '${dashboardId}' created successfully`);
6318
6765
  sendResponse4(id, {
6319
6766
  success: true,
6320
6767
  data: {
6321
6768
  dashboardId,
6322
6769
  dashboard: createdDashboard,
6323
- message: `Dashboard '${dashboardId}' created successfully`
6770
+ message: `Dashboard '${dashboardId}' created successfully (File)`
6324
6771
  }
6325
6772
  }, sendMessage, clientId);
6326
6773
  } catch (error) {
@@ -6330,36 +6777,56 @@ async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, send
6330
6777
  }, sendMessage, clientId);
6331
6778
  }
6332
6779
  }
6333
- async function handleUpdate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, clientId) {
6334
- if (!dashboardId || dashboardId.trim().length === 0) {
6780
+ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, description, updatedBy, executeCollection, dashboardManager2, sendMessage, clientId) {
6781
+ if (!numericId) {
6335
6782
  sendResponse4(id, {
6336
6783
  success: false,
6337
- error: "Dashboard ID is required and cannot be empty"
6784
+ error: "Dashboard ID is required"
6338
6785
  }, sendMessage, clientId);
6339
6786
  return;
6340
6787
  }
6341
- if (!dashboard) {
6342
- sendResponse4(id, {
6343
- success: false,
6344
- error: "Dashboard data is required"
6345
- }, sendMessage, clientId);
6346
- return;
6788
+ try {
6789
+ const result = await executeCollection("dashboards", "update", {
6790
+ id: numericId,
6791
+ name,
6792
+ description,
6793
+ dashboard,
6794
+ updatedBy
6795
+ });
6796
+ if (result && result.success) {
6797
+ logger.info(`[DB] Dashboard updated successfully, ID: ${numericId}`);
6798
+ sendResponse4(id, {
6799
+ success: true,
6800
+ data: {
6801
+ id: numericId,
6802
+ dashboardId: result.data?.dashboardId,
6803
+ dashboard: result.data?.dashboard || dashboard,
6804
+ message: `Dashboard updated successfully (DB)`
6805
+ }
6806
+ }, sendMessage, clientId);
6807
+ return;
6808
+ }
6809
+ } catch (dbError) {
6810
+ logger.warn(`[DB] Failed to update dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6347
6811
  }
6812
+ const fileStorageId = dashboardId || String(numericId);
6348
6813
  try {
6349
- const updatedDashboard = dashboardManager2.updateDashboard(dashboardId, dashboard);
6814
+ const updatedDashboard = dashboardManager2.updateDashboard(fileStorageId, dashboard);
6350
6815
  if (!updatedDashboard) {
6351
6816
  sendResponse4(id, {
6352
6817
  success: false,
6353
- error: `Dashboard '${dashboardId}' not found`
6818
+ error: `Dashboard '${fileStorageId}' not found`
6354
6819
  }, sendMessage, clientId);
6355
6820
  return;
6356
6821
  }
6822
+ logger.info(`[FILE] Dashboard '${fileStorageId}' updated successfully`);
6357
6823
  sendResponse4(id, {
6358
6824
  success: true,
6359
6825
  data: {
6360
- dashboardId,
6826
+ id: numericId,
6827
+ dashboardId: fileStorageId,
6361
6828
  dashboard: updatedDashboard,
6362
- message: `Dashboard '${dashboardId}' updated successfully`
6829
+ message: `Dashboard '${fileStorageId}' updated successfully (File)`
6363
6830
  }
6364
6831
  }, sendMessage, clientId);
6365
6832
  } catch (error) {
@@ -6369,65 +6836,154 @@ async function handleUpdate2(id, dashboardId, dashboard, dashboardManager2, send
6369
6836
  }, sendMessage, clientId);
6370
6837
  }
6371
6838
  }
6372
- async function handleDelete2(id, dashboardId, dashboardManager2, sendMessage, clientId) {
6373
- if (!dashboardId || dashboardId.trim().length === 0) {
6839
+ async function handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
6840
+ if (!numericId) {
6374
6841
  sendResponse4(id, {
6375
6842
  success: false,
6376
- error: "Dashboard ID is required and cannot be empty"
6843
+ error: "Dashboard ID is required"
6377
6844
  }, sendMessage, clientId);
6378
6845
  return;
6379
6846
  }
6380
- const deleted = dashboardManager2.deleteDashboard(dashboardId);
6847
+ try {
6848
+ const result = await executeCollection("dashboards", "delete", { id: numericId });
6849
+ if (result && result.success) {
6850
+ logger.info(`[DB] Dashboard deleted successfully, ID: ${numericId}`);
6851
+ sendResponse4(id, {
6852
+ success: true,
6853
+ data: {
6854
+ id: numericId,
6855
+ message: `Dashboard deleted successfully (DB)`
6856
+ }
6857
+ }, sendMessage, clientId);
6858
+ return;
6859
+ }
6860
+ } catch (dbError) {
6861
+ logger.warn(`[DB] Failed to delete dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6862
+ }
6863
+ const fileStorageId = dashboardId || String(numericId);
6864
+ const deleted = dashboardManager2.deleteDashboard(fileStorageId);
6381
6865
  if (!deleted) {
6382
6866
  sendResponse4(id, {
6383
6867
  success: false,
6384
- error: `Dashboard '${dashboardId}' not found`
6868
+ error: `Dashboard '${fileStorageId}' not found`
6385
6869
  }, sendMessage, clientId);
6386
6870
  return;
6387
6871
  }
6872
+ logger.info(`[FILE] Dashboard '${fileStorageId}' deleted successfully`);
6388
6873
  sendResponse4(id, {
6389
6874
  success: true,
6390
6875
  data: {
6391
- dashboardId,
6392
- message: `Dashboard '${dashboardId}' deleted successfully`
6876
+ id: numericId,
6877
+ dashboardId: fileStorageId,
6878
+ message: `Dashboard '${fileStorageId}' deleted successfully (File)`
6393
6879
  }
6394
6880
  }, sendMessage, clientId);
6395
6881
  }
6396
- async function handleGetAll2(id, dashboardManager2, sendMessage, clientId) {
6397
- const dashboards = dashboardManager2.getAllDashboards();
6398
- logger.info(`Admin retrieved all dashboards (count: ${dashboards.length})`);
6399
- sendResponse4(id, {
6400
- success: true,
6401
- data: {
6402
- dashboards,
6403
- count: dashboards.length,
6404
- message: `Retrieved ${dashboards.length} dashboards`
6405
- }
6882
+ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessage, clientId) {
6883
+ try {
6884
+ const result = await executeCollection("dashboards", "getAll", {});
6885
+ if (result && result.success) {
6886
+ logger.info(`[DB] Retrieved ${result.count} dashboards`);
6887
+ sendResponse4(id, {
6888
+ success: true,
6889
+ data: {
6890
+ dashboards: result.data,
6891
+ count: result.count,
6892
+ message: `Retrieved ${result.count} dashboards (DB)`
6893
+ }
6894
+ }, sendMessage, clientId);
6895
+ return;
6896
+ }
6897
+ } catch (dbError) {
6898
+ logger.warn(`[DB] Failed to get all dashboards, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6899
+ }
6900
+ const dashboards = dashboardManager2.getAllDashboards();
6901
+ logger.info(`[FILE] Retrieved ${dashboards.length} dashboards`);
6902
+ sendResponse4(id, {
6903
+ success: true,
6904
+ data: {
6905
+ dashboards,
6906
+ count: dashboards.length,
6907
+ message: `Retrieved ${dashboards.length} dashboards (File)`
6908
+ }
6406
6909
  }, sendMessage, clientId);
6407
6910
  }
6408
- async function handleGetOne2(id, dashboardId, dashboardManager2, sendMessage, clientId) {
6409
- if (!dashboardId || dashboardId.trim().length === 0) {
6911
+ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
6912
+ if (!numericId) {
6410
6913
  sendResponse4(id, {
6411
6914
  success: false,
6412
- error: "Dashboard ID is required and cannot be empty"
6915
+ error: "Dashboard ID is required"
6413
6916
  }, sendMessage, clientId);
6414
6917
  return;
6415
6918
  }
6416
- const dashboard = dashboardManager2.getDashboard(dashboardId);
6919
+ try {
6920
+ const result = await executeCollection("dashboards", "getOne", { id: numericId });
6921
+ if (result && result.success) {
6922
+ logger.info(`[DB] Retrieved dashboard ID: ${numericId}`);
6923
+ sendResponse4(id, {
6924
+ success: true,
6925
+ data: {
6926
+ id: numericId,
6927
+ dashboardId: result.data?.dashboardId,
6928
+ dashboard: result.data?.dashboard || result.data,
6929
+ message: `Retrieved dashboard (DB)`
6930
+ }
6931
+ }, sendMessage, clientId);
6932
+ return;
6933
+ }
6934
+ } catch (dbError) {
6935
+ logger.warn(`[DB] Failed to get dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6936
+ }
6937
+ const fileStorageId = dashboardId || String(numericId);
6938
+ const dashboard = dashboardManager2.getDashboard(fileStorageId);
6417
6939
  if (!dashboard) {
6418
6940
  sendResponse4(id, {
6419
6941
  success: false,
6420
- error: `Dashboard '${dashboardId}' not found`
6942
+ error: `Dashboard '${fileStorageId}' not found`
6421
6943
  }, sendMessage, clientId);
6422
6944
  return;
6423
6945
  }
6424
- logger.info(`Admin retrieved dashboard: ${dashboardId}`);
6946
+ logger.info(`[FILE] Retrieved dashboard: ${fileStorageId}`);
6425
6947
  sendResponse4(id, {
6426
6948
  success: true,
6427
6949
  data: {
6428
- dashboardId,
6950
+ id: numericId,
6951
+ dashboardId: fileStorageId,
6429
6952
  dashboard,
6430
- message: `Retrieved dashboard '${dashboardId}'`
6953
+ message: `Retrieved dashboard '${fileStorageId}' (File)`
6954
+ }
6955
+ }, sendMessage, clientId);
6956
+ }
6957
+ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, clientId) {
6958
+ try {
6959
+ const result = await executeCollection("dashboards", "query", {
6960
+ filters: filters || {},
6961
+ limit,
6962
+ sort
6963
+ });
6964
+ if (result && result.success) {
6965
+ logger.info(`[DB] Query returned ${result.count} dashboards`);
6966
+ sendResponse4(id, {
6967
+ success: true,
6968
+ data: {
6969
+ dashboards: result.data,
6970
+ count: result.count,
6971
+ message: `Query returned ${result.count} dashboards (DB)`
6972
+ }
6973
+ }, sendMessage, clientId);
6974
+ return;
6975
+ }
6976
+ } catch (dbError) {
6977
+ logger.warn(`[DB] Failed to query dashboards: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6978
+ }
6979
+ const dashboards = dashboardManager2.getAllDashboards();
6980
+ logger.info(`[FILE] Retrieved ${dashboards.length} dashboards (all - no query filter)`);
6981
+ sendResponse4(id, {
6982
+ success: true,
6983
+ data: {
6984
+ dashboards,
6985
+ count: dashboards.length,
6986
+ message: `Retrieved ${dashboards.length} dashboards (File - no query filter)`
6431
6987
  }
6432
6988
  }, sendMessage, clientId);
6433
6989
  }
@@ -6460,13 +7016,29 @@ function setReportManager(manager) {
6460
7016
  }
6461
7017
 
6462
7018
  // src/handlers/reports.ts
6463
- async function handleReportsRequest(data, sendMessage) {
7019
+ async function handleReportsRequest(data, collections, sendMessage) {
7020
+ const executeCollection = async (collection, op, params) => {
7021
+ const handler = collections[collection]?.[op];
7022
+ if (!handler) {
7023
+ return null;
7024
+ }
7025
+ return await handler(params);
7026
+ };
6464
7027
  try {
6465
7028
  const request = ReportsRequestMessageSchema.parse(data);
6466
7029
  const { id, payload, from } = request;
6467
7030
  const { operation, data: requestData } = payload;
6468
7031
  const reportId = requestData?.reportId;
6469
7032
  const report = requestData?.report;
7033
+ const projectId = requestData?.projectId;
7034
+ const name = requestData?.name;
7035
+ const description = requestData?.description;
7036
+ const createdBy = requestData?.createdBy;
7037
+ const updatedBy = requestData?.updatedBy;
7038
+ const numericId = requestData?.id;
7039
+ const filters = requestData?.filters;
7040
+ const limit = requestData?.limit;
7041
+ const sort = requestData?.sort;
6470
7042
  if (from.type !== "admin") {
6471
7043
  sendResponse5(id, {
6472
7044
  success: false,
@@ -6478,19 +7050,22 @@ async function handleReportsRequest(data, sendMessage) {
6478
7050
  const reportManager2 = getReportManager();
6479
7051
  switch (operation) {
6480
7052
  case "create":
6481
- await handleCreate3(id, reportId, report, reportManager2, sendMessage, from.id);
7053
+ await handleCreate3(id, reportId, report, projectId, name, description, createdBy, executeCollection, reportManager2, sendMessage, from.id);
6482
7054
  break;
6483
7055
  case "update":
6484
- await handleUpdate3(id, reportId, report, reportManager2, sendMessage, from.id);
7056
+ await handleUpdate3(id, numericId, reportId, report, name, description, updatedBy, executeCollection, reportManager2, sendMessage, from.id);
6485
7057
  break;
6486
7058
  case "delete":
6487
- await handleDelete3(id, reportId, reportManager2, sendMessage, from.id);
7059
+ await handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, from.id);
6488
7060
  break;
6489
7061
  case "getAll":
6490
- await handleGetAll3(id, reportManager2, sendMessage, from.id);
7062
+ await handleGetAll3(id, executeCollection, reportManager2, sendMessage, from.id);
6491
7063
  break;
6492
7064
  case "getOne":
6493
- await handleGetOne3(id, reportId, reportManager2, sendMessage, from.id);
7065
+ await handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, from.id);
7066
+ break;
7067
+ case "query":
7068
+ await handleQuery3(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, from.id);
6494
7069
  break;
6495
7070
  default:
6496
7071
  sendResponse5(id, {
@@ -6506,7 +7081,7 @@ async function handleReportsRequest(data, sendMessage) {
6506
7081
  }, sendMessage);
6507
7082
  }
6508
7083
  }
6509
- async function handleCreate3(id, reportId, report, reportManager2, sendMessage, clientId) {
7084
+ async function handleCreate3(id, reportId, report, projectId, name, description, createdBy, executeCollection, reportManager2, sendMessage, clientId) {
6510
7085
  if (!reportId || reportId.trim().length === 0) {
6511
7086
  sendResponse5(id, {
6512
7087
  success: false,
@@ -6514,21 +7089,50 @@ async function handleCreate3(id, reportId, report, reportManager2, sendMessage,
6514
7089
  }, sendMessage, clientId);
6515
7090
  return;
6516
7091
  }
6517
- if (!report) {
7092
+ if (!projectId) {
6518
7093
  sendResponse5(id, {
6519
7094
  success: false,
6520
- error: "Report data is required"
7095
+ error: "Project ID is required"
6521
7096
  }, sendMessage, clientId);
6522
7097
  return;
6523
7098
  }
6524
7099
  try {
7100
+ const result = await executeCollection("reports", "create", {
7101
+ reportId,
7102
+ projectId,
7103
+ name: name || "",
7104
+ description,
7105
+ report,
7106
+ createdBy
7107
+ });
7108
+ if (result && result.success) {
7109
+ logger.info(`[DB] Report created successfully, ID: ${result.data?.id}`);
7110
+ sendResponse5(id, {
7111
+ success: true,
7112
+ data: {
7113
+ id: result.data?.id,
7114
+ reportId: result.data?.reportId,
7115
+ report: result.data?.report || report,
7116
+ message: `Report created successfully (DB)`
7117
+ }
7118
+ }, sendMessage, clientId);
7119
+ return;
7120
+ }
7121
+ } catch (dbError) {
7122
+ logger.warn(`[DB] Failed to create report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7123
+ }
7124
+ try {
7125
+ if (!report) {
7126
+ report = {};
7127
+ }
6525
7128
  const createdReport = reportManager2.createReport(reportId, report);
7129
+ logger.info(`[FILE] Report '${reportId}' created successfully`);
6526
7130
  sendResponse5(id, {
6527
7131
  success: true,
6528
7132
  data: {
6529
7133
  reportId,
6530
7134
  report: createdReport,
6531
- message: `Report '${reportId}' created successfully`
7135
+ message: `Report '${reportId}' created successfully (File)`
6532
7136
  }
6533
7137
  }, sendMessage, clientId);
6534
7138
  } catch (error) {
@@ -6538,36 +7142,56 @@ async function handleCreate3(id, reportId, report, reportManager2, sendMessage,
6538
7142
  }, sendMessage, clientId);
6539
7143
  }
6540
7144
  }
6541
- async function handleUpdate3(id, reportId, report, reportManager2, sendMessage, clientId) {
6542
- if (!reportId || reportId.trim().length === 0) {
7145
+ async function handleUpdate3(id, numericId, reportId, report, name, description, updatedBy, executeCollection, reportManager2, sendMessage, clientId) {
7146
+ if (!numericId) {
6543
7147
  sendResponse5(id, {
6544
7148
  success: false,
6545
- error: "Report ID is required and cannot be empty"
7149
+ error: "Report ID is required"
6546
7150
  }, sendMessage, clientId);
6547
7151
  return;
6548
7152
  }
6549
- if (!report) {
6550
- sendResponse5(id, {
6551
- success: false,
6552
- error: "Report data is required"
6553
- }, sendMessage, clientId);
6554
- return;
7153
+ try {
7154
+ const result = await executeCollection("reports", "update", {
7155
+ id: numericId,
7156
+ name,
7157
+ description,
7158
+ report,
7159
+ updatedBy
7160
+ });
7161
+ if (result && result.success) {
7162
+ logger.info(`[DB] Report updated successfully, ID: ${numericId}`);
7163
+ sendResponse5(id, {
7164
+ success: true,
7165
+ data: {
7166
+ id: numericId,
7167
+ reportId: result.data?.reportId,
7168
+ report: result.data?.report || report,
7169
+ message: `Report updated successfully (DB)`
7170
+ }
7171
+ }, sendMessage, clientId);
7172
+ return;
7173
+ }
7174
+ } catch (dbError) {
7175
+ logger.warn(`[DB] Failed to update report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6555
7176
  }
7177
+ const fileStorageId = reportId || String(numericId);
6556
7178
  try {
6557
- const updatedReport = reportManager2.updateReport(reportId, report);
7179
+ const updatedReport = reportManager2.updateReport(fileStorageId, report);
6558
7180
  if (!updatedReport) {
6559
7181
  sendResponse5(id, {
6560
7182
  success: false,
6561
- error: `Report '${reportId}' not found`
7183
+ error: `Report '${fileStorageId}' not found`
6562
7184
  }, sendMessage, clientId);
6563
7185
  return;
6564
7186
  }
7187
+ logger.info(`[FILE] Report '${fileStorageId}' updated successfully`);
6565
7188
  sendResponse5(id, {
6566
7189
  success: true,
6567
7190
  data: {
6568
- reportId,
7191
+ id: numericId,
7192
+ reportId: fileStorageId,
6569
7193
  report: updatedReport,
6570
- message: `Report '${reportId}' updated successfully`
7194
+ message: `Report '${fileStorageId}' updated successfully (File)`
6571
7195
  }
6572
7196
  }, sendMessage, clientId);
6573
7197
  } catch (error) {
@@ -6577,65 +7201,154 @@ async function handleUpdate3(id, reportId, report, reportManager2, sendMessage,
6577
7201
  }, sendMessage, clientId);
6578
7202
  }
6579
7203
  }
6580
- async function handleDelete3(id, reportId, reportManager2, sendMessage, clientId) {
6581
- if (!reportId || reportId.trim().length === 0) {
7204
+ async function handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
7205
+ if (!numericId) {
6582
7206
  sendResponse5(id, {
6583
7207
  success: false,
6584
- error: "Report ID is required and cannot be empty"
7208
+ error: "Report ID is required"
6585
7209
  }, sendMessage, clientId);
6586
7210
  return;
6587
7211
  }
6588
- const deleted = reportManager2.deleteReport(reportId);
7212
+ try {
7213
+ const result = await executeCollection("reports", "delete", { id: numericId });
7214
+ if (result && result.success) {
7215
+ logger.info(`[DB] Report deleted successfully, ID: ${numericId}`);
7216
+ sendResponse5(id, {
7217
+ success: true,
7218
+ data: {
7219
+ id: numericId,
7220
+ message: `Report deleted successfully (DB)`
7221
+ }
7222
+ }, sendMessage, clientId);
7223
+ return;
7224
+ }
7225
+ } catch (dbError) {
7226
+ logger.warn(`[DB] Failed to delete report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7227
+ }
7228
+ const fileStorageId = reportId || String(numericId);
7229
+ const deleted = reportManager2.deleteReport(fileStorageId);
6589
7230
  if (!deleted) {
6590
7231
  sendResponse5(id, {
6591
7232
  success: false,
6592
- error: `Report '${reportId}' not found`
7233
+ error: `Report '${fileStorageId}' not found`
6593
7234
  }, sendMessage, clientId);
6594
7235
  return;
6595
7236
  }
7237
+ logger.info(`[FILE] Report '${fileStorageId}' deleted successfully`);
6596
7238
  sendResponse5(id, {
6597
7239
  success: true,
6598
7240
  data: {
6599
- reportId,
6600
- message: `Report '${reportId}' deleted successfully`
7241
+ id: numericId,
7242
+ reportId: fileStorageId,
7243
+ message: `Report '${fileStorageId}' deleted successfully (File)`
6601
7244
  }
6602
7245
  }, sendMessage, clientId);
6603
7246
  }
6604
- async function handleGetAll3(id, reportManager2, sendMessage, clientId) {
7247
+ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage, clientId) {
7248
+ try {
7249
+ const result = await executeCollection("reports", "getAll", {});
7250
+ if (result && result.success) {
7251
+ logger.info(`[DB] Retrieved ${result.count} reports`);
7252
+ sendResponse5(id, {
7253
+ success: true,
7254
+ data: {
7255
+ reports: result.data,
7256
+ count: result.count,
7257
+ message: `Retrieved ${result.count} reports (DB)`
7258
+ }
7259
+ }, sendMessage, clientId);
7260
+ return;
7261
+ }
7262
+ } catch (dbError) {
7263
+ logger.warn(`[DB] Failed to get all reports, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7264
+ }
6605
7265
  const reports = reportManager2.getAllReports();
6606
- logger.info(`Admin retrieved all reports (count: ${reports.length})`);
7266
+ logger.info(`[FILE] Retrieved ${reports.length} reports`);
6607
7267
  sendResponse5(id, {
6608
7268
  success: true,
6609
7269
  data: {
6610
7270
  reports,
6611
7271
  count: reports.length,
6612
- message: `Retrieved ${reports.length} reports`
7272
+ message: `Retrieved ${reports.length} reports (File)`
6613
7273
  }
6614
7274
  }, sendMessage, clientId);
6615
7275
  }
6616
- async function handleGetOne3(id, reportId, reportManager2, sendMessage, clientId) {
6617
- if (!reportId || reportId.trim().length === 0) {
7276
+ async function handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
7277
+ if (!numericId) {
6618
7278
  sendResponse5(id, {
6619
7279
  success: false,
6620
- error: "Report ID is required and cannot be empty"
7280
+ error: "Report ID is required"
6621
7281
  }, sendMessage, clientId);
6622
7282
  return;
6623
7283
  }
6624
- const report = reportManager2.getReport(reportId);
7284
+ try {
7285
+ const result = await executeCollection("reports", "getOne", { id: numericId });
7286
+ if (result && result.success) {
7287
+ logger.info(`[DB] Retrieved report ID: ${numericId}`);
7288
+ sendResponse5(id, {
7289
+ success: true,
7290
+ data: {
7291
+ id: numericId,
7292
+ reportId: result.data?.reportId,
7293
+ report: result.data?.report || result.data,
7294
+ message: `Retrieved report (DB)`
7295
+ }
7296
+ }, sendMessage, clientId);
7297
+ return;
7298
+ }
7299
+ } catch (dbError) {
7300
+ logger.warn(`[DB] Failed to get report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7301
+ }
7302
+ const fileStorageId = reportId || String(numericId);
7303
+ const report = reportManager2.getReport(fileStorageId);
6625
7304
  if (!report) {
6626
7305
  sendResponse5(id, {
6627
7306
  success: false,
6628
- error: `Report '${reportId}' not found`
7307
+ error: `Report '${fileStorageId}' not found`
6629
7308
  }, sendMessage, clientId);
6630
7309
  return;
6631
7310
  }
6632
- logger.info(`Admin retrieved report: ${reportId}`);
7311
+ logger.info(`[FILE] Retrieved report: ${fileStorageId}`);
6633
7312
  sendResponse5(id, {
6634
7313
  success: true,
6635
7314
  data: {
6636
- reportId,
7315
+ id: numericId,
7316
+ reportId: fileStorageId,
6637
7317
  report,
6638
- message: `Retrieved report '${reportId}'`
7318
+ message: `Retrieved report '${fileStorageId}' (File)`
7319
+ }
7320
+ }, sendMessage, clientId);
7321
+ }
7322
+ async function handleQuery3(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, clientId) {
7323
+ try {
7324
+ const result = await executeCollection("reports", "query", {
7325
+ filters: filters || {},
7326
+ limit,
7327
+ sort
7328
+ });
7329
+ if (result && result.success) {
7330
+ logger.info(`[DB] Query returned ${result.count} reports`);
7331
+ sendResponse5(id, {
7332
+ success: true,
7333
+ data: {
7334
+ reports: result.data,
7335
+ count: result.count,
7336
+ message: `Query returned ${result.count} reports (DB)`
7337
+ }
7338
+ }, sendMessage, clientId);
7339
+ return;
7340
+ }
7341
+ } catch (dbError) {
7342
+ logger.warn(`[DB] Failed to query reports: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7343
+ }
7344
+ const reports = reportManager2.getAllReports();
7345
+ logger.info(`[FILE] Retrieved ${reports.length} reports (all - no query filter)`);
7346
+ sendResponse5(id, {
7347
+ success: true,
7348
+ data: {
7349
+ reports,
7350
+ count: reports.length,
7351
+ message: `Retrieved ${reports.length} reports (File - no query filter)`
6639
7352
  }
6640
7353
  }, sendMessage, clientId);
6641
7354
  }
@@ -6655,6 +7368,297 @@ function sendResponse5(id, res, sendMessage, clientId) {
6655
7368
  sendMessage(response);
6656
7369
  }
6657
7370
 
7371
+ // src/handlers/uis.ts
7372
+ async function handleUIsRequest(data, collections, sendMessage) {
7373
+ const executeCollection = async (collection, op, params) => {
7374
+ const handler = collections[collection]?.[op];
7375
+ if (!handler) {
7376
+ throw new Error(`Collection handler not found: ${collection}.${op}`);
7377
+ }
7378
+ return await handler(params);
7379
+ };
7380
+ try {
7381
+ const request = UIsRequestMessageSchema.parse(data);
7382
+ const { id, payload, from } = request;
7383
+ const { operation, data: requestData } = payload;
7384
+ const uiId = requestData?.uiId;
7385
+ const ui = requestData?.ui;
7386
+ const projectId = requestData?.projectId;
7387
+ const name = requestData?.name;
7388
+ const description = requestData?.description;
7389
+ const createdBy = requestData?.createdBy;
7390
+ const updatedBy = requestData?.updatedBy;
7391
+ const numericId = requestData?.id;
7392
+ const filters = requestData?.filters;
7393
+ const limit = requestData?.limit;
7394
+ const sort = requestData?.sort;
7395
+ if (from.type !== "admin") {
7396
+ sendResponse6(id, {
7397
+ success: false,
7398
+ error: "Unauthorized: Only admin can manage UIs"
7399
+ }, sendMessage, from.id);
7400
+ logger.warn(`Unauthorized UI management attempt from: ${from.type}`);
7401
+ return;
7402
+ }
7403
+ switch (operation) {
7404
+ case "create":
7405
+ await handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, from.id);
7406
+ break;
7407
+ case "update":
7408
+ await handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, from.id);
7409
+ break;
7410
+ case "delete":
7411
+ await handleDelete4(id, numericId, executeCollection, sendMessage, from.id);
7412
+ break;
7413
+ case "getAll":
7414
+ await handleGetAll4(id, executeCollection, sendMessage, from.id);
7415
+ break;
7416
+ case "getOne":
7417
+ await handleGetOne4(id, numericId, executeCollection, sendMessage, from.id);
7418
+ break;
7419
+ case "query":
7420
+ await handleQuery4(id, filters, limit, sort, executeCollection, sendMessage, from.id);
7421
+ break;
7422
+ default:
7423
+ sendResponse6(id, {
7424
+ success: false,
7425
+ error: `Unknown operation: ${operation}`
7426
+ }, sendMessage, from.id);
7427
+ }
7428
+ } catch (error) {
7429
+ logger.error("Failed to handle UIs request:", error);
7430
+ sendResponse6(null, {
7431
+ success: false,
7432
+ error: error instanceof Error ? error.message : "Unknown error occurred"
7433
+ }, sendMessage);
7434
+ }
7435
+ }
7436
+ async function handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, clientId) {
7437
+ if (!uiId || uiId.trim().length === 0) {
7438
+ sendResponse6(id, {
7439
+ success: false,
7440
+ error: "UI ID is required and cannot be empty"
7441
+ }, sendMessage, clientId);
7442
+ return;
7443
+ }
7444
+ if (!projectId || projectId.trim().length === 0) {
7445
+ sendResponse6(id, {
7446
+ success: false,
7447
+ error: "Project ID is required and cannot be empty"
7448
+ }, sendMessage, clientId);
7449
+ return;
7450
+ }
7451
+ try {
7452
+ const result = await executeCollection("uis", "create", {
7453
+ uiId,
7454
+ projectId,
7455
+ name: name || uiId,
7456
+ description,
7457
+ ui,
7458
+ createdBy
7459
+ });
7460
+ if (result && result.success) {
7461
+ logger.info(`UI created successfully, ID: ${result.data?.id}`);
7462
+ sendResponse6(id, {
7463
+ success: true,
7464
+ data: {
7465
+ id: result.data?.id,
7466
+ uiId: result.data?.uiId || uiId,
7467
+ ui: result.data?.ui || ui,
7468
+ message: `UI created successfully`
7469
+ }
7470
+ }, sendMessage, clientId);
7471
+ } else {
7472
+ sendResponse6(id, {
7473
+ success: false,
7474
+ error: "Failed to create UI"
7475
+ }, sendMessage, clientId);
7476
+ }
7477
+ } catch (error) {
7478
+ sendResponse6(id, {
7479
+ success: false,
7480
+ error: error instanceof Error ? error.message : "Failed to create UI"
7481
+ }, sendMessage, clientId);
7482
+ }
7483
+ }
7484
+ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, clientId) {
7485
+ if (!numericId) {
7486
+ sendResponse6(id, {
7487
+ success: false,
7488
+ error: "UI ID is required"
7489
+ }, sendMessage, clientId);
7490
+ return;
7491
+ }
7492
+ try {
7493
+ const result = await executeCollection("uis", "update", {
7494
+ id: numericId,
7495
+ name,
7496
+ description,
7497
+ ui,
7498
+ updatedBy
7499
+ });
7500
+ if (result && result.success) {
7501
+ logger.info(`UI updated successfully, ID: ${numericId}`);
7502
+ sendResponse6(id, {
7503
+ success: true,
7504
+ data: {
7505
+ id: numericId,
7506
+ uiId: result.data?.uiId,
7507
+ ui: result.data?.ui || ui,
7508
+ message: `UI updated successfully`
7509
+ }
7510
+ }, sendMessage, clientId);
7511
+ } else {
7512
+ sendResponse6(id, {
7513
+ success: false,
7514
+ error: "Failed to update UI"
7515
+ }, sendMessage, clientId);
7516
+ }
7517
+ } catch (error) {
7518
+ sendResponse6(id, {
7519
+ success: false,
7520
+ error: error instanceof Error ? error.message : "Failed to update UI"
7521
+ }, sendMessage, clientId);
7522
+ }
7523
+ }
7524
+ async function handleDelete4(id, numericId, executeCollection, sendMessage, clientId) {
7525
+ if (!numericId) {
7526
+ sendResponse6(id, {
7527
+ success: false,
7528
+ error: "UI ID is required"
7529
+ }, sendMessage, clientId);
7530
+ return;
7531
+ }
7532
+ try {
7533
+ const result = await executeCollection("uis", "delete", { id: numericId });
7534
+ if (result && result.success) {
7535
+ logger.info(`UI deleted successfully, ID: ${numericId}`);
7536
+ sendResponse6(id, {
7537
+ success: true,
7538
+ data: {
7539
+ id: numericId,
7540
+ message: `UI deleted successfully`
7541
+ }
7542
+ }, sendMessage, clientId);
7543
+ } else {
7544
+ sendResponse6(id, {
7545
+ success: false,
7546
+ error: "Failed to delete UI"
7547
+ }, sendMessage, clientId);
7548
+ }
7549
+ } catch (error) {
7550
+ sendResponse6(id, {
7551
+ success: false,
7552
+ error: error instanceof Error ? error.message : "Failed to delete UI"
7553
+ }, sendMessage, clientId);
7554
+ }
7555
+ }
7556
+ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
7557
+ try {
7558
+ const result = await executeCollection("uis", "getAll", {});
7559
+ if (result && result.success) {
7560
+ logger.info(`Retrieved ${result.count} UIs`);
7561
+ sendResponse6(id, {
7562
+ success: true,
7563
+ data: {
7564
+ uis: result.data,
7565
+ count: result.count,
7566
+ message: `Retrieved ${result.count} UIs`
7567
+ }
7568
+ }, sendMessage, clientId);
7569
+ } else {
7570
+ sendResponse6(id, {
7571
+ success: false,
7572
+ error: "Failed to get UIs"
7573
+ }, sendMessage, clientId);
7574
+ }
7575
+ } catch (error) {
7576
+ sendResponse6(id, {
7577
+ success: false,
7578
+ error: error instanceof Error ? error.message : "Failed to get UIs"
7579
+ }, sendMessage, clientId);
7580
+ }
7581
+ }
7582
+ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clientId) {
7583
+ if (!numericId) {
7584
+ sendResponse6(id, {
7585
+ success: false,
7586
+ error: "UI ID is required"
7587
+ }, sendMessage, clientId);
7588
+ return;
7589
+ }
7590
+ try {
7591
+ const result = await executeCollection("uis", "getOne", { id: numericId });
7592
+ if (result && result.success) {
7593
+ logger.info(`Retrieved UI ID: ${numericId}`);
7594
+ sendResponse6(id, {
7595
+ success: true,
7596
+ data: {
7597
+ id: numericId,
7598
+ uiId: result.data?.uiId,
7599
+ ui: result.data?.ui || result.data,
7600
+ message: `Retrieved UI`
7601
+ }
7602
+ }, sendMessage, clientId);
7603
+ } else {
7604
+ sendResponse6(id, {
7605
+ success: false,
7606
+ error: `UI not found`
7607
+ }, sendMessage, clientId);
7608
+ }
7609
+ } catch (error) {
7610
+ sendResponse6(id, {
7611
+ success: false,
7612
+ error: error instanceof Error ? error.message : "Failed to get UI"
7613
+ }, sendMessage, clientId);
7614
+ }
7615
+ }
7616
+ async function handleQuery4(id, filters, limit, sort, executeCollection, sendMessage, clientId) {
7617
+ try {
7618
+ const result = await executeCollection("uis", "query", {
7619
+ filters: filters || {},
7620
+ limit,
7621
+ sort
7622
+ });
7623
+ if (result && result.success) {
7624
+ logger.info(`Query returned ${result.count} UIs`);
7625
+ sendResponse6(id, {
7626
+ success: true,
7627
+ data: {
7628
+ uis: result.data,
7629
+ count: result.count,
7630
+ message: `Query returned ${result.count} UIs`
7631
+ }
7632
+ }, sendMessage, clientId);
7633
+ } else {
7634
+ sendResponse6(id, {
7635
+ success: false,
7636
+ error: "Failed to query UIs"
7637
+ }, sendMessage, clientId);
7638
+ }
7639
+ } catch (error) {
7640
+ sendResponse6(id, {
7641
+ success: false,
7642
+ error: error instanceof Error ? error.message : "Failed to query UIs"
7643
+ }, sendMessage, clientId);
7644
+ }
7645
+ }
7646
+ function sendResponse6(id, res, sendMessage, clientId) {
7647
+ const response = {
7648
+ id: id || "unknown",
7649
+ type: "UIS_RES",
7650
+ from: { type: "data-agent" },
7651
+ to: {
7652
+ type: "admin",
7653
+ id: clientId
7654
+ },
7655
+ payload: {
7656
+ ...res
7657
+ }
7658
+ };
7659
+ sendMessage(response);
7660
+ }
7661
+
6658
7662
  // src/handlers/bookmarks.ts
6659
7663
  async function handleBookmarksRequest(data, collections, sendMessage) {
6660
7664
  const executeCollection = async (collection, op, params) => {
@@ -6671,22 +7675,27 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
6671
7675
  const bookmarkId = requestData?.id;
6672
7676
  const userId = requestData?.userId;
6673
7677
  const threadId = requestData?.threadId;
7678
+ const name = requestData?.name;
7679
+ const description = requestData?.description;
6674
7680
  const uiblock = requestData?.uiblock;
7681
+ const filters = requestData?.filters;
7682
+ const limit = requestData?.limit;
7683
+ const sort = requestData?.sort;
6675
7684
  switch (operation) {
6676
7685
  case "create":
6677
- await handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, from.id);
7686
+ await handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, from.id);
6678
7687
  break;
6679
7688
  case "update":
6680
- await handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, from.id);
7689
+ await handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, from.id);
6681
7690
  break;
6682
7691
  case "delete":
6683
- await handleDelete4(id, bookmarkId, executeCollection, sendMessage, from.id);
7692
+ await handleDelete5(id, bookmarkId, executeCollection, sendMessage, from.id);
6684
7693
  break;
6685
7694
  case "getAll":
6686
- await handleGetAll4(id, executeCollection, sendMessage, from.id);
7695
+ await handleGetAll5(id, executeCollection, sendMessage, from.id);
6687
7696
  break;
6688
7697
  case "getOne":
6689
- await handleGetOne4(id, bookmarkId, executeCollection, sendMessage, from.id);
7698
+ await handleGetOne5(id, bookmarkId, executeCollection, sendMessage, from.id);
6690
7699
  break;
6691
7700
  case "getByUser":
6692
7701
  await handleGetByUser(id, userId, threadId, executeCollection, sendMessage, from.id);
@@ -6694,83 +7703,79 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
6694
7703
  case "getByThread":
6695
7704
  await handleGetByThread(id, threadId, executeCollection, sendMessage, from.id);
6696
7705
  break;
7706
+ case "query":
7707
+ await handleQuery5(id, filters, limit, sort, executeCollection, sendMessage, from.id);
7708
+ break;
6697
7709
  default:
6698
- sendResponse6(id, {
7710
+ sendResponse7(id, {
6699
7711
  success: false,
6700
7712
  error: `Unknown operation: ${operation}`
6701
7713
  }, sendMessage, from.id);
6702
7714
  }
6703
7715
  } catch (error) {
6704
7716
  logger.error("Failed to handle bookmarks request:", error);
6705
- sendResponse6(null, {
7717
+ sendResponse7(null, {
6706
7718
  success: false,
6707
7719
  error: error instanceof Error ? error.message : "Unknown error occurred"
6708
7720
  }, sendMessage);
6709
7721
  }
6710
7722
  }
6711
- async function handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, clientId) {
7723
+ async function handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
6712
7724
  if (!userId) {
6713
- sendResponse6(id, {
7725
+ sendResponse7(id, {
6714
7726
  success: false,
6715
7727
  error: "userId is required"
6716
7728
  }, sendMessage, clientId);
6717
7729
  return;
6718
7730
  }
6719
7731
  if (!uiblock) {
6720
- sendResponse6(id, {
7732
+ sendResponse7(id, {
6721
7733
  success: false,
6722
7734
  error: "UIBlock data is required"
6723
7735
  }, sendMessage, clientId);
6724
7736
  return;
6725
7737
  }
6726
7738
  try {
6727
- const result = await executeCollection("bookmarks", "create", { userId, threadId, uiblock });
6728
- sendResponse6(id, {
7739
+ const result = await executeCollection("bookmarks", "create", { userId, threadId, name, description, uiblock });
7740
+ sendResponse7(id, {
6729
7741
  success: true,
6730
7742
  data: result.data,
6731
7743
  message: "Bookmark created successfully"
6732
7744
  }, sendMessage, clientId);
6733
7745
  logger.info(`Bookmark created: ID ${result.data.id}`);
6734
7746
  } catch (error) {
6735
- sendResponse6(id, {
7747
+ sendResponse7(id, {
6736
7748
  success: false,
6737
7749
  error: error instanceof Error ? error.message : "Failed to create bookmark"
6738
7750
  }, sendMessage, clientId);
6739
7751
  }
6740
7752
  }
6741
- async function handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, clientId) {
7753
+ async function handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
6742
7754
  if (!bookmarkId) {
6743
- sendResponse6(id, {
7755
+ sendResponse7(id, {
6744
7756
  success: false,
6745
7757
  error: "Bookmark ID is required"
6746
7758
  }, sendMessage, clientId);
6747
7759
  return;
6748
7760
  }
6749
- if (!uiblock) {
6750
- sendResponse6(id, {
6751
- success: false,
6752
- error: "UIBlock data is required"
6753
- }, sendMessage, clientId);
6754
- return;
6755
- }
6756
7761
  try {
6757
- const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, uiblock });
6758
- sendResponse6(id, {
7762
+ const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, name, description, uiblock });
7763
+ sendResponse7(id, {
6759
7764
  success: true,
6760
7765
  data: result.data,
6761
7766
  message: "Bookmark updated successfully"
6762
7767
  }, sendMessage, clientId);
6763
7768
  logger.info(`Bookmark updated: ID ${bookmarkId}`);
6764
7769
  } catch (error) {
6765
- sendResponse6(id, {
7770
+ sendResponse7(id, {
6766
7771
  success: false,
6767
7772
  error: error instanceof Error ? error.message : "Failed to update bookmark"
6768
7773
  }, sendMessage, clientId);
6769
7774
  }
6770
7775
  }
6771
- async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, clientId) {
7776
+ async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, clientId) {
6772
7777
  if (!bookmarkId) {
6773
- sendResponse6(id, {
7778
+ sendResponse7(id, {
6774
7779
  success: false,
6775
7780
  error: "Bookmark ID is required"
6776
7781
  }, sendMessage, clientId);
@@ -6778,23 +7783,23 @@ async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, cli
6778
7783
  }
6779
7784
  try {
6780
7785
  const result = await executeCollection("bookmarks", "delete", { id: bookmarkId });
6781
- sendResponse6(id, {
7786
+ sendResponse7(id, {
6782
7787
  success: true,
6783
7788
  data: result.data,
6784
7789
  message: "Bookmark deleted successfully"
6785
7790
  }, sendMessage, clientId);
6786
7791
  logger.info(`Bookmark deleted: ID ${bookmarkId}`);
6787
7792
  } catch (error) {
6788
- sendResponse6(id, {
7793
+ sendResponse7(id, {
6789
7794
  success: false,
6790
7795
  error: error instanceof Error ? error.message : "Failed to delete bookmark"
6791
7796
  }, sendMessage, clientId);
6792
7797
  }
6793
7798
  }
6794
- async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
7799
+ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
6795
7800
  try {
6796
7801
  const result = await executeCollection("bookmarks", "getAll", {});
6797
- sendResponse6(id, {
7802
+ sendResponse7(id, {
6798
7803
  success: true,
6799
7804
  data: result.data,
6800
7805
  count: result.count,
@@ -6802,15 +7807,15 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
6802
7807
  }, sendMessage, clientId);
6803
7808
  logger.info(`Retrieved all bookmarks (count: ${result.count})`);
6804
7809
  } catch (error) {
6805
- sendResponse6(id, {
7810
+ sendResponse7(id, {
6806
7811
  success: false,
6807
7812
  error: error instanceof Error ? error.message : "Failed to get bookmarks"
6808
7813
  }, sendMessage, clientId);
6809
7814
  }
6810
7815
  }
6811
- async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, clientId) {
7816
+ async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, clientId) {
6812
7817
  if (!bookmarkId) {
6813
- sendResponse6(id, {
7818
+ sendResponse7(id, {
6814
7819
  success: false,
6815
7820
  error: "Bookmark ID is required"
6816
7821
  }, sendMessage, clientId);
@@ -6818,14 +7823,14 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
6818
7823
  }
6819
7824
  try {
6820
7825
  const result = await executeCollection("bookmarks", "getOne", { id: bookmarkId });
6821
- sendResponse6(id, {
7826
+ sendResponse7(id, {
6822
7827
  success: true,
6823
7828
  data: result.data,
6824
7829
  message: `Retrieved bookmark ID ${bookmarkId}`
6825
7830
  }, sendMessage, clientId);
6826
7831
  logger.info(`Retrieved bookmark: ID ${bookmarkId}`);
6827
7832
  } catch (error) {
6828
- sendResponse6(id, {
7833
+ sendResponse7(id, {
6829
7834
  success: false,
6830
7835
  error: error instanceof Error ? error.message : "Failed to get bookmark"
6831
7836
  }, sendMessage, clientId);
@@ -6833,7 +7838,7 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
6833
7838
  }
6834
7839
  async function handleGetByUser(id, userId, threadId, executeCollection, sendMessage, clientId) {
6835
7840
  if (!userId) {
6836
- sendResponse6(id, {
7841
+ sendResponse7(id, {
6837
7842
  success: false,
6838
7843
  error: "userId is required"
6839
7844
  }, sendMessage, clientId);
@@ -6841,7 +7846,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6841
7846
  }
6842
7847
  try {
6843
7848
  const result = await executeCollection("bookmarks", "getByUser", { userId, threadId });
6844
- sendResponse6(id, {
7849
+ sendResponse7(id, {
6845
7850
  success: true,
6846
7851
  data: result.data,
6847
7852
  count: result.count,
@@ -6849,7 +7854,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6849
7854
  }, sendMessage, clientId);
6850
7855
  logger.info(`Retrieved bookmarks for user ${userId} (count: ${result.count})`);
6851
7856
  } catch (error) {
6852
- sendResponse6(id, {
7857
+ sendResponse7(id, {
6853
7858
  success: false,
6854
7859
  error: error instanceof Error ? error.message : "Failed to get bookmarks by user"
6855
7860
  }, sendMessage, clientId);
@@ -6857,7 +7862,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6857
7862
  }
6858
7863
  async function handleGetByThread(id, threadId, executeCollection, sendMessage, clientId) {
6859
7864
  if (!threadId) {
6860
- sendResponse6(id, {
7865
+ sendResponse7(id, {
6861
7866
  success: false,
6862
7867
  error: "threadId is required"
6863
7868
  }, sendMessage, clientId);
@@ -6865,7 +7870,7 @@ async function handleGetByThread(id, threadId, executeCollection, sendMessage, c
6865
7870
  }
6866
7871
  try {
6867
7872
  const result = await executeCollection("bookmarks", "getByThread", { threadId });
6868
- sendResponse6(id, {
7873
+ sendResponse7(id, {
6869
7874
  success: true,
6870
7875
  data: result.data,
6871
7876
  count: result.count,
@@ -6873,13 +7878,34 @@ async function handleGetByThread(id, threadId, executeCollection, sendMessage, c
6873
7878
  }, sendMessage, clientId);
6874
7879
  logger.info(`Retrieved bookmarks for thread ${threadId} (count: ${result.count})`);
6875
7880
  } catch (error) {
6876
- sendResponse6(id, {
7881
+ sendResponse7(id, {
6877
7882
  success: false,
6878
7883
  error: error instanceof Error ? error.message : "Failed to get bookmarks by thread"
6879
7884
  }, sendMessage, clientId);
6880
7885
  }
6881
7886
  }
6882
- function sendResponse6(id, res, sendMessage, clientId) {
7887
+ async function handleQuery5(id, filters, limit, sort, executeCollection, sendMessage, clientId) {
7888
+ try {
7889
+ const result = await executeCollection("bookmarks", "query", {
7890
+ filters: filters || {},
7891
+ limit,
7892
+ sort
7893
+ });
7894
+ sendResponse7(id, {
7895
+ success: true,
7896
+ data: result.data,
7897
+ count: result.count,
7898
+ message: `Query returned ${result.count} bookmarks`
7899
+ }, sendMessage, clientId);
7900
+ logger.info(`Query returned ${result.count} bookmarks`);
7901
+ } catch (error) {
7902
+ sendResponse7(id, {
7903
+ success: false,
7904
+ error: error instanceof Error ? error.message : "Failed to query bookmarks"
7905
+ }, sendMessage, clientId);
7906
+ }
7907
+ }
7908
+ function sendResponse7(id, res, sendMessage, clientId) {
6883
7909
  const response = {
6884
7910
  id: id || "unknown",
6885
7911
  type: "BOOKMARKS_RES",
@@ -7890,30 +8916,35 @@ var SuperatomSDK = class {
7890
8916
  });
7891
8917
  break;
7892
8918
  case "USER_PROMPT_SUGGESTIONS_REQ":
7893
- handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg)).catch((error) => {
8919
+ handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg), this.collections, this.userId).catch((error) => {
7894
8920
  logger.error("Failed to handle user prompt suggestions request:", error);
7895
8921
  });
7896
8922
  break;
7897
8923
  case "COMPONENT_LIST_RES":
7898
- handleComponentListResponse(parsed, (com) => this.storeComponents(com)).catch((error) => {
8924
+ handleComponentListResponse(parsed, (com) => this.storeComponents(com), this.collections).catch((error) => {
7899
8925
  logger.error("Failed to handle component list request:", error);
7900
8926
  });
7901
8927
  break;
7902
8928
  case "USERS":
7903
- handleUsersRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8929
+ handleUsersRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7904
8930
  logger.error("Failed to handle users request:", error);
7905
8931
  });
7906
8932
  break;
7907
8933
  case "DASHBOARDS":
7908
- handleDashboardsRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8934
+ handleDashboardsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7909
8935
  logger.error("Failed to handle dashboards request:", error);
7910
8936
  });
7911
8937
  break;
7912
8938
  case "REPORTS":
7913
- handleReportsRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8939
+ handleReportsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7914
8940
  logger.error("Failed to handle reports request:", error);
7915
8941
  });
7916
8942
  break;
8943
+ case "UIS":
8944
+ handleUIsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
8945
+ logger.error("Failed to handle UIs request:", error);
8946
+ });
8947
+ break;
7917
8948
  case "BOOKMARKS":
7918
8949
  handleBookmarksRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7919
8950
  logger.error("Failed to handle bookmarks request:", error);