@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.js CHANGED
@@ -451,7 +451,8 @@ var UserPromptRequestMessageSchema = import_zod3.z.object({
451
451
  });
452
452
  var UserPromptSuggestionsPayloadSchema = import_zod3.z.object({
453
453
  prompt: import_zod3.z.string(),
454
- limit: import_zod3.z.number().int().positive().default(5)
454
+ limit: import_zod3.z.number().int().positive().default(5),
455
+ similarityThreshold: import_zod3.z.number().min(0).max(1).default(0.4)
455
456
  });
456
457
  var UserPromptSuggestionsMessageSchema = import_zod3.z.object({
457
458
  id: import_zod3.z.string(),
@@ -494,14 +495,25 @@ var ToolSchema = import_zod3.z.object({
494
495
  params: import_zod3.z.record(import_zod3.z.string()),
495
496
  fn: import_zod3.z.function().args(import_zod3.z.any()).returns(import_zod3.z.any())
496
497
  });
498
+ var UserQueryFiltersSchema = import_zod3.z.object({
499
+ username: import_zod3.z.string().optional(),
500
+ email: import_zod3.z.string().optional(),
501
+ role: import_zod3.z.string().optional(),
502
+ fullname: import_zod3.z.string().optional()
503
+ });
497
504
  var UsersRequestPayloadSchema = import_zod3.z.object({
498
- operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne"]),
505
+ operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
499
506
  data: import_zod3.z.object({
507
+ id: import_zod3.z.number().optional(),
500
508
  username: import_zod3.z.string().optional(),
501
509
  email: import_zod3.z.string().email("Invalid email format").optional(),
502
510
  password: import_zod3.z.string().optional(),
503
511
  fullname: import_zod3.z.string().optional(),
504
- role: import_zod3.z.string().optional()
512
+ role: import_zod3.z.string().optional(),
513
+ // Query operation fields
514
+ filters: UserQueryFiltersSchema.optional(),
515
+ limit: import_zod3.z.number().optional(),
516
+ sort: import_zod3.z.enum(["ASC", "DESC"]).optional()
505
517
  }).optional()
506
518
  });
507
519
  var UsersRequestMessageSchema = import_zod3.z.object({
@@ -538,11 +550,28 @@ var ActionsRequestMessageSchema = import_zod3.z.object({
538
550
  type: import_zod3.z.literal("ACTIONS"),
539
551
  payload: ActionsRequestPayloadSchema
540
552
  });
553
+ var DashboardQueryFiltersSchema = import_zod3.z.object({
554
+ dashboardId: import_zod3.z.string().optional(),
555
+ projectId: import_zod3.z.string().optional(),
556
+ createdBy: import_zod3.z.number().optional(),
557
+ updatedBy: import_zod3.z.number().optional(),
558
+ name: import_zod3.z.string().optional()
559
+ });
541
560
  var DashboardsRequestPayloadSchema = import_zod3.z.object({
542
- operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne"]),
561
+ operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
543
562
  data: import_zod3.z.object({
563
+ id: import_zod3.z.number().optional(),
544
564
  dashboardId: import_zod3.z.string().optional(),
545
- dashboard: DSLRendererPropsSchema.optional()
565
+ projectId: import_zod3.z.string().optional(),
566
+ name: import_zod3.z.string().optional(),
567
+ description: import_zod3.z.string().optional(),
568
+ createdBy: import_zod3.z.number().optional(),
569
+ updatedBy: import_zod3.z.number().optional(),
570
+ dashboard: DSLRendererPropsSchema.optional(),
571
+ // Query operation fields
572
+ filters: DashboardQueryFiltersSchema.optional(),
573
+ limit: import_zod3.z.number().optional(),
574
+ sort: import_zod3.z.enum(["ASC", "DESC"]).optional()
546
575
  }).optional()
547
576
  });
548
577
  var DashboardsRequestMessageSchema = import_zod3.z.object({
@@ -551,11 +580,28 @@ var DashboardsRequestMessageSchema = import_zod3.z.object({
551
580
  type: import_zod3.z.literal("DASHBOARDS"),
552
581
  payload: DashboardsRequestPayloadSchema
553
582
  });
583
+ var ReportQueryFiltersSchema = import_zod3.z.object({
584
+ reportId: import_zod3.z.string().optional(),
585
+ projectId: import_zod3.z.string().optional(),
586
+ createdBy: import_zod3.z.number().optional(),
587
+ updatedBy: import_zod3.z.number().optional(),
588
+ name: import_zod3.z.string().optional()
589
+ });
554
590
  var ReportsRequestPayloadSchema = import_zod3.z.object({
555
- operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne"]),
591
+ operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
556
592
  data: import_zod3.z.object({
593
+ id: import_zod3.z.number().optional(),
557
594
  reportId: import_zod3.z.string().optional(),
558
- report: DSLRendererPropsSchema2.optional()
595
+ projectId: import_zod3.z.string().optional(),
596
+ name: import_zod3.z.string().optional(),
597
+ description: import_zod3.z.string().optional(),
598
+ createdBy: import_zod3.z.number().optional(),
599
+ updatedBy: import_zod3.z.number().optional(),
600
+ report: DSLRendererPropsSchema2.optional(),
601
+ // Query operation fields
602
+ filters: ReportQueryFiltersSchema.optional(),
603
+ limit: import_zod3.z.number().optional(),
604
+ sort: import_zod3.z.enum(["ASC", "DESC"]).optional()
559
605
  }).optional()
560
606
  });
561
607
  var ReportsRequestMessageSchema = import_zod3.z.object({
@@ -564,6 +610,36 @@ var ReportsRequestMessageSchema = import_zod3.z.object({
564
610
  type: import_zod3.z.literal("REPORTS"),
565
611
  payload: ReportsRequestPayloadSchema
566
612
  });
613
+ var UIQueryFiltersSchema = import_zod3.z.object({
614
+ uiId: import_zod3.z.string().optional(),
615
+ projectId: import_zod3.z.string().optional(),
616
+ createdBy: import_zod3.z.number().optional(),
617
+ updatedBy: import_zod3.z.number().optional(),
618
+ name: import_zod3.z.string().optional()
619
+ });
620
+ var UIsRequestPayloadSchema = import_zod3.z.object({
621
+ operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
622
+ data: import_zod3.z.object({
623
+ id: import_zod3.z.number().optional(),
624
+ uiId: import_zod3.z.string().optional(),
625
+ projectId: import_zod3.z.string().optional(),
626
+ name: import_zod3.z.string().optional(),
627
+ description: import_zod3.z.string().optional(),
628
+ createdBy: import_zod3.z.number().optional(),
629
+ updatedBy: import_zod3.z.number().optional(),
630
+ ui: DSLRendererPropsSchema.optional(),
631
+ // Query operation fields
632
+ filters: UIQueryFiltersSchema.optional(),
633
+ limit: import_zod3.z.number().optional(),
634
+ sort: import_zod3.z.enum(["ASC", "DESC"]).optional()
635
+ }).optional()
636
+ });
637
+ var UIsRequestMessageSchema = import_zod3.z.object({
638
+ id: import_zod3.z.string(),
639
+ from: MessageParticipantSchema,
640
+ type: import_zod3.z.literal("UIS"),
641
+ payload: UIsRequestPayloadSchema
642
+ });
567
643
  var UIBlockSchema = import_zod3.z.object({
568
644
  id: import_zod3.z.string().optional(),
569
645
  userQuestion: import_zod3.z.string().optional(),
@@ -587,20 +663,37 @@ var UIBlockSchema = import_zod3.z.object({
587
663
  similarity: import_zod3.z.number().optional()
588
664
  }).optional()
589
665
  });
666
+ var DBUIBlockSchema = import_zod3.z.object({
667
+ id: import_zod3.z.string(),
668
+ component: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.any()).nullable(),
669
+ analysis: import_zod3.z.string().nullable(),
670
+ user_prompt: import_zod3.z.string()
671
+ });
590
672
  var BookmarkDataSchema = import_zod3.z.object({
591
673
  id: import_zod3.z.number().optional(),
592
- uiblock: import_zod3.z.any(),
593
- // JSON object
674
+ uiblock: DBUIBlockSchema,
675
+ // Typed JSON object
594
676
  created_at: import_zod3.z.string().optional(),
595
677
  updated_at: import_zod3.z.string().optional()
596
678
  });
679
+ var BookmarkQueryFiltersSchema = import_zod3.z.object({
680
+ userId: import_zod3.z.number().optional(),
681
+ threadId: import_zod3.z.string().optional(),
682
+ name: import_zod3.z.string().optional()
683
+ });
597
684
  var BookmarksRequestPayloadSchema = import_zod3.z.object({
598
- operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "getByUser", "getByThread"]),
685
+ operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "getByUser", "getByThread", "query"]),
599
686
  data: import_zod3.z.object({
600
687
  id: import_zod3.z.number().optional(),
601
688
  userId: import_zod3.z.number().optional(),
602
689
  threadId: import_zod3.z.string().optional(),
603
- uiblock: import_zod3.z.any().optional()
690
+ name: import_zod3.z.string().optional(),
691
+ description: import_zod3.z.string().optional(),
692
+ uiblock: DBUIBlockSchema.optional(),
693
+ // Query operation fields
694
+ filters: BookmarkQueryFiltersSchema.optional(),
695
+ limit: import_zod3.z.number().optional(),
696
+ sort: import_zod3.z.enum(["ASC", "DESC"]).optional()
604
697
  }).optional()
605
698
  });
606
699
  var BookmarksRequestMessageSchema = import_zod3.z.object({
@@ -5626,12 +5719,13 @@ function sendDataResponse4(id, res, sendMessage, clientId) {
5626
5719
  }
5627
5720
 
5628
5721
  // src/handlers/user-prompt-suggestions.ts
5629
- async function handleUserPromptSuggestions(data, components, sendMessage) {
5722
+ async function handleUserPromptSuggestions(data, components, sendMessage, collections, userId) {
5630
5723
  try {
5631
5724
  const request = UserPromptSuggestionsMessageSchema.parse(data);
5632
5725
  const { id, payload, from } = request;
5633
5726
  const { prompt, limit = 5 } = payload;
5634
5727
  const wsId = from.id;
5728
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Processing user prompt suggestions: ${prompt}`);
5635
5729
  if (!prompt || prompt.trim().length === 0) {
5636
5730
  sendResponse(id, {
5637
5731
  success: false,
@@ -5639,7 +5733,73 @@ async function handleUserPromptSuggestions(data, components, sendMessage) {
5639
5733
  }, sendMessage, wsId);
5640
5734
  return;
5641
5735
  }
5736
+ const componentSearchHandler = collections?.["components"]?.["search"];
5737
+ const bookmarkSearchHandler = collections?.["bookmarks"]?.["search"];
5738
+ let componentSuggestions = [];
5739
+ let bookmarkSuggestions = [];
5740
+ let useEmbeddingSearch = false;
5741
+ const searchPromises = [];
5742
+ if (componentSearchHandler) {
5743
+ searchPromises.push(
5744
+ (async () => {
5745
+ try {
5746
+ logger.info("Using embedding-based search for components");
5747
+ const result = await componentSearchHandler({ prompt, limit });
5748
+ if (result.success && result.suggestions) {
5749
+ componentSuggestions = result.suggestions.map((s) => ({
5750
+ ...s,
5751
+ suggestionType: "component"
5752
+ }));
5753
+ useEmbeddingSearch = true;
5754
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Found ${componentSuggestions.length} component suggestions`);
5755
+ }
5756
+ } catch (embeddingError) {
5757
+ logger.warn("Component embedding search failed:", embeddingError);
5758
+ }
5759
+ })()
5760
+ );
5761
+ }
5762
+ if (bookmarkSearchHandler && userId && userId !== "anonymous") {
5763
+ searchPromises.push(
5764
+ (async () => {
5765
+ try {
5766
+ logger.info(`Using embedding-based search for bookmarks (user: ${userId})`);
5767
+ const result = await bookmarkSearchHandler({ prompt, userId, limit });
5768
+ if (result.success && result.suggestions) {
5769
+ bookmarkSuggestions = result.suggestions.map((s) => ({
5770
+ ...s,
5771
+ suggestionType: "bookmark"
5772
+ }));
5773
+ useEmbeddingSearch = true;
5774
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Found ${bookmarkSuggestions.length} bookmark suggestions`);
5775
+ }
5776
+ } catch (embeddingError) {
5777
+ logger.warn("Bookmark embedding search failed:", embeddingError);
5778
+ }
5779
+ })()
5780
+ );
5781
+ }
5782
+ if (searchPromises.length > 0) {
5783
+ await Promise.all(searchPromises);
5784
+ }
5785
+ if (useEmbeddingSearch && (componentSuggestions.length > 0 || bookmarkSuggestions.length > 0)) {
5786
+ const allSuggestions = [...componentSuggestions, ...bookmarkSuggestions].sort((a, b) => (b.similarity || 0) - (a.similarity || 0)).slice(0, limit);
5787
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Returning all suggestions: ${componentSuggestions.length} components, ${bookmarkSuggestions.length} bookmarks`);
5788
+ sendResponse(id, {
5789
+ success: true,
5790
+ data: {
5791
+ prompt,
5792
+ suggestions: allSuggestions,
5793
+ count: allSuggestions.length,
5794
+ componentCount: componentSuggestions.length,
5795
+ bookmarkCount: bookmarkSuggestions.length,
5796
+ message: `Found ${allSuggestions.length} suggestions (${componentSuggestions.length} components, ${bookmarkSuggestions.length} bookmarks)`
5797
+ }
5798
+ }, sendMessage, wsId);
5799
+ return;
5800
+ }
5642
5801
  const displayComponents = components.filter((c) => c.isDisplayComp === true);
5802
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Using token-based approach. Display components: ${displayComponents.length}`);
5643
5803
  if (!displayComponents || displayComponents.length === 0) {
5644
5804
  sendResponse(id, {
5645
5805
  success: true,
@@ -5977,10 +6137,10 @@ function sendResponse2(id, res, sendMessage, clientId) {
5977
6137
  }
5978
6138
 
5979
6139
  // src/handlers/components-list-response.ts
5980
- async function handleComponentListResponse(data, storeComponents) {
6140
+ async function handleComponentListResponse(data, storeComponents, collections) {
5981
6141
  try {
5982
6142
  const componentListResponse = ComponentListResponseMessageSchema.parse(data);
5983
- const { id, payload } = componentListResponse;
6143
+ const { payload } = componentListResponse;
5984
6144
  const componentsList = payload.components;
5985
6145
  if (!componentsList) {
5986
6146
  logger.error("Components list not found in the response");
@@ -5988,6 +6148,20 @@ async function handleComponentListResponse(data, storeComponents) {
5988
6148
  }
5989
6149
  const components = ComponentsSchema.parse(componentsList);
5990
6150
  storeComponents(components);
6151
+ const embedHandler = collections?.["components"]?.["embed"];
6152
+ if (embedHandler) {
6153
+ try {
6154
+ logger.info("Embedding display components for semantic search...");
6155
+ const result = await embedHandler({ components });
6156
+ if (result.success) {
6157
+ logger.info(`Successfully embedded ${result.count} display components`);
6158
+ } else {
6159
+ logger.warn("Failed to embed components:", result.error);
6160
+ }
6161
+ } catch (embedError) {
6162
+ logger.warn("Failed to embed components:", embedError);
6163
+ }
6164
+ }
5991
6165
  return;
5992
6166
  } catch (error) {
5993
6167
  logger.error("Failed to handle user prompt request:", error);
@@ -5995,17 +6169,28 @@ async function handleComponentListResponse(data, storeComponents) {
5995
6169
  }
5996
6170
 
5997
6171
  // src/handlers/users.ts
5998
- async function handleUsersRequest(data, sendMessage) {
6172
+ async function handleUsersRequest(data, collections, sendMessage) {
6173
+ const executeCollection = async (collection, op, params) => {
6174
+ const handler = collections[collection]?.[op];
6175
+ if (!handler) {
6176
+ return null;
6177
+ }
6178
+ return await handler(params);
6179
+ };
5999
6180
  try {
6000
6181
  const request = UsersRequestMessageSchema.parse(data);
6001
6182
  const { id, payload, from } = request;
6002
6183
  const { operation, data: requestData } = payload;
6184
+ const numericId = requestData?.id;
6003
6185
  const username = requestData?.username;
6004
6186
  const email = requestData?.email;
6005
6187
  const password = requestData?.password;
6006
6188
  const fullname = requestData?.fullname;
6007
6189
  const role = requestData?.role;
6008
- if (from.type !== "admin") {
6190
+ const filters = requestData?.filters;
6191
+ const limit = requestData?.limit;
6192
+ const sort = requestData?.sort;
6193
+ if (from.type !== "admin" && operation !== "getOne" && operation !== "getAll" && operation !== "query") {
6009
6194
  sendResponse3(id, {
6010
6195
  success: false,
6011
6196
  error: "Unauthorized: Only admin can manage users"
@@ -6016,19 +6201,22 @@ async function handleUsersRequest(data, sendMessage) {
6016
6201
  const userManager = getUserManager();
6017
6202
  switch (operation) {
6018
6203
  case "create":
6019
- await handleCreate(id, { username, email, password, fullname, role }, userManager, sendMessage, from.id);
6204
+ await handleCreate(id, { username, email, password, fullname, role }, executeCollection, userManager, sendMessage, from.id);
6020
6205
  break;
6021
6206
  case "update":
6022
- await handleUpdate(id, { username, email, password, fullname, role }, userManager, sendMessage, from.id);
6207
+ await handleUpdate(id, numericId, { username, email, password, fullname, role }, executeCollection, userManager, sendMessage, from.id);
6023
6208
  break;
6024
6209
  case "delete":
6025
- await handleDelete(id, username, userManager, sendMessage, from.id);
6210
+ await handleDelete(id, numericId, username, executeCollection, userManager, sendMessage, from.id);
6026
6211
  break;
6027
6212
  case "getAll":
6028
- await handleGetAll(id, userManager, sendMessage, from.id);
6213
+ await handleGetAll(id, executeCollection, userManager, sendMessage, from.id);
6029
6214
  break;
6030
6215
  case "getOne":
6031
- await handleGetOne(id, username, userManager, sendMessage, from.id);
6216
+ await handleGetOne(id, numericId, username, executeCollection, userManager, sendMessage, from.id);
6217
+ break;
6218
+ case "query":
6219
+ await handleQuery(id, filters, limit, sort, executeCollection, userManager, sendMessage, from.id);
6032
6220
  break;
6033
6221
  default:
6034
6222
  sendResponse3(id, {
@@ -6044,7 +6232,7 @@ async function handleUsersRequest(data, sendMessage) {
6044
6232
  }, sendMessage);
6045
6233
  }
6046
6234
  }
6047
- async function handleCreate(id, userData, userManager, sendMessage, clientId) {
6235
+ async function handleCreate(id, userData, executeCollection, userManager, sendMessage, clientId) {
6048
6236
  const { username, email, password, fullname, role } = userData;
6049
6237
  if (!username || username.trim().length === 0) {
6050
6238
  sendResponse3(id, {
@@ -6070,52 +6258,121 @@ async function handleCreate(id, userData, userManager, sendMessage, clientId) {
6070
6258
  return;
6071
6259
  }
6072
6260
  }
6073
- if (userManager.userExists(username)) {
6261
+ try {
6262
+ const result = await executeCollection("users", "create", {
6263
+ username,
6264
+ email: email || void 0,
6265
+ password,
6266
+ fullname: fullname || void 0,
6267
+ role: role || void 0
6268
+ });
6269
+ if (result && result.success) {
6270
+ logger.info(`[DB] User created successfully: ${username}`);
6271
+ sendResponse3(id, {
6272
+ success: true,
6273
+ data: {
6274
+ id: result.data?.id,
6275
+ username: result.data?.username,
6276
+ email: result.data?.email,
6277
+ fullname: result.data?.fullname,
6278
+ role: result.data?.role,
6279
+ message: `User '${username}' created successfully (DB)`
6280
+ }
6281
+ }, sendMessage, clientId);
6282
+ return;
6283
+ }
6284
+ } catch (dbError) {
6285
+ logger.warn(`[DB] Failed to create user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6286
+ }
6287
+ try {
6288
+ if (userManager.userExists(username)) {
6289
+ sendResponse3(id, {
6290
+ success: false,
6291
+ error: `User '${username}' already exists`
6292
+ }, sendMessage, clientId);
6293
+ return;
6294
+ }
6295
+ if (email && userManager.getUserByEmail(email)) {
6296
+ sendResponse3(id, {
6297
+ success: false,
6298
+ error: `User with email '${email}' already exists`
6299
+ }, sendMessage, clientId);
6300
+ return;
6301
+ }
6302
+ const newUserData = {
6303
+ username,
6304
+ password
6305
+ };
6306
+ if (email && email.trim().length > 0) {
6307
+ newUserData.email = email.trim();
6308
+ }
6309
+ if (fullname && fullname.trim().length > 0) {
6310
+ newUserData.fullname = fullname.trim();
6311
+ }
6312
+ if (role && role.trim().length > 0) {
6313
+ newUserData.role = role.trim();
6314
+ }
6315
+ const newUser = userManager.createUser(newUserData);
6316
+ logger.info(`[FILE] User '${username}' created successfully`);
6317
+ sendResponse3(id, {
6318
+ success: true,
6319
+ data: {
6320
+ username: newUser.username,
6321
+ email: newUser.email,
6322
+ fullname: newUser.fullname,
6323
+ role: newUser.role,
6324
+ message: `User '${username}' created successfully (File)`
6325
+ }
6326
+ }, sendMessage, clientId);
6327
+ } catch (error) {
6074
6328
  sendResponse3(id, {
6075
6329
  success: false,
6076
- error: `User '${username}' already exists`
6330
+ error: error instanceof Error ? error.message : "Failed to create user"
6077
6331
  }, sendMessage, clientId);
6078
- return;
6079
6332
  }
6080
- if (email && userManager.getUserByEmail(email)) {
6333
+ }
6334
+ async function handleUpdate(id, numericId, userData, executeCollection, userManager, sendMessage, clientId) {
6335
+ const { username, email, password, fullname, role } = userData;
6336
+ if (!numericId && !username) {
6081
6337
  sendResponse3(id, {
6082
6338
  success: false,
6083
- error: `User with email '${email}' already exists`
6339
+ error: "User ID or username is required"
6084
6340
  }, sendMessage, clientId);
6085
6341
  return;
6086
6342
  }
6087
- const newUserData = {
6088
- username,
6089
- password
6090
- };
6091
- if (email && email.trim().length > 0) {
6092
- newUserData.email = email.trim();
6093
- }
6094
- if (fullname && fullname.trim().length > 0) {
6095
- newUserData.fullname = fullname.trim();
6096
- }
6097
- if (role && role.trim().length > 0) {
6098
- newUserData.role = role.trim();
6099
- }
6100
- const newUser = userManager.createUser(newUserData);
6101
- logger.info(`User created by admin: ${username}${email ? ` (${email})` : ""}`);
6102
- sendResponse3(id, {
6103
- success: true,
6104
- data: {
6105
- username: newUser.username,
6106
- email: newUser.email,
6107
- fullname: newUser.fullname,
6108
- role: newUser.role,
6109
- message: `User '${username}' created successfully`
6343
+ if (numericId) {
6344
+ try {
6345
+ const result = await executeCollection("users", "update", {
6346
+ id: numericId,
6347
+ username,
6348
+ email,
6349
+ password,
6350
+ fullname,
6351
+ role
6352
+ });
6353
+ if (result && result.success) {
6354
+ logger.info(`[DB] User updated successfully, ID: ${numericId}`);
6355
+ sendResponse3(id, {
6356
+ success: true,
6357
+ data: {
6358
+ id: result.data?.id,
6359
+ username: result.data?.username,
6360
+ email: result.data?.email,
6361
+ fullname: result.data?.fullname,
6362
+ role: result.data?.role,
6363
+ message: `User updated successfully (DB)`
6364
+ }
6365
+ }, sendMessage, clientId);
6366
+ return;
6367
+ }
6368
+ } catch (dbError) {
6369
+ logger.warn(`[DB] Failed to update user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6110
6370
  }
6111
- }, sendMessage, clientId);
6112
- }
6113
- async function handleUpdate(id, userData, userManager, sendMessage, clientId) {
6114
- const { username, email, password, fullname, role } = userData;
6371
+ }
6115
6372
  if (!username || username.trim().length === 0) {
6116
6373
  sendResponse3(id, {
6117
6374
  success: false,
6118
- error: "Username is required and cannot be empty"
6375
+ error: "Username is required for file-based storage update"
6119
6376
  }, sendMessage, clientId);
6120
6377
  return;
6121
6378
  }
@@ -6166,24 +6423,57 @@ async function handleUpdate(id, userData, userManager, sendMessage, clientId) {
6166
6423
  }, sendMessage, clientId);
6167
6424
  return;
6168
6425
  }
6169
- const updatedUser = userManager.updateUser(username, updates);
6170
- logger.info(`User updated by admin: ${username}`);
6171
- sendResponse3(id, {
6172
- success: true,
6173
- data: {
6174
- username: updatedUser.username,
6175
- email: updatedUser.email,
6176
- fullname: updatedUser.fullname,
6177
- role: updatedUser.role,
6178
- message: `User '${username}' updated successfully`
6179
- }
6180
- }, sendMessage, clientId);
6426
+ try {
6427
+ const updatedUser = userManager.updateUser(username, updates);
6428
+ logger.info(`[FILE] User '${username}' updated successfully`);
6429
+ sendResponse3(id, {
6430
+ success: true,
6431
+ data: {
6432
+ username: updatedUser.username,
6433
+ email: updatedUser.email,
6434
+ fullname: updatedUser.fullname,
6435
+ role: updatedUser.role,
6436
+ message: `User '${username}' updated successfully (File)`
6437
+ }
6438
+ }, sendMessage, clientId);
6439
+ } catch (error) {
6440
+ sendResponse3(id, {
6441
+ success: false,
6442
+ error: error instanceof Error ? error.message : "Failed to update user"
6443
+ }, sendMessage, clientId);
6444
+ }
6181
6445
  }
6182
- async function handleDelete(id, username, userManager, sendMessage, clientId) {
6446
+ async function handleDelete(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
6447
+ if (!numericId && !username) {
6448
+ sendResponse3(id, {
6449
+ success: false,
6450
+ error: "User ID or username is required"
6451
+ }, sendMessage, clientId);
6452
+ return;
6453
+ }
6454
+ if (numericId) {
6455
+ try {
6456
+ const result = await executeCollection("users", "delete", { id: numericId });
6457
+ if (result && result.success) {
6458
+ logger.info(`[DB] User deleted successfully, ID: ${numericId}`);
6459
+ sendResponse3(id, {
6460
+ success: true,
6461
+ data: {
6462
+ id: numericId,
6463
+ username: result.data?.username,
6464
+ message: `User deleted successfully (DB)`
6465
+ }
6466
+ }, sendMessage, clientId);
6467
+ return;
6468
+ }
6469
+ } catch (dbError) {
6470
+ logger.warn(`[DB] Failed to delete user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6471
+ }
6472
+ }
6183
6473
  if (!username || username.trim().length === 0) {
6184
6474
  sendResponse3(id, {
6185
6475
  success: false,
6186
- error: "Username is required and cannot be empty"
6476
+ error: "Username is required for file-based storage delete"
6187
6477
  }, sendMessage, clientId);
6188
6478
  return;
6189
6479
  }
@@ -6202,16 +6492,42 @@ async function handleDelete(id, username, userManager, sendMessage, clientId) {
6202
6492
  }, sendMessage, clientId);
6203
6493
  return;
6204
6494
  }
6205
- logger.info(`User deleted by admin: ${username}`);
6495
+ logger.info(`[FILE] User '${username}' deleted successfully`);
6206
6496
  sendResponse3(id, {
6207
6497
  success: true,
6208
6498
  data: {
6209
6499
  username,
6210
- message: `User '${username}' deleted successfully`
6500
+ message: `User '${username}' deleted successfully (File)`
6211
6501
  }
6212
6502
  }, sendMessage, clientId);
6213
6503
  }
6214
- async function handleGetAll(id, userManager, sendMessage, clientId) {
6504
+ async function handleGetAll(id, executeCollection, userManager, sendMessage, clientId) {
6505
+ try {
6506
+ const result = await executeCollection("users", "getAll", {});
6507
+ if (result && result.success) {
6508
+ const sanitizedUsers2 = result.data.map((user) => ({
6509
+ id: user.id,
6510
+ username: user.username,
6511
+ email: user.email,
6512
+ fullname: user.fullname,
6513
+ role: user.role,
6514
+ createdAt: user.createdAt,
6515
+ updatedAt: user.updatedAt
6516
+ }));
6517
+ logger.info(`[DB] Retrieved ${result.count} users`);
6518
+ sendResponse3(id, {
6519
+ success: true,
6520
+ data: {
6521
+ users: sanitizedUsers2,
6522
+ count: result.count,
6523
+ message: `Retrieved ${result.count} users (DB)`
6524
+ }
6525
+ }, sendMessage, clientId);
6526
+ return;
6527
+ }
6528
+ } catch (dbError) {
6529
+ logger.warn(`[DB] Failed to get all users, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6530
+ }
6215
6531
  const users = userManager.getAllUsers();
6216
6532
  const sanitizedUsers = users.map((user) => ({
6217
6533
  username: user.username,
@@ -6220,21 +6536,55 @@ async function handleGetAll(id, userManager, sendMessage, clientId) {
6220
6536
  role: user.role,
6221
6537
  wsIds: user.wsIds || []
6222
6538
  }));
6223
- logger.info(`Admin retrieved all users (count: ${sanitizedUsers.length})`);
6539
+ logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users`);
6224
6540
  sendResponse3(id, {
6225
6541
  success: true,
6226
6542
  data: {
6227
6543
  users: sanitizedUsers,
6228
6544
  count: sanitizedUsers.length,
6229
- message: `Retrieved ${sanitizedUsers.length} users`
6545
+ message: `Retrieved ${sanitizedUsers.length} users (File)`
6230
6546
  }
6231
6547
  }, sendMessage, clientId);
6232
6548
  }
6233
- async function handleGetOne(id, username, userManager, sendMessage, clientId) {
6549
+ async function handleGetOne(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
6550
+ if (!numericId && !username) {
6551
+ sendResponse3(id, {
6552
+ success: false,
6553
+ error: "User ID or username is required"
6554
+ }, sendMessage, clientId);
6555
+ return;
6556
+ }
6557
+ if (numericId) {
6558
+ try {
6559
+ const result = await executeCollection("users", "getOne", { id: numericId });
6560
+ if (result && result.success) {
6561
+ const sanitizedUser2 = {
6562
+ id: result.data?.id,
6563
+ username: result.data?.username,
6564
+ email: result.data?.email,
6565
+ fullname: result.data?.fullname,
6566
+ role: result.data?.role,
6567
+ createdAt: result.data?.createdAt,
6568
+ updatedAt: result.data?.updatedAt
6569
+ };
6570
+ logger.info(`[DB] Retrieved user ID: ${numericId}`);
6571
+ sendResponse3(id, {
6572
+ success: true,
6573
+ data: {
6574
+ user: sanitizedUser2,
6575
+ message: `Retrieved user (DB)`
6576
+ }
6577
+ }, sendMessage, clientId);
6578
+ return;
6579
+ }
6580
+ } catch (dbError) {
6581
+ logger.warn(`[DB] Failed to get user, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6582
+ }
6583
+ }
6234
6584
  if (!username || username.trim().length === 0) {
6235
6585
  sendResponse3(id, {
6236
6586
  success: false,
6237
- error: "Username is required and cannot be empty"
6587
+ error: "Username is required for file-based storage lookup"
6238
6588
  }, sendMessage, clientId);
6239
6589
  return;
6240
6590
  }
@@ -6253,12 +6603,61 @@ async function handleGetOne(id, username, userManager, sendMessage, clientId) {
6253
6603
  role: user.role,
6254
6604
  wsIds: user.wsIds || []
6255
6605
  };
6256
- logger.info(`Admin retrieved user: ${username}`);
6606
+ logger.info(`[FILE] Retrieved user: ${username}`);
6257
6607
  sendResponse3(id, {
6258
6608
  success: true,
6259
6609
  data: {
6260
6610
  user: sanitizedUser,
6261
- message: `Retrieved user '${username}'`
6611
+ message: `Retrieved user '${username}' (File)`
6612
+ }
6613
+ }, sendMessage, clientId);
6614
+ }
6615
+ async function handleQuery(id, filters, limit, sort, executeCollection, userManager, sendMessage, clientId) {
6616
+ try {
6617
+ const result = await executeCollection("users", "query", {
6618
+ filters: filters || {},
6619
+ limit,
6620
+ sort
6621
+ });
6622
+ if (result && result.success) {
6623
+ const sanitizedUsers2 = result.data.map((user) => ({
6624
+ id: user.id,
6625
+ username: user.username,
6626
+ email: user.email,
6627
+ fullname: user.fullname,
6628
+ role: user.role,
6629
+ createdAt: user.createdAt,
6630
+ updatedAt: user.updatedAt
6631
+ }));
6632
+ logger.info(`[DB] Query returned ${result.count} users`);
6633
+ sendResponse3(id, {
6634
+ success: true,
6635
+ data: {
6636
+ users: sanitizedUsers2,
6637
+ count: result.count,
6638
+ message: `Query returned ${result.count} users (DB)`
6639
+ }
6640
+ }, sendMessage, clientId);
6641
+ return;
6642
+ }
6643
+ } catch (dbError) {
6644
+ logger.warn(`[DB] Failed to query users: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6645
+ }
6646
+ const users = userManager.getAllUsers();
6647
+ const sanitizedUsers = users.map((user) => ({
6648
+ username: user.username,
6649
+ email: user.email,
6650
+ fullname: user.fullname,
6651
+ role: user.role,
6652
+ wsIds: user.wsIds || []
6653
+ }));
6654
+ logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users (all - no query filter)`);
6655
+ sendResponse3(id, {
6656
+ success: true,
6657
+ data: {
6658
+ users: sanitizedUsers,
6659
+ count: sanitizedUsers.length,
6660
+ message: `Retrieved ${sanitizedUsers.length} users (File - no query filter)`
6262
6661
  }
6263
6662
  }, sendMessage, clientId);
6264
6663
  }
@@ -6292,13 +6691,29 @@ function getDashboardManager() {
6292
6691
  }
6293
6692
 
6294
6693
  // src/handlers/dashboards.ts
6295
- async function handleDashboardsRequest(data, sendMessage) {
6694
+ async function handleDashboardsRequest(data, collections, sendMessage) {
6695
+ const executeCollection = async (collection, op, params) => {
6696
+ const handler = collections[collection]?.[op];
6697
+ if (!handler) {
6698
+ return null;
6699
+ }
6700
+ return await handler(params);
6701
+ };
6296
6702
  try {
6297
6703
  const request = DashboardsRequestMessageSchema.parse(data);
6298
6704
  const { id, payload, from } = request;
6299
6705
  const { operation, data: requestData } = payload;
6300
6706
  const dashboardId = requestData?.dashboardId;
6301
6707
  const dashboard = requestData?.dashboard;
6708
+ const projectId = requestData?.projectId;
6709
+ const name = requestData?.name;
6710
+ const description = requestData?.description;
6711
+ const createdBy = requestData?.createdBy;
6712
+ const updatedBy = requestData?.updatedBy;
6713
+ const numericId = requestData?.id;
6714
+ const filters = requestData?.filters;
6715
+ const limit = requestData?.limit;
6716
+ const sort = requestData?.sort;
6302
6717
  if (from.type !== "admin") {
6303
6718
  sendResponse4(id, {
6304
6719
  success: false,
@@ -6310,19 +6725,22 @@ async function handleDashboardsRequest(data, sendMessage) {
6310
6725
  const dashboardManager2 = getDashboardManager();
6311
6726
  switch (operation) {
6312
6727
  case "create":
6313
- await handleCreate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, from.id);
6728
+ await handleCreate2(id, dashboardId, dashboard, projectId, name, description, createdBy, executeCollection, dashboardManager2, sendMessage, from.id);
6314
6729
  break;
6315
6730
  case "update":
6316
- await handleUpdate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, from.id);
6731
+ await handleUpdate2(id, numericId, dashboardId, dashboard, name, description, updatedBy, executeCollection, dashboardManager2, sendMessage, from.id);
6317
6732
  break;
6318
6733
  case "delete":
6319
- await handleDelete2(id, dashboardId, dashboardManager2, sendMessage, from.id);
6734
+ await handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, from.id);
6320
6735
  break;
6321
6736
  case "getAll":
6322
- await handleGetAll2(id, dashboardManager2, sendMessage, from.id);
6737
+ await handleGetAll2(id, executeCollection, dashboardManager2, sendMessage, from.id);
6323
6738
  break;
6324
6739
  case "getOne":
6325
- await handleGetOne2(id, dashboardId, dashboardManager2, sendMessage, from.id);
6740
+ await handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, from.id);
6741
+ break;
6742
+ case "query":
6743
+ await handleQuery2(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, from.id);
6326
6744
  break;
6327
6745
  default:
6328
6746
  sendResponse4(id, {
@@ -6338,7 +6756,7 @@ async function handleDashboardsRequest(data, sendMessage) {
6338
6756
  }, sendMessage);
6339
6757
  }
6340
6758
  }
6341
- async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, clientId) {
6759
+ async function handleCreate2(id, dashboardId, dashboard, projectId, name, description, createdBy, executeCollection, dashboardManager2, sendMessage, clientId) {
6342
6760
  if (!dashboardId || dashboardId.trim().length === 0) {
6343
6761
  sendResponse4(id, {
6344
6762
  success: false,
@@ -6346,21 +6764,50 @@ async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, send
6346
6764
  }, sendMessage, clientId);
6347
6765
  return;
6348
6766
  }
6349
- if (!dashboard) {
6767
+ if (!projectId) {
6350
6768
  sendResponse4(id, {
6351
6769
  success: false,
6352
- error: "Dashboard data is required"
6770
+ error: "Project ID is required"
6353
6771
  }, sendMessage, clientId);
6354
6772
  return;
6355
6773
  }
6356
6774
  try {
6775
+ const result = await executeCollection("dashboards", "create", {
6776
+ dashboardId,
6777
+ projectId,
6778
+ name: name || "",
6779
+ description,
6780
+ dashboard,
6781
+ createdBy
6782
+ });
6783
+ if (result && result.success) {
6784
+ logger.info(`[DB] Dashboard created successfully, ID: ${result.data?.id}`);
6785
+ sendResponse4(id, {
6786
+ success: true,
6787
+ data: {
6788
+ id: result.data?.id,
6789
+ dashboardId: result.data?.dashboardId,
6790
+ dashboard: result.data?.dashboard || dashboard,
6791
+ message: `Dashboard created successfully (DB)`
6792
+ }
6793
+ }, sendMessage, clientId);
6794
+ return;
6795
+ }
6796
+ } catch (dbError) {
6797
+ logger.warn(`[DB] Failed to create dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6798
+ }
6799
+ try {
6800
+ if (!dashboard) {
6801
+ dashboard = {};
6802
+ }
6357
6803
  const createdDashboard = dashboardManager2.createDashboard(dashboardId, dashboard);
6804
+ logger.info(`[FILE] Dashboard '${dashboardId}' created successfully`);
6358
6805
  sendResponse4(id, {
6359
6806
  success: true,
6360
6807
  data: {
6361
6808
  dashboardId,
6362
6809
  dashboard: createdDashboard,
6363
- message: `Dashboard '${dashboardId}' created successfully`
6810
+ message: `Dashboard '${dashboardId}' created successfully (File)`
6364
6811
  }
6365
6812
  }, sendMessage, clientId);
6366
6813
  } catch (error) {
@@ -6370,36 +6817,56 @@ async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, send
6370
6817
  }, sendMessage, clientId);
6371
6818
  }
6372
6819
  }
6373
- async function handleUpdate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, clientId) {
6374
- if (!dashboardId || dashboardId.trim().length === 0) {
6820
+ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, description, updatedBy, executeCollection, dashboardManager2, sendMessage, clientId) {
6821
+ if (!numericId) {
6375
6822
  sendResponse4(id, {
6376
6823
  success: false,
6377
- error: "Dashboard ID is required and cannot be empty"
6824
+ error: "Dashboard ID is required"
6378
6825
  }, sendMessage, clientId);
6379
6826
  return;
6380
6827
  }
6381
- if (!dashboard) {
6382
- sendResponse4(id, {
6383
- success: false,
6384
- error: "Dashboard data is required"
6385
- }, sendMessage, clientId);
6386
- return;
6828
+ try {
6829
+ const result = await executeCollection("dashboards", "update", {
6830
+ id: numericId,
6831
+ name,
6832
+ description,
6833
+ dashboard,
6834
+ updatedBy
6835
+ });
6836
+ if (result && result.success) {
6837
+ logger.info(`[DB] Dashboard updated successfully, ID: ${numericId}`);
6838
+ sendResponse4(id, {
6839
+ success: true,
6840
+ data: {
6841
+ id: numericId,
6842
+ dashboardId: result.data?.dashboardId,
6843
+ dashboard: result.data?.dashboard || dashboard,
6844
+ message: `Dashboard updated successfully (DB)`
6845
+ }
6846
+ }, sendMessage, clientId);
6847
+ return;
6848
+ }
6849
+ } catch (dbError) {
6850
+ logger.warn(`[DB] Failed to update dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6387
6851
  }
6852
+ const fileStorageId = dashboardId || String(numericId);
6388
6853
  try {
6389
- const updatedDashboard = dashboardManager2.updateDashboard(dashboardId, dashboard);
6854
+ const updatedDashboard = dashboardManager2.updateDashboard(fileStorageId, dashboard);
6390
6855
  if (!updatedDashboard) {
6391
6856
  sendResponse4(id, {
6392
6857
  success: false,
6393
- error: `Dashboard '${dashboardId}' not found`
6858
+ error: `Dashboard '${fileStorageId}' not found`
6394
6859
  }, sendMessage, clientId);
6395
6860
  return;
6396
6861
  }
6862
+ logger.info(`[FILE] Dashboard '${fileStorageId}' updated successfully`);
6397
6863
  sendResponse4(id, {
6398
6864
  success: true,
6399
6865
  data: {
6400
- dashboardId,
6866
+ id: numericId,
6867
+ dashboardId: fileStorageId,
6401
6868
  dashboard: updatedDashboard,
6402
- message: `Dashboard '${dashboardId}' updated successfully`
6869
+ message: `Dashboard '${fileStorageId}' updated successfully (File)`
6403
6870
  }
6404
6871
  }, sendMessage, clientId);
6405
6872
  } catch (error) {
@@ -6409,65 +6876,154 @@ async function handleUpdate2(id, dashboardId, dashboard, dashboardManager2, send
6409
6876
  }, sendMessage, clientId);
6410
6877
  }
6411
6878
  }
6412
- async function handleDelete2(id, dashboardId, dashboardManager2, sendMessage, clientId) {
6413
- if (!dashboardId || dashboardId.trim().length === 0) {
6879
+ async function handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
6880
+ if (!numericId) {
6414
6881
  sendResponse4(id, {
6415
6882
  success: false,
6416
- error: "Dashboard ID is required and cannot be empty"
6883
+ error: "Dashboard ID is required"
6417
6884
  }, sendMessage, clientId);
6418
6885
  return;
6419
6886
  }
6420
- const deleted = dashboardManager2.deleteDashboard(dashboardId);
6887
+ try {
6888
+ const result = await executeCollection("dashboards", "delete", { id: numericId });
6889
+ if (result && result.success) {
6890
+ logger.info(`[DB] Dashboard deleted successfully, ID: ${numericId}`);
6891
+ sendResponse4(id, {
6892
+ success: true,
6893
+ data: {
6894
+ id: numericId,
6895
+ message: `Dashboard deleted successfully (DB)`
6896
+ }
6897
+ }, sendMessage, clientId);
6898
+ return;
6899
+ }
6900
+ } catch (dbError) {
6901
+ logger.warn(`[DB] Failed to delete dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6902
+ }
6903
+ const fileStorageId = dashboardId || String(numericId);
6904
+ const deleted = dashboardManager2.deleteDashboard(fileStorageId);
6421
6905
  if (!deleted) {
6422
6906
  sendResponse4(id, {
6423
6907
  success: false,
6424
- error: `Dashboard '${dashboardId}' not found`
6908
+ error: `Dashboard '${fileStorageId}' not found`
6425
6909
  }, sendMessage, clientId);
6426
6910
  return;
6427
6911
  }
6912
+ logger.info(`[FILE] Dashboard '${fileStorageId}' deleted successfully`);
6428
6913
  sendResponse4(id, {
6429
6914
  success: true,
6430
6915
  data: {
6431
- dashboardId,
6432
- message: `Dashboard '${dashboardId}' deleted successfully`
6916
+ id: numericId,
6917
+ dashboardId: fileStorageId,
6918
+ message: `Dashboard '${fileStorageId}' deleted successfully (File)`
6433
6919
  }
6434
6920
  }, sendMessage, clientId);
6435
6921
  }
6436
- async function handleGetAll2(id, dashboardManager2, sendMessage, clientId) {
6437
- const dashboards = dashboardManager2.getAllDashboards();
6438
- logger.info(`Admin retrieved all dashboards (count: ${dashboards.length})`);
6439
- sendResponse4(id, {
6440
- success: true,
6441
- data: {
6442
- dashboards,
6443
- count: dashboards.length,
6444
- message: `Retrieved ${dashboards.length} dashboards`
6445
- }
6922
+ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessage, clientId) {
6923
+ try {
6924
+ const result = await executeCollection("dashboards", "getAll", {});
6925
+ if (result && result.success) {
6926
+ logger.info(`[DB] Retrieved ${result.count} dashboards`);
6927
+ sendResponse4(id, {
6928
+ success: true,
6929
+ data: {
6930
+ dashboards: result.data,
6931
+ count: result.count,
6932
+ message: `Retrieved ${result.count} dashboards (DB)`
6933
+ }
6934
+ }, sendMessage, clientId);
6935
+ return;
6936
+ }
6937
+ } catch (dbError) {
6938
+ logger.warn(`[DB] Failed to get all dashboards, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6939
+ }
6940
+ const dashboards = dashboardManager2.getAllDashboards();
6941
+ logger.info(`[FILE] Retrieved ${dashboards.length} dashboards`);
6942
+ sendResponse4(id, {
6943
+ success: true,
6944
+ data: {
6945
+ dashboards,
6946
+ count: dashboards.length,
6947
+ message: `Retrieved ${dashboards.length} dashboards (File)`
6948
+ }
6446
6949
  }, sendMessage, clientId);
6447
6950
  }
6448
- async function handleGetOne2(id, dashboardId, dashboardManager2, sendMessage, clientId) {
6449
- if (!dashboardId || dashboardId.trim().length === 0) {
6951
+ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
6952
+ if (!numericId) {
6450
6953
  sendResponse4(id, {
6451
6954
  success: false,
6452
- error: "Dashboard ID is required and cannot be empty"
6955
+ error: "Dashboard ID is required"
6453
6956
  }, sendMessage, clientId);
6454
6957
  return;
6455
6958
  }
6456
- const dashboard = dashboardManager2.getDashboard(dashboardId);
6959
+ try {
6960
+ const result = await executeCollection("dashboards", "getOne", { id: numericId });
6961
+ if (result && result.success) {
6962
+ logger.info(`[DB] Retrieved dashboard ID: ${numericId}`);
6963
+ sendResponse4(id, {
6964
+ success: true,
6965
+ data: {
6966
+ id: numericId,
6967
+ dashboardId: result.data?.dashboardId,
6968
+ dashboard: result.data?.dashboard || result.data,
6969
+ message: `Retrieved dashboard (DB)`
6970
+ }
6971
+ }, sendMessage, clientId);
6972
+ return;
6973
+ }
6974
+ } catch (dbError) {
6975
+ logger.warn(`[DB] Failed to get dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6976
+ }
6977
+ const fileStorageId = dashboardId || String(numericId);
6978
+ const dashboard = dashboardManager2.getDashboard(fileStorageId);
6457
6979
  if (!dashboard) {
6458
6980
  sendResponse4(id, {
6459
6981
  success: false,
6460
- error: `Dashboard '${dashboardId}' not found`
6982
+ error: `Dashboard '${fileStorageId}' not found`
6461
6983
  }, sendMessage, clientId);
6462
6984
  return;
6463
6985
  }
6464
- logger.info(`Admin retrieved dashboard: ${dashboardId}`);
6986
+ logger.info(`[FILE] Retrieved dashboard: ${fileStorageId}`);
6465
6987
  sendResponse4(id, {
6466
6988
  success: true,
6467
6989
  data: {
6468
- dashboardId,
6990
+ id: numericId,
6991
+ dashboardId: fileStorageId,
6469
6992
  dashboard,
6470
- message: `Retrieved dashboard '${dashboardId}'`
6993
+ message: `Retrieved dashboard '${fileStorageId}' (File)`
6994
+ }
6995
+ }, sendMessage, clientId);
6996
+ }
6997
+ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, clientId) {
6998
+ try {
6999
+ const result = await executeCollection("dashboards", "query", {
7000
+ filters: filters || {},
7001
+ limit,
7002
+ sort
7003
+ });
7004
+ if (result && result.success) {
7005
+ logger.info(`[DB] Query returned ${result.count} dashboards`);
7006
+ sendResponse4(id, {
7007
+ success: true,
7008
+ data: {
7009
+ dashboards: result.data,
7010
+ count: result.count,
7011
+ message: `Query returned ${result.count} dashboards (DB)`
7012
+ }
7013
+ }, sendMessage, clientId);
7014
+ return;
7015
+ }
7016
+ } catch (dbError) {
7017
+ logger.warn(`[DB] Failed to query dashboards: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7018
+ }
7019
+ const dashboards = dashboardManager2.getAllDashboards();
7020
+ logger.info(`[FILE] Retrieved ${dashboards.length} dashboards (all - no query filter)`);
7021
+ sendResponse4(id, {
7022
+ success: true,
7023
+ data: {
7024
+ dashboards,
7025
+ count: dashboards.length,
7026
+ message: `Retrieved ${dashboards.length} dashboards (File - no query filter)`
6471
7027
  }
6472
7028
  }, sendMessage, clientId);
6473
7029
  }
@@ -6500,13 +7056,29 @@ function setReportManager(manager) {
6500
7056
  }
6501
7057
 
6502
7058
  // src/handlers/reports.ts
6503
- async function handleReportsRequest(data, sendMessage) {
7059
+ async function handleReportsRequest(data, collections, sendMessage) {
7060
+ const executeCollection = async (collection, op, params) => {
7061
+ const handler = collections[collection]?.[op];
7062
+ if (!handler) {
7063
+ return null;
7064
+ }
7065
+ return await handler(params);
7066
+ };
6504
7067
  try {
6505
7068
  const request = ReportsRequestMessageSchema.parse(data);
6506
7069
  const { id, payload, from } = request;
6507
7070
  const { operation, data: requestData } = payload;
6508
7071
  const reportId = requestData?.reportId;
6509
7072
  const report = requestData?.report;
7073
+ const projectId = requestData?.projectId;
7074
+ const name = requestData?.name;
7075
+ const description = requestData?.description;
7076
+ const createdBy = requestData?.createdBy;
7077
+ const updatedBy = requestData?.updatedBy;
7078
+ const numericId = requestData?.id;
7079
+ const filters = requestData?.filters;
7080
+ const limit = requestData?.limit;
7081
+ const sort = requestData?.sort;
6510
7082
  if (from.type !== "admin") {
6511
7083
  sendResponse5(id, {
6512
7084
  success: false,
@@ -6518,19 +7090,22 @@ async function handleReportsRequest(data, sendMessage) {
6518
7090
  const reportManager2 = getReportManager();
6519
7091
  switch (operation) {
6520
7092
  case "create":
6521
- await handleCreate3(id, reportId, report, reportManager2, sendMessage, from.id);
7093
+ await handleCreate3(id, reportId, report, projectId, name, description, createdBy, executeCollection, reportManager2, sendMessage, from.id);
6522
7094
  break;
6523
7095
  case "update":
6524
- await handleUpdate3(id, reportId, report, reportManager2, sendMessage, from.id);
7096
+ await handleUpdate3(id, numericId, reportId, report, name, description, updatedBy, executeCollection, reportManager2, sendMessage, from.id);
6525
7097
  break;
6526
7098
  case "delete":
6527
- await handleDelete3(id, reportId, reportManager2, sendMessage, from.id);
7099
+ await handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, from.id);
6528
7100
  break;
6529
7101
  case "getAll":
6530
- await handleGetAll3(id, reportManager2, sendMessage, from.id);
7102
+ await handleGetAll3(id, executeCollection, reportManager2, sendMessage, from.id);
6531
7103
  break;
6532
7104
  case "getOne":
6533
- await handleGetOne3(id, reportId, reportManager2, sendMessage, from.id);
7105
+ await handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, from.id);
7106
+ break;
7107
+ case "query":
7108
+ await handleQuery3(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, from.id);
6534
7109
  break;
6535
7110
  default:
6536
7111
  sendResponse5(id, {
@@ -6546,7 +7121,7 @@ async function handleReportsRequest(data, sendMessage) {
6546
7121
  }, sendMessage);
6547
7122
  }
6548
7123
  }
6549
- async function handleCreate3(id, reportId, report, reportManager2, sendMessage, clientId) {
7124
+ async function handleCreate3(id, reportId, report, projectId, name, description, createdBy, executeCollection, reportManager2, sendMessage, clientId) {
6550
7125
  if (!reportId || reportId.trim().length === 0) {
6551
7126
  sendResponse5(id, {
6552
7127
  success: false,
@@ -6554,21 +7129,50 @@ async function handleCreate3(id, reportId, report, reportManager2, sendMessage,
6554
7129
  }, sendMessage, clientId);
6555
7130
  return;
6556
7131
  }
6557
- if (!report) {
7132
+ if (!projectId) {
6558
7133
  sendResponse5(id, {
6559
7134
  success: false,
6560
- error: "Report data is required"
7135
+ error: "Project ID is required"
6561
7136
  }, sendMessage, clientId);
6562
7137
  return;
6563
7138
  }
6564
7139
  try {
7140
+ const result = await executeCollection("reports", "create", {
7141
+ reportId,
7142
+ projectId,
7143
+ name: name || "",
7144
+ description,
7145
+ report,
7146
+ createdBy
7147
+ });
7148
+ if (result && result.success) {
7149
+ logger.info(`[DB] Report created successfully, ID: ${result.data?.id}`);
7150
+ sendResponse5(id, {
7151
+ success: true,
7152
+ data: {
7153
+ id: result.data?.id,
7154
+ reportId: result.data?.reportId,
7155
+ report: result.data?.report || report,
7156
+ message: `Report created successfully (DB)`
7157
+ }
7158
+ }, sendMessage, clientId);
7159
+ return;
7160
+ }
7161
+ } catch (dbError) {
7162
+ logger.warn(`[DB] Failed to create report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7163
+ }
7164
+ try {
7165
+ if (!report) {
7166
+ report = {};
7167
+ }
6565
7168
  const createdReport = reportManager2.createReport(reportId, report);
7169
+ logger.info(`[FILE] Report '${reportId}' created successfully`);
6566
7170
  sendResponse5(id, {
6567
7171
  success: true,
6568
7172
  data: {
6569
7173
  reportId,
6570
7174
  report: createdReport,
6571
- message: `Report '${reportId}' created successfully`
7175
+ message: `Report '${reportId}' created successfully (File)`
6572
7176
  }
6573
7177
  }, sendMessage, clientId);
6574
7178
  } catch (error) {
@@ -6578,36 +7182,56 @@ async function handleCreate3(id, reportId, report, reportManager2, sendMessage,
6578
7182
  }, sendMessage, clientId);
6579
7183
  }
6580
7184
  }
6581
- async function handleUpdate3(id, reportId, report, reportManager2, sendMessage, clientId) {
6582
- if (!reportId || reportId.trim().length === 0) {
7185
+ async function handleUpdate3(id, numericId, reportId, report, name, description, updatedBy, executeCollection, reportManager2, sendMessage, clientId) {
7186
+ if (!numericId) {
6583
7187
  sendResponse5(id, {
6584
7188
  success: false,
6585
- error: "Report ID is required and cannot be empty"
7189
+ error: "Report ID is required"
6586
7190
  }, sendMessage, clientId);
6587
7191
  return;
6588
7192
  }
6589
- if (!report) {
6590
- sendResponse5(id, {
6591
- success: false,
6592
- error: "Report data is required"
6593
- }, sendMessage, clientId);
6594
- return;
7193
+ try {
7194
+ const result = await executeCollection("reports", "update", {
7195
+ id: numericId,
7196
+ name,
7197
+ description,
7198
+ report,
7199
+ updatedBy
7200
+ });
7201
+ if (result && result.success) {
7202
+ logger.info(`[DB] Report updated successfully, ID: ${numericId}`);
7203
+ sendResponse5(id, {
7204
+ success: true,
7205
+ data: {
7206
+ id: numericId,
7207
+ reportId: result.data?.reportId,
7208
+ report: result.data?.report || report,
7209
+ message: `Report updated successfully (DB)`
7210
+ }
7211
+ }, sendMessage, clientId);
7212
+ return;
7213
+ }
7214
+ } catch (dbError) {
7215
+ logger.warn(`[DB] Failed to update report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6595
7216
  }
7217
+ const fileStorageId = reportId || String(numericId);
6596
7218
  try {
6597
- const updatedReport = reportManager2.updateReport(reportId, report);
7219
+ const updatedReport = reportManager2.updateReport(fileStorageId, report);
6598
7220
  if (!updatedReport) {
6599
7221
  sendResponse5(id, {
6600
7222
  success: false,
6601
- error: `Report '${reportId}' not found`
7223
+ error: `Report '${fileStorageId}' not found`
6602
7224
  }, sendMessage, clientId);
6603
7225
  return;
6604
7226
  }
7227
+ logger.info(`[FILE] Report '${fileStorageId}' updated successfully`);
6605
7228
  sendResponse5(id, {
6606
7229
  success: true,
6607
7230
  data: {
6608
- reportId,
7231
+ id: numericId,
7232
+ reportId: fileStorageId,
6609
7233
  report: updatedReport,
6610
- message: `Report '${reportId}' updated successfully`
7234
+ message: `Report '${fileStorageId}' updated successfully (File)`
6611
7235
  }
6612
7236
  }, sendMessage, clientId);
6613
7237
  } catch (error) {
@@ -6617,65 +7241,154 @@ async function handleUpdate3(id, reportId, report, reportManager2, sendMessage,
6617
7241
  }, sendMessage, clientId);
6618
7242
  }
6619
7243
  }
6620
- async function handleDelete3(id, reportId, reportManager2, sendMessage, clientId) {
6621
- if (!reportId || reportId.trim().length === 0) {
7244
+ async function handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
7245
+ if (!numericId) {
6622
7246
  sendResponse5(id, {
6623
7247
  success: false,
6624
- error: "Report ID is required and cannot be empty"
7248
+ error: "Report ID is required"
6625
7249
  }, sendMessage, clientId);
6626
7250
  return;
6627
7251
  }
6628
- const deleted = reportManager2.deleteReport(reportId);
7252
+ try {
7253
+ const result = await executeCollection("reports", "delete", { id: numericId });
7254
+ if (result && result.success) {
7255
+ logger.info(`[DB] Report deleted successfully, ID: ${numericId}`);
7256
+ sendResponse5(id, {
7257
+ success: true,
7258
+ data: {
7259
+ id: numericId,
7260
+ message: `Report deleted successfully (DB)`
7261
+ }
7262
+ }, sendMessage, clientId);
7263
+ return;
7264
+ }
7265
+ } catch (dbError) {
7266
+ logger.warn(`[DB] Failed to delete report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7267
+ }
7268
+ const fileStorageId = reportId || String(numericId);
7269
+ const deleted = reportManager2.deleteReport(fileStorageId);
6629
7270
  if (!deleted) {
6630
7271
  sendResponse5(id, {
6631
7272
  success: false,
6632
- error: `Report '${reportId}' not found`
7273
+ error: `Report '${fileStorageId}' not found`
6633
7274
  }, sendMessage, clientId);
6634
7275
  return;
6635
7276
  }
7277
+ logger.info(`[FILE] Report '${fileStorageId}' deleted successfully`);
6636
7278
  sendResponse5(id, {
6637
7279
  success: true,
6638
7280
  data: {
6639
- reportId,
6640
- message: `Report '${reportId}' deleted successfully`
7281
+ id: numericId,
7282
+ reportId: fileStorageId,
7283
+ message: `Report '${fileStorageId}' deleted successfully (File)`
6641
7284
  }
6642
7285
  }, sendMessage, clientId);
6643
7286
  }
6644
- async function handleGetAll3(id, reportManager2, sendMessage, clientId) {
7287
+ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage, clientId) {
7288
+ try {
7289
+ const result = await executeCollection("reports", "getAll", {});
7290
+ if (result && result.success) {
7291
+ logger.info(`[DB] Retrieved ${result.count} reports`);
7292
+ sendResponse5(id, {
7293
+ success: true,
7294
+ data: {
7295
+ reports: result.data,
7296
+ count: result.count,
7297
+ message: `Retrieved ${result.count} reports (DB)`
7298
+ }
7299
+ }, sendMessage, clientId);
7300
+ return;
7301
+ }
7302
+ } catch (dbError) {
7303
+ logger.warn(`[DB] Failed to get all reports, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7304
+ }
6645
7305
  const reports = reportManager2.getAllReports();
6646
- logger.info(`Admin retrieved all reports (count: ${reports.length})`);
7306
+ logger.info(`[FILE] Retrieved ${reports.length} reports`);
6647
7307
  sendResponse5(id, {
6648
7308
  success: true,
6649
7309
  data: {
6650
7310
  reports,
6651
7311
  count: reports.length,
6652
- message: `Retrieved ${reports.length} reports`
7312
+ message: `Retrieved ${reports.length} reports (File)`
6653
7313
  }
6654
7314
  }, sendMessage, clientId);
6655
7315
  }
6656
- async function handleGetOne3(id, reportId, reportManager2, sendMessage, clientId) {
6657
- if (!reportId || reportId.trim().length === 0) {
7316
+ async function handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
7317
+ if (!numericId) {
6658
7318
  sendResponse5(id, {
6659
7319
  success: false,
6660
- error: "Report ID is required and cannot be empty"
7320
+ error: "Report ID is required"
6661
7321
  }, sendMessage, clientId);
6662
7322
  return;
6663
7323
  }
6664
- const report = reportManager2.getReport(reportId);
7324
+ try {
7325
+ const result = await executeCollection("reports", "getOne", { id: numericId });
7326
+ if (result && result.success) {
7327
+ logger.info(`[DB] Retrieved report ID: ${numericId}`);
7328
+ sendResponse5(id, {
7329
+ success: true,
7330
+ data: {
7331
+ id: numericId,
7332
+ reportId: result.data?.reportId,
7333
+ report: result.data?.report || result.data,
7334
+ message: `Retrieved report (DB)`
7335
+ }
7336
+ }, sendMessage, clientId);
7337
+ return;
7338
+ }
7339
+ } catch (dbError) {
7340
+ logger.warn(`[DB] Failed to get report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7341
+ }
7342
+ const fileStorageId = reportId || String(numericId);
7343
+ const report = reportManager2.getReport(fileStorageId);
6665
7344
  if (!report) {
6666
7345
  sendResponse5(id, {
6667
7346
  success: false,
6668
- error: `Report '${reportId}' not found`
7347
+ error: `Report '${fileStorageId}' not found`
6669
7348
  }, sendMessage, clientId);
6670
7349
  return;
6671
7350
  }
6672
- logger.info(`Admin retrieved report: ${reportId}`);
7351
+ logger.info(`[FILE] Retrieved report: ${fileStorageId}`);
6673
7352
  sendResponse5(id, {
6674
7353
  success: true,
6675
7354
  data: {
6676
- reportId,
7355
+ id: numericId,
7356
+ reportId: fileStorageId,
6677
7357
  report,
6678
- message: `Retrieved report '${reportId}'`
7358
+ message: `Retrieved report '${fileStorageId}' (File)`
7359
+ }
7360
+ }, sendMessage, clientId);
7361
+ }
7362
+ async function handleQuery3(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, clientId) {
7363
+ try {
7364
+ const result = await executeCollection("reports", "query", {
7365
+ filters: filters || {},
7366
+ limit,
7367
+ sort
7368
+ });
7369
+ if (result && result.success) {
7370
+ logger.info(`[DB] Query returned ${result.count} reports`);
7371
+ sendResponse5(id, {
7372
+ success: true,
7373
+ data: {
7374
+ reports: result.data,
7375
+ count: result.count,
7376
+ message: `Query returned ${result.count} reports (DB)`
7377
+ }
7378
+ }, sendMessage, clientId);
7379
+ return;
7380
+ }
7381
+ } catch (dbError) {
7382
+ logger.warn(`[DB] Failed to query reports: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7383
+ }
7384
+ const reports = reportManager2.getAllReports();
7385
+ logger.info(`[FILE] Retrieved ${reports.length} reports (all - no query filter)`);
7386
+ sendResponse5(id, {
7387
+ success: true,
7388
+ data: {
7389
+ reports,
7390
+ count: reports.length,
7391
+ message: `Retrieved ${reports.length} reports (File - no query filter)`
6679
7392
  }
6680
7393
  }, sendMessage, clientId);
6681
7394
  }
@@ -6695,6 +7408,297 @@ function sendResponse5(id, res, sendMessage, clientId) {
6695
7408
  sendMessage(response);
6696
7409
  }
6697
7410
 
7411
+ // src/handlers/uis.ts
7412
+ async function handleUIsRequest(data, collections, sendMessage) {
7413
+ const executeCollection = async (collection, op, params) => {
7414
+ const handler = collections[collection]?.[op];
7415
+ if (!handler) {
7416
+ throw new Error(`Collection handler not found: ${collection}.${op}`);
7417
+ }
7418
+ return await handler(params);
7419
+ };
7420
+ try {
7421
+ const request = UIsRequestMessageSchema.parse(data);
7422
+ const { id, payload, from } = request;
7423
+ const { operation, data: requestData } = payload;
7424
+ const uiId = requestData?.uiId;
7425
+ const ui = requestData?.ui;
7426
+ const projectId = requestData?.projectId;
7427
+ const name = requestData?.name;
7428
+ const description = requestData?.description;
7429
+ const createdBy = requestData?.createdBy;
7430
+ const updatedBy = requestData?.updatedBy;
7431
+ const numericId = requestData?.id;
7432
+ const filters = requestData?.filters;
7433
+ const limit = requestData?.limit;
7434
+ const sort = requestData?.sort;
7435
+ if (from.type !== "admin") {
7436
+ sendResponse6(id, {
7437
+ success: false,
7438
+ error: "Unauthorized: Only admin can manage UIs"
7439
+ }, sendMessage, from.id);
7440
+ logger.warn(`Unauthorized UI management attempt from: ${from.type}`);
7441
+ return;
7442
+ }
7443
+ switch (operation) {
7444
+ case "create":
7445
+ await handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, from.id);
7446
+ break;
7447
+ case "update":
7448
+ await handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, from.id);
7449
+ break;
7450
+ case "delete":
7451
+ await handleDelete4(id, numericId, executeCollection, sendMessage, from.id);
7452
+ break;
7453
+ case "getAll":
7454
+ await handleGetAll4(id, executeCollection, sendMessage, from.id);
7455
+ break;
7456
+ case "getOne":
7457
+ await handleGetOne4(id, numericId, executeCollection, sendMessage, from.id);
7458
+ break;
7459
+ case "query":
7460
+ await handleQuery4(id, filters, limit, sort, executeCollection, sendMessage, from.id);
7461
+ break;
7462
+ default:
7463
+ sendResponse6(id, {
7464
+ success: false,
7465
+ error: `Unknown operation: ${operation}`
7466
+ }, sendMessage, from.id);
7467
+ }
7468
+ } catch (error) {
7469
+ logger.error("Failed to handle UIs request:", error);
7470
+ sendResponse6(null, {
7471
+ success: false,
7472
+ error: error instanceof Error ? error.message : "Unknown error occurred"
7473
+ }, sendMessage);
7474
+ }
7475
+ }
7476
+ async function handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, clientId) {
7477
+ if (!uiId || uiId.trim().length === 0) {
7478
+ sendResponse6(id, {
7479
+ success: false,
7480
+ error: "UI ID is required and cannot be empty"
7481
+ }, sendMessage, clientId);
7482
+ return;
7483
+ }
7484
+ if (!projectId || projectId.trim().length === 0) {
7485
+ sendResponse6(id, {
7486
+ success: false,
7487
+ error: "Project ID is required and cannot be empty"
7488
+ }, sendMessage, clientId);
7489
+ return;
7490
+ }
7491
+ try {
7492
+ const result = await executeCollection("uis", "create", {
7493
+ uiId,
7494
+ projectId,
7495
+ name: name || uiId,
7496
+ description,
7497
+ ui,
7498
+ createdBy
7499
+ });
7500
+ if (result && result.success) {
7501
+ logger.info(`UI created successfully, ID: ${result.data?.id}`);
7502
+ sendResponse6(id, {
7503
+ success: true,
7504
+ data: {
7505
+ id: result.data?.id,
7506
+ uiId: result.data?.uiId || uiId,
7507
+ ui: result.data?.ui || ui,
7508
+ message: `UI created successfully`
7509
+ }
7510
+ }, sendMessage, clientId);
7511
+ } else {
7512
+ sendResponse6(id, {
7513
+ success: false,
7514
+ error: "Failed to create UI"
7515
+ }, sendMessage, clientId);
7516
+ }
7517
+ } catch (error) {
7518
+ sendResponse6(id, {
7519
+ success: false,
7520
+ error: error instanceof Error ? error.message : "Failed to create UI"
7521
+ }, sendMessage, clientId);
7522
+ }
7523
+ }
7524
+ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, 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", "update", {
7534
+ id: numericId,
7535
+ name,
7536
+ description,
7537
+ ui,
7538
+ updatedBy
7539
+ });
7540
+ if (result && result.success) {
7541
+ logger.info(`UI updated successfully, ID: ${numericId}`);
7542
+ sendResponse6(id, {
7543
+ success: true,
7544
+ data: {
7545
+ id: numericId,
7546
+ uiId: result.data?.uiId,
7547
+ ui: result.data?.ui || ui,
7548
+ message: `UI updated successfully`
7549
+ }
7550
+ }, sendMessage, clientId);
7551
+ } else {
7552
+ sendResponse6(id, {
7553
+ success: false,
7554
+ error: "Failed to update UI"
7555
+ }, sendMessage, clientId);
7556
+ }
7557
+ } catch (error) {
7558
+ sendResponse6(id, {
7559
+ success: false,
7560
+ error: error instanceof Error ? error.message : "Failed to update UI"
7561
+ }, sendMessage, clientId);
7562
+ }
7563
+ }
7564
+ async function handleDelete4(id, numericId, executeCollection, sendMessage, clientId) {
7565
+ if (!numericId) {
7566
+ sendResponse6(id, {
7567
+ success: false,
7568
+ error: "UI ID is required"
7569
+ }, sendMessage, clientId);
7570
+ return;
7571
+ }
7572
+ try {
7573
+ const result = await executeCollection("uis", "delete", { id: numericId });
7574
+ if (result && result.success) {
7575
+ logger.info(`UI deleted successfully, ID: ${numericId}`);
7576
+ sendResponse6(id, {
7577
+ success: true,
7578
+ data: {
7579
+ id: numericId,
7580
+ message: `UI deleted successfully`
7581
+ }
7582
+ }, sendMessage, clientId);
7583
+ } else {
7584
+ sendResponse6(id, {
7585
+ success: false,
7586
+ error: "Failed to delete UI"
7587
+ }, sendMessage, clientId);
7588
+ }
7589
+ } catch (error) {
7590
+ sendResponse6(id, {
7591
+ success: false,
7592
+ error: error instanceof Error ? error.message : "Failed to delete UI"
7593
+ }, sendMessage, clientId);
7594
+ }
7595
+ }
7596
+ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
7597
+ try {
7598
+ const result = await executeCollection("uis", "getAll", {});
7599
+ if (result && result.success) {
7600
+ logger.info(`Retrieved ${result.count} UIs`);
7601
+ sendResponse6(id, {
7602
+ success: true,
7603
+ data: {
7604
+ uis: result.data,
7605
+ count: result.count,
7606
+ message: `Retrieved ${result.count} UIs`
7607
+ }
7608
+ }, sendMessage, clientId);
7609
+ } else {
7610
+ sendResponse6(id, {
7611
+ success: false,
7612
+ error: "Failed to get UIs"
7613
+ }, sendMessage, clientId);
7614
+ }
7615
+ } catch (error) {
7616
+ sendResponse6(id, {
7617
+ success: false,
7618
+ error: error instanceof Error ? error.message : "Failed to get UIs"
7619
+ }, sendMessage, clientId);
7620
+ }
7621
+ }
7622
+ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clientId) {
7623
+ if (!numericId) {
7624
+ sendResponse6(id, {
7625
+ success: false,
7626
+ error: "UI ID is required"
7627
+ }, sendMessage, clientId);
7628
+ return;
7629
+ }
7630
+ try {
7631
+ const result = await executeCollection("uis", "getOne", { id: numericId });
7632
+ if (result && result.success) {
7633
+ logger.info(`Retrieved UI ID: ${numericId}`);
7634
+ sendResponse6(id, {
7635
+ success: true,
7636
+ data: {
7637
+ id: numericId,
7638
+ uiId: result.data?.uiId,
7639
+ ui: result.data?.ui || result.data,
7640
+ message: `Retrieved UI`
7641
+ }
7642
+ }, sendMessage, clientId);
7643
+ } else {
7644
+ sendResponse6(id, {
7645
+ success: false,
7646
+ error: `UI not found`
7647
+ }, sendMessage, clientId);
7648
+ }
7649
+ } catch (error) {
7650
+ sendResponse6(id, {
7651
+ success: false,
7652
+ error: error instanceof Error ? error.message : "Failed to get UI"
7653
+ }, sendMessage, clientId);
7654
+ }
7655
+ }
7656
+ async function handleQuery4(id, filters, limit, sort, executeCollection, sendMessage, clientId) {
7657
+ try {
7658
+ const result = await executeCollection("uis", "query", {
7659
+ filters: filters || {},
7660
+ limit,
7661
+ sort
7662
+ });
7663
+ if (result && result.success) {
7664
+ logger.info(`Query returned ${result.count} UIs`);
7665
+ sendResponse6(id, {
7666
+ success: true,
7667
+ data: {
7668
+ uis: result.data,
7669
+ count: result.count,
7670
+ message: `Query returned ${result.count} UIs`
7671
+ }
7672
+ }, sendMessage, clientId);
7673
+ } else {
7674
+ sendResponse6(id, {
7675
+ success: false,
7676
+ error: "Failed to query UIs"
7677
+ }, sendMessage, clientId);
7678
+ }
7679
+ } catch (error) {
7680
+ sendResponse6(id, {
7681
+ success: false,
7682
+ error: error instanceof Error ? error.message : "Failed to query UIs"
7683
+ }, sendMessage, clientId);
7684
+ }
7685
+ }
7686
+ function sendResponse6(id, res, sendMessage, clientId) {
7687
+ const response = {
7688
+ id: id || "unknown",
7689
+ type: "UIS_RES",
7690
+ from: { type: "data-agent" },
7691
+ to: {
7692
+ type: "admin",
7693
+ id: clientId
7694
+ },
7695
+ payload: {
7696
+ ...res
7697
+ }
7698
+ };
7699
+ sendMessage(response);
7700
+ }
7701
+
6698
7702
  // src/handlers/bookmarks.ts
6699
7703
  async function handleBookmarksRequest(data, collections, sendMessage) {
6700
7704
  const executeCollection = async (collection, op, params) => {
@@ -6711,22 +7715,27 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
6711
7715
  const bookmarkId = requestData?.id;
6712
7716
  const userId = requestData?.userId;
6713
7717
  const threadId = requestData?.threadId;
7718
+ const name = requestData?.name;
7719
+ const description = requestData?.description;
6714
7720
  const uiblock = requestData?.uiblock;
7721
+ const filters = requestData?.filters;
7722
+ const limit = requestData?.limit;
7723
+ const sort = requestData?.sort;
6715
7724
  switch (operation) {
6716
7725
  case "create":
6717
- await handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, from.id);
7726
+ await handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, from.id);
6718
7727
  break;
6719
7728
  case "update":
6720
- await handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, from.id);
7729
+ await handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, from.id);
6721
7730
  break;
6722
7731
  case "delete":
6723
- await handleDelete4(id, bookmarkId, executeCollection, sendMessage, from.id);
7732
+ await handleDelete5(id, bookmarkId, executeCollection, sendMessage, from.id);
6724
7733
  break;
6725
7734
  case "getAll":
6726
- await handleGetAll4(id, executeCollection, sendMessage, from.id);
7735
+ await handleGetAll5(id, executeCollection, sendMessage, from.id);
6727
7736
  break;
6728
7737
  case "getOne":
6729
- await handleGetOne4(id, bookmarkId, executeCollection, sendMessage, from.id);
7738
+ await handleGetOne5(id, bookmarkId, executeCollection, sendMessage, from.id);
6730
7739
  break;
6731
7740
  case "getByUser":
6732
7741
  await handleGetByUser(id, userId, threadId, executeCollection, sendMessage, from.id);
@@ -6734,83 +7743,79 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
6734
7743
  case "getByThread":
6735
7744
  await handleGetByThread(id, threadId, executeCollection, sendMessage, from.id);
6736
7745
  break;
7746
+ case "query":
7747
+ await handleQuery5(id, filters, limit, sort, executeCollection, sendMessage, from.id);
7748
+ break;
6737
7749
  default:
6738
- sendResponse6(id, {
7750
+ sendResponse7(id, {
6739
7751
  success: false,
6740
7752
  error: `Unknown operation: ${operation}`
6741
7753
  }, sendMessage, from.id);
6742
7754
  }
6743
7755
  } catch (error) {
6744
7756
  logger.error("Failed to handle bookmarks request:", error);
6745
- sendResponse6(null, {
7757
+ sendResponse7(null, {
6746
7758
  success: false,
6747
7759
  error: error instanceof Error ? error.message : "Unknown error occurred"
6748
7760
  }, sendMessage);
6749
7761
  }
6750
7762
  }
6751
- async function handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, clientId) {
7763
+ async function handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
6752
7764
  if (!userId) {
6753
- sendResponse6(id, {
7765
+ sendResponse7(id, {
6754
7766
  success: false,
6755
7767
  error: "userId is required"
6756
7768
  }, sendMessage, clientId);
6757
7769
  return;
6758
7770
  }
6759
7771
  if (!uiblock) {
6760
- sendResponse6(id, {
7772
+ sendResponse7(id, {
6761
7773
  success: false,
6762
7774
  error: "UIBlock data is required"
6763
7775
  }, sendMessage, clientId);
6764
7776
  return;
6765
7777
  }
6766
7778
  try {
6767
- const result = await executeCollection("bookmarks", "create", { userId, threadId, uiblock });
6768
- sendResponse6(id, {
7779
+ const result = await executeCollection("bookmarks", "create", { userId, threadId, name, description, uiblock });
7780
+ sendResponse7(id, {
6769
7781
  success: true,
6770
7782
  data: result.data,
6771
7783
  message: "Bookmark created successfully"
6772
7784
  }, sendMessage, clientId);
6773
7785
  logger.info(`Bookmark created: ID ${result.data.id}`);
6774
7786
  } catch (error) {
6775
- sendResponse6(id, {
7787
+ sendResponse7(id, {
6776
7788
  success: false,
6777
7789
  error: error instanceof Error ? error.message : "Failed to create bookmark"
6778
7790
  }, sendMessage, clientId);
6779
7791
  }
6780
7792
  }
6781
- async function handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, clientId) {
7793
+ async function handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
6782
7794
  if (!bookmarkId) {
6783
- sendResponse6(id, {
7795
+ sendResponse7(id, {
6784
7796
  success: false,
6785
7797
  error: "Bookmark ID is required"
6786
7798
  }, sendMessage, clientId);
6787
7799
  return;
6788
7800
  }
6789
- if (!uiblock) {
6790
- sendResponse6(id, {
6791
- success: false,
6792
- error: "UIBlock data is required"
6793
- }, sendMessage, clientId);
6794
- return;
6795
- }
6796
7801
  try {
6797
- const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, uiblock });
6798
- sendResponse6(id, {
7802
+ const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, name, description, uiblock });
7803
+ sendResponse7(id, {
6799
7804
  success: true,
6800
7805
  data: result.data,
6801
7806
  message: "Bookmark updated successfully"
6802
7807
  }, sendMessage, clientId);
6803
7808
  logger.info(`Bookmark updated: ID ${bookmarkId}`);
6804
7809
  } catch (error) {
6805
- sendResponse6(id, {
7810
+ sendResponse7(id, {
6806
7811
  success: false,
6807
7812
  error: error instanceof Error ? error.message : "Failed to update bookmark"
6808
7813
  }, sendMessage, clientId);
6809
7814
  }
6810
7815
  }
6811
- async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, clientId) {
7816
+ async function handleDelete5(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,23 +7823,23 @@ async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, cli
6818
7823
  }
6819
7824
  try {
6820
7825
  const result = await executeCollection("bookmarks", "delete", { id: bookmarkId });
6821
- sendResponse6(id, {
7826
+ sendResponse7(id, {
6822
7827
  success: true,
6823
7828
  data: result.data,
6824
7829
  message: "Bookmark deleted successfully"
6825
7830
  }, sendMessage, clientId);
6826
7831
  logger.info(`Bookmark deleted: 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 delete bookmark"
6831
7836
  }, sendMessage, clientId);
6832
7837
  }
6833
7838
  }
6834
- async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
7839
+ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
6835
7840
  try {
6836
7841
  const result = await executeCollection("bookmarks", "getAll", {});
6837
- sendResponse6(id, {
7842
+ sendResponse7(id, {
6838
7843
  success: true,
6839
7844
  data: result.data,
6840
7845
  count: result.count,
@@ -6842,15 +7847,15 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
6842
7847
  }, sendMessage, clientId);
6843
7848
  logger.info(`Retrieved all bookmarks (count: ${result.count})`);
6844
7849
  } catch (error) {
6845
- sendResponse6(id, {
7850
+ sendResponse7(id, {
6846
7851
  success: false,
6847
7852
  error: error instanceof Error ? error.message : "Failed to get bookmarks"
6848
7853
  }, sendMessage, clientId);
6849
7854
  }
6850
7855
  }
6851
- async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, clientId) {
7856
+ async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, clientId) {
6852
7857
  if (!bookmarkId) {
6853
- sendResponse6(id, {
7858
+ sendResponse7(id, {
6854
7859
  success: false,
6855
7860
  error: "Bookmark ID is required"
6856
7861
  }, sendMessage, clientId);
@@ -6858,14 +7863,14 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
6858
7863
  }
6859
7864
  try {
6860
7865
  const result = await executeCollection("bookmarks", "getOne", { id: bookmarkId });
6861
- sendResponse6(id, {
7866
+ sendResponse7(id, {
6862
7867
  success: true,
6863
7868
  data: result.data,
6864
7869
  message: `Retrieved bookmark ID ${bookmarkId}`
6865
7870
  }, sendMessage, clientId);
6866
7871
  logger.info(`Retrieved bookmark: ID ${bookmarkId}`);
6867
7872
  } catch (error) {
6868
- sendResponse6(id, {
7873
+ sendResponse7(id, {
6869
7874
  success: false,
6870
7875
  error: error instanceof Error ? error.message : "Failed to get bookmark"
6871
7876
  }, sendMessage, clientId);
@@ -6873,7 +7878,7 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
6873
7878
  }
6874
7879
  async function handleGetByUser(id, userId, threadId, executeCollection, sendMessage, clientId) {
6875
7880
  if (!userId) {
6876
- sendResponse6(id, {
7881
+ sendResponse7(id, {
6877
7882
  success: false,
6878
7883
  error: "userId is required"
6879
7884
  }, sendMessage, clientId);
@@ -6881,7 +7886,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6881
7886
  }
6882
7887
  try {
6883
7888
  const result = await executeCollection("bookmarks", "getByUser", { userId, threadId });
6884
- sendResponse6(id, {
7889
+ sendResponse7(id, {
6885
7890
  success: true,
6886
7891
  data: result.data,
6887
7892
  count: result.count,
@@ -6889,7 +7894,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6889
7894
  }, sendMessage, clientId);
6890
7895
  logger.info(`Retrieved bookmarks for user ${userId} (count: ${result.count})`);
6891
7896
  } catch (error) {
6892
- sendResponse6(id, {
7897
+ sendResponse7(id, {
6893
7898
  success: false,
6894
7899
  error: error instanceof Error ? error.message : "Failed to get bookmarks by user"
6895
7900
  }, sendMessage, clientId);
@@ -6897,7 +7902,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6897
7902
  }
6898
7903
  async function handleGetByThread(id, threadId, executeCollection, sendMessage, clientId) {
6899
7904
  if (!threadId) {
6900
- sendResponse6(id, {
7905
+ sendResponse7(id, {
6901
7906
  success: false,
6902
7907
  error: "threadId is required"
6903
7908
  }, sendMessage, clientId);
@@ -6905,7 +7910,7 @@ async function handleGetByThread(id, threadId, executeCollection, sendMessage, c
6905
7910
  }
6906
7911
  try {
6907
7912
  const result = await executeCollection("bookmarks", "getByThread", { threadId });
6908
- sendResponse6(id, {
7913
+ sendResponse7(id, {
6909
7914
  success: true,
6910
7915
  data: result.data,
6911
7916
  count: result.count,
@@ -6913,13 +7918,34 @@ async function handleGetByThread(id, threadId, executeCollection, sendMessage, c
6913
7918
  }, sendMessage, clientId);
6914
7919
  logger.info(`Retrieved bookmarks for thread ${threadId} (count: ${result.count})`);
6915
7920
  } catch (error) {
6916
- sendResponse6(id, {
7921
+ sendResponse7(id, {
6917
7922
  success: false,
6918
7923
  error: error instanceof Error ? error.message : "Failed to get bookmarks by thread"
6919
7924
  }, sendMessage, clientId);
6920
7925
  }
6921
7926
  }
6922
- function sendResponse6(id, res, sendMessage, clientId) {
7927
+ async function handleQuery5(id, filters, limit, sort, executeCollection, sendMessage, clientId) {
7928
+ try {
7929
+ const result = await executeCollection("bookmarks", "query", {
7930
+ filters: filters || {},
7931
+ limit,
7932
+ sort
7933
+ });
7934
+ sendResponse7(id, {
7935
+ success: true,
7936
+ data: result.data,
7937
+ count: result.count,
7938
+ message: `Query returned ${result.count} bookmarks`
7939
+ }, sendMessage, clientId);
7940
+ logger.info(`Query returned ${result.count} bookmarks`);
7941
+ } catch (error) {
7942
+ sendResponse7(id, {
7943
+ success: false,
7944
+ error: error instanceof Error ? error.message : "Failed to query bookmarks"
7945
+ }, sendMessage, clientId);
7946
+ }
7947
+ }
7948
+ function sendResponse7(id, res, sendMessage, clientId) {
6923
7949
  const response = {
6924
7950
  id: id || "unknown",
6925
7951
  type: "BOOKMARKS_RES",
@@ -7930,30 +8956,35 @@ var SuperatomSDK = class {
7930
8956
  });
7931
8957
  break;
7932
8958
  case "USER_PROMPT_SUGGESTIONS_REQ":
7933
- handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg)).catch((error) => {
8959
+ handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg), this.collections, this.userId).catch((error) => {
7934
8960
  logger.error("Failed to handle user prompt suggestions request:", error);
7935
8961
  });
7936
8962
  break;
7937
8963
  case "COMPONENT_LIST_RES":
7938
- handleComponentListResponse(parsed, (com) => this.storeComponents(com)).catch((error) => {
8964
+ handleComponentListResponse(parsed, (com) => this.storeComponents(com), this.collections).catch((error) => {
7939
8965
  logger.error("Failed to handle component list request:", error);
7940
8966
  });
7941
8967
  break;
7942
8968
  case "USERS":
7943
- handleUsersRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8969
+ handleUsersRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7944
8970
  logger.error("Failed to handle users request:", error);
7945
8971
  });
7946
8972
  break;
7947
8973
  case "DASHBOARDS":
7948
- handleDashboardsRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8974
+ handleDashboardsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7949
8975
  logger.error("Failed to handle dashboards request:", error);
7950
8976
  });
7951
8977
  break;
7952
8978
  case "REPORTS":
7953
- handleReportsRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8979
+ handleReportsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7954
8980
  logger.error("Failed to handle reports request:", error);
7955
8981
  });
7956
8982
  break;
8983
+ case "UIS":
8984
+ handleUIsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
8985
+ logger.error("Failed to handle UIs request:", error);
8986
+ });
8987
+ break;
7957
8988
  case "BOOKMARKS":
7958
8989
  handleBookmarksRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7959
8990
  logger.error("Failed to handle bookmarks request:", error);