@burgan-tech/morph-touch-runtime 0.0.2
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/LICENSE +21 -0
- package/burgan-tech-morph-touch-runtime-0.0.2.tgz +0 -0
- package/package.json +21 -0
- package/touch/Extensions/.gitkeep +0 -0
- package/touch/Functions/.gitkeep +0 -0
- package/touch/Functions/check-livekit-room-access.1.0.0.json +28 -0
- package/touch/Functions/check-livekit-room-access.http +44 -0
- package/touch/Functions/get-absence-entry.1.0.0.json +28 -0
- package/touch/Functions/get-advisor-stats.1.0.0.json +27 -0
- package/touch/Functions/get-available-slots.1.0.0.json +30 -0
- package/touch/Functions/get-available-slots.http +29 -0
- package/touch/Functions/get-chat-rooms.1.0.0.json +28 -0
- package/touch/Functions/get-chat-rooms.http +62 -0
- package/touch/Functions/get-customer-info.1.0.0.json +27 -0
- package/touch/Functions/get-matrix-sync.1.0.0.json +28 -0
- package/touch/Functions/get-rezervations.1.0.0.json +26 -0
- package/touch/Functions/get-rezervations.http +59 -0
- package/touch/Functions/get-room-messages.1.0.0.json +29 -0
- package/touch/Functions/get-room-messages.http +45 -0
- package/touch/Functions/rezervation-transfer.http +118 -0
- package/touch/Functions/send-room-message.1.0.0.json +29 -0
- package/touch/Functions/src/CheckLivekitRoomAccessMapping.csx +238 -0
- package/touch/Functions/src/GetAbsenceEntryMapping.csx +225 -0
- package/touch/Functions/src/GetAdvisorStatsMapping.csx +190 -0
- package/touch/Functions/src/GetAvailableSlotsMapping.csx +468 -0
- package/touch/Functions/src/GetChatRoomsMapping.csx +202 -0
- package/touch/Functions/src/GetCustomerInfoMapping.csx +140 -0
- package/touch/Functions/src/GetMatrixSyncMapping.csx +197 -0
- package/touch/Functions/src/GetRezervationsMapping.csx +162 -0
- package/touch/Functions/src/GetRoomMessagesMapping.csx +165 -0
- package/touch/Functions/src/SendCancelNotificationMapping.csx +63 -0
- package/touch/Functions/src/SendRoomMessageMapping.csx +131 -0
- package/touch/Schemas/.gitkeep +0 -0
- package/touch/Schemas/absence-entry.1.0.0.json +232 -0
- package/touch/Schemas/advisor-chat-rooms.1.0.0.json +62 -0
- package/touch/Schemas/chat-room.1.0.0.json +110 -0
- package/touch/Schemas/notification-sender.1.0.0.json +159 -0
- package/touch/Schemas/portfolio-manager.1.0.0.json +63 -0
- package/touch/Schemas/rezervation.1.0.0.json +102 -0
- package/touch/Tasks/.gitkeep +0 -0
- package/touch/Tasks/cancel-absence-entry-for-rezervation.1.0.0.json +21 -0
- package/touch/Tasks/check-already-completed-chat-room.1.0.0.json +24 -0
- package/touch/Tasks/check-duplicate-portfolio-manager.1.0.0.json +23 -0
- package/touch/Tasks/check-duplicate-rezervation.1.0.0.json +23 -0
- package/touch/Tasks/check-existing-permanent-chat-room.1.0.0.json +21 -0
- package/touch/Tasks/check-randevu-time.1.0.0.json +17 -0
- package/touch/Tasks/create-permanent-chat-room.1.0.0.json +28 -0
- package/touch/Tasks/determine-transfer-type.1.0.0.json +16 -0
- package/touch/Tasks/enrich-rezervations-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/execute-permanent-chatroom-update.1.0.0.json +21 -0
- package/touch/Tasks/execute-rez-chatroom-transfer.1.0.0.json +21 -0
- package/touch/Tasks/execute-rezervation-transfer.1.0.0.json +19 -0
- package/touch/Tasks/fetch-absence-entries-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-advisors-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-permanent-chatrooms-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-rez-chatrooms-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-rezervations-for-transfer.1.0.0.json +22 -0
- package/touch/Tasks/get-absence-entry-task.1.0.0.json +23 -0
- package/touch/Tasks/get-available-slots-http.1.0.0.json +27 -0
- package/touch/Tasks/get-available-slots.1.0.0.json +24 -0
- package/touch/Tasks/get-chat-room-data-for-rezervation.1.0.0.json +23 -0
- package/touch/Tasks/get-chat-token.1.0.0.json +27 -0
- package/touch/Tasks/get-matrix-room-messages.1.0.0.json +25 -0
- package/touch/Tasks/get-matrix-sync.1.0.0.json +25 -0
- package/touch/Tasks/get-rezervation-data-task.1.0.0.json +22 -0
- package/touch/Tasks/get-rezervation-state-task.1.0.0.json +22 -0
- package/touch/Tasks/get-rezervations-task.1.0.0.json +21 -0
- package/touch/Tasks/get-user-info-for-rezervation.1.0.0.json +24 -0
- package/touch/Tasks/get-video-call-url.1.0.0.json +17 -0
- package/touch/Tasks/invite-user-to-rezervation-room.1.0.0.json +27 -0
- package/touch/Tasks/join-chat-room-for-rezervation.1.0.0.json +28 -0
- package/touch/Tasks/join-matrix-room.1.0.0.json +27 -0
- package/touch/Tasks/join-user-to-room.1.0.0.json +27 -0
- package/touch/Tasks/merge-invited-user.1.0.0.json +17 -0
- package/touch/Tasks/merge-rezervation-update.1.0.0.json +16 -0
- package/touch/Tasks/merge-target-advisor-for-transfer.1.0.0.json +17 -0
- package/touch/Tasks/merge-update-body-for-randevu-update.1.0.0.json +16 -0
- package/touch/Tasks/merge-video-call-urls.1.0.0.json +17 -0
- package/touch/Tasks/query-chat-room-instances.1.0.0.json +23 -0
- package/touch/Tasks/remove-member-from-room.1.0.0.json +28 -0
- package/touch/Tasks/send-matrix-room-message.1.0.0.json +26 -0
- package/touch/Tasks/send-push-notification.1.0.0.json +26 -0
- package/touch/Tasks/send-sms-notification.1.0.0.json +26 -0
- package/touch/Tasks/set-chat-room-status-active.1.0.0.json +16 -0
- package/touch/Tasks/set-chat-room-status-deactive.1.0.0.json +16 -0
- package/touch/Tasks/set-previous-advisor.1.0.0.json +16 -0
- package/touch/Tasks/set-user-from-headers-for-rezervation.1.0.0.json +17 -0
- package/touch/Tasks/start-absence-entry-for-rezervation.1.0.0.json +21 -0
- package/touch/Tasks/start-chat-room-for-rezervation.1.0.0.json +20 -0
- package/touch/Tasks/start-notification-sender.1.0.0.json +20 -0
- package/touch/Tasks/start-permanent-chat-room.1.0.0.json +21 -0
- package/touch/Tasks/start-transfer-from-absence-entry.1.0.0.json +19 -0
- package/touch/Tasks/start-video-call.1.0.0.json +22 -0
- package/touch/Tasks/trigger-chat-room-deactivate.1.0.0.json +21 -0
- package/touch/Tasks/trigger-chat-room-transfer.1.0.0.json +21 -0
- package/touch/Tasks/trigger-chat-room-update.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-add-invited-participant.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-apply-update.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-to-in-meet.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-video-call-update.1.0.0.json +21 -0
- package/touch/Tasks/validate-date-for-rezervation.1.0.0.json +18 -0
- package/touch/Tasks/validate-slot-for-rezervation.1.0.0.json +24 -0
- package/touch/Tasks/validate-transfer-availability.1.0.0.json +23 -0
- package/touch/Views/.gitkeep +0 -0
- package/touch/Workflows/.gitkeep +0 -0
- package/touch/Workflows/absence-entry.http +458 -0
- package/touch/Workflows/absence-entry.json +179 -0
- package/touch/Workflows/add-participant-to-rezervation.http +47 -0
- package/touch/Workflows/add-participant-to-rezervation.json +340 -0
- package/touch/Workflows/chat-room.http +207 -0
- package/touch/Workflows/chat-room.json +452 -0
- package/touch/Workflows/investment-advisor.json +367 -0
- package/touch/Workflows/notification-sender.http +299 -0
- package/touch/Workflows/notification-sender.json +262 -0
- package/touch/Workflows/portfolio-manager.json +367 -0
- package/touch/Workflows/randevu-update.http +87 -0
- package/touch/Workflows/rezervation-start.json +467 -0
- package/touch/Workflows/rezervation-transfer.json +512 -0
- package/touch/Workflows/rezervation-update.http +87 -0
- package/touch/Workflows/rezervation-update.json +485 -0
- package/touch/Workflows/rezervation.http +214 -0
- package/touch/Workflows/rezervation.json +726 -0
- package/touch/Workflows/src/AllChatRoomsSuccessRule.csx +65 -0
- package/touch/Workflows/src/AlwaysTrueRule.csx +13 -0
- package/touch/Workflows/src/AnyChatRoomFailedRule.csx +64 -0
- package/touch/Workflows/src/AutoProcessRule.csx +38 -0
- package/touch/Workflows/src/BuildRezChatRoomPlanMapping.csx +160 -0
- package/touch/Workflows/src/CanStartRezervationTimerMapping.csx +48 -0
- package/touch/Workflows/src/CanStartTransferMapping.csx +14 -0
- package/touch/Workflows/src/CancelAbsenceEntryForRezervationMapping.csx +48 -0
- package/touch/Workflows/src/CancelAbsenceForRandevuUpdateMapping.csx +62 -0
- package/touch/Workflows/src/ChatRoomCreatedFailedRule.csx +54 -0
- package/touch/Workflows/src/ChatRoomCreatedSuccessRule.csx +54 -0
- package/touch/Workflows/src/ChatRoomRemoveMapping.csx +104 -0
- package/touch/Workflows/src/ChatRoomTransferInviteMapping.csx +109 -0
- package/touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +71 -0
- package/touch/Workflows/src/ChatRoomUpdateMapping.csx +107 -0
- package/touch/Workflows/src/CheckAlreadyCompletedChatRoomMapping.csx +100 -0
- package/touch/Workflows/src/CheckDuplicatePortfolioManagerMapping.csx +119 -0
- package/touch/Workflows/src/CheckDuplicateRezervationMapping.csx +150 -0
- package/touch/Workflows/src/CheckExistingPermanentChatRoomMapping.csx +169 -0
- package/touch/Workflows/src/CheckRandevuTimeMapping.csx +67 -0
- package/touch/Workflows/src/CheckRezervationStateActiveOrInMeetRule.csx +14 -0
- package/touch/Workflows/src/CreateAbsenceEntryForRezervationMapping.csx +111 -0
- package/touch/Workflows/src/CreateAbsenceForRandevuUpdateMapping.csx +108 -0
- package/touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +122 -0
- package/touch/Workflows/src/CreatePermanentChatRoomMapping.csx +140 -0
- package/touch/Workflows/src/CustomerControlToEndRule.csx +14 -0
- package/touch/Workflows/src/DetermineTransferTypeMapping.csx +92 -0
- package/touch/Workflows/src/EnrichRezervationsForTransferMapping.csx +495 -0
- package/touch/Workflows/src/ExecutePermanentChatRoomUpdateMapping.csx +124 -0
- package/touch/Workflows/src/ExecuteRezChatRoomTransferMapping.csx +95 -0
- package/touch/Workflows/src/ExecuteTransferMapping.csx +152 -0
- package/touch/Workflows/src/FetchAbsenceEntriesForTransferMapping.csx +116 -0
- package/touch/Workflows/src/FetchAdvisorsForTransferMapping.csx +145 -0
- package/touch/Workflows/src/FetchPermanentChatRoomsMapping.csx +128 -0
- package/touch/Workflows/src/FetchRezervationsForTransferMapping.csx +124 -0
- package/touch/Workflows/src/GetChatRoomDataForRezervationMapping.csx +100 -0
- package/touch/Workflows/src/GetChatTokenMapping.csx +85 -0
- package/touch/Workflows/src/GetRezervationDataForAddParticipantMapping.csx +105 -0
- package/touch/Workflows/src/GetRezervationDataForRandevuUpdateMapping.csx +110 -0
- package/touch/Workflows/src/GetRezervationDataMapping.csx +111 -0
- package/touch/Workflows/src/GetRezervationStateForRandevuUpdateMapping.csx +80 -0
- package/touch/Workflows/src/GetRezervationStateMapping.csx +92 -0
- package/touch/Workflows/src/GetUserInfoForRezervationMapping.csx +63 -0
- package/touch/Workflows/src/GetVideoCallUrlMapping.csx +62 -0
- package/touch/Workflows/src/HasChangedAdvisorRule.csx +28 -0
- package/touch/Workflows/src/HasChatIntegrationRule.csx +41 -0
- package/touch/Workflows/src/HasExistingPermanentRoomRule.csx +28 -0
- package/touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +86 -0
- package/touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +78 -0
- package/touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +88 -0
- package/touch/Workflows/src/InvitedUserMergeMapping.csx +77 -0
- package/touch/Workflows/src/InvitedUserNotAllowedRule.csx +71 -0
- package/touch/Workflows/src/InvitedUserNotInMeetRule.csx +19 -0
- package/touch/Workflows/src/IsNotfSentRule.csx +36 -0
- package/touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +118 -0
- package/touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +119 -0
- package/touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +118 -0
- package/touch/Workflows/src/JoinMatrixRoomMapping.csx +100 -0
- package/touch/Workflows/src/JoinUserToRoomMapping.csx +118 -0
- package/touch/Workflows/src/LoginForAddParticipantChatMapping.csx +102 -0
- package/touch/Workflows/src/LoginForRandevuStartChatMapping.csx +96 -0
- package/touch/Workflows/src/MergeRezervationUpdateMapping.csx +82 -0
- package/touch/Workflows/src/MergeTargetAdvisorForTransferMapping.csx +79 -0
- package/touch/Workflows/src/MergeUpdateBodyForRandevuUpdateMapping.csx +91 -0
- package/touch/Workflows/src/NoExistingPermanentRoomRule.csx +23 -0
- package/touch/Workflows/src/NotificationCompleteAlwaysRule.csx +14 -0
- package/touch/Workflows/src/NotificationCompleteFromPendingRule.csx +41 -0
- package/touch/Workflows/src/NotificationCompleteFromSmsRule.csx +36 -0
- package/touch/Workflows/src/NotificationPushFromPendingRule.csx +42 -0
- package/touch/Workflows/src/NotificationPushFromSmsRule.csx +36 -0
- package/touch/Workflows/src/NotificationSmsPendingRule.csx +32 -0
- package/touch/Workflows/src/PermanentDoneRule.csx +44 -0
- package/touch/Workflows/src/PermanentProcessNextRule.csx +44 -0
- package/touch/Workflows/src/RezChatRoomProcessNextRule.csx +44 -0
- package/touch/Workflows/src/RezChatRoomsDoneRule.csx +44 -0
- package/touch/Workflows/src/SendPushNotificationMapping.csx +146 -0
- package/touch/Workflows/src/SendSmsNotificationMapping.csx +138 -0
- package/touch/Workflows/src/SetChatRoomStatusActiveMapping.csx +22 -0
- package/touch/Workflows/src/SetChatRoomStatusDeactiveMapping.csx +22 -0
- package/touch/Workflows/src/SetPreviousAdvisorMapping.csx +28 -0
- package/touch/Workflows/src/SetUserFromHeadersForRezervationMapping.csx +24 -0
- package/touch/Workflows/src/SlotAvailableRule.csx +33 -0
- package/touch/Workflows/src/SlotUnavailableRule.csx +33 -0
- package/touch/Workflows/src/StartChatRoomForRezervationMapping.csx +100 -0
- package/touch/Workflows/src/StartGetChatTokenForRezervationMapping.csx +71 -0
- package/touch/Workflows/src/StartNotificationForAdvisorMapping.csx +117 -0
- package/touch/Workflows/src/StartNotificationForRezervationFromUserInfoMapping.csx +128 -0
- package/touch/Workflows/src/StartNotificationForUserMapping.csx +117 -0
- package/touch/Workflows/src/StartPermanentChatRoomMapping.csx +92 -0
- package/touch/Workflows/src/StartTransferFromAbsenceEntryMapping.csx +94 -0
- package/touch/Workflows/src/StartVideoCallCustomerSubFlowMapping.csx +37 -0
- package/touch/Workflows/src/StartVideoCallForInvitedParticipantMapping.csx +54 -0
- package/touch/Workflows/src/StartVideoCallForRandevuStartMapping.csx +70 -0
- package/touch/Workflows/src/StartVideoCallStaffSubFlowMapping.csx +37 -0
- package/touch/Workflows/src/StateActiveForUpdateRule.csx +14 -0
- package/touch/Workflows/src/StateActiveRule.csx +14 -0
- package/touch/Workflows/src/StateInMeetRule.csx +14 -0
- package/touch/Workflows/src/StateNotActiveForUpdateRule.csx +14 -0
- package/touch/Workflows/src/StateNotActiveOrInMeetRule.csx +14 -0
- package/touch/Workflows/src/StatusCustomerEnterRule.csx +25 -0
- package/touch/Workflows/src/StatusStaffEnterRule.csx +25 -0
- package/touch/Workflows/src/SyncWorkingHoursRule.csx +46 -0
- package/touch/Workflows/src/TokenSuccessRule.csx +24 -0
- package/touch/Workflows/src/TransferAllDoneRule.csx +50 -0
- package/touch/Workflows/src/TransferHasInvalidRule.csx +34 -0
- package/touch/Workflows/src/TransferProcessNextRule.csx +50 -0
- package/touch/Workflows/src/TriggerChatRoomDeactivateMapping.csx +77 -0
- package/touch/Workflows/src/TriggerChatRoomTransferMapping.csx +93 -0
- package/touch/Workflows/src/TriggerChatRoomUpdateMapping.csx +99 -0
- package/touch/Workflows/src/TriggerRezervationAddInvitedParticipantMapping.csx +77 -0
- package/touch/Workflows/src/TriggerRezervationApplyUpdateMapping.csx +66 -0
- package/touch/Workflows/src/TriggerRezervationToInMeetMapping.csx +69 -0
- package/touch/Workflows/src/TriggerRezervationVideoCallUpdateMapping.csx +67 -0
- package/touch/Workflows/src/ValidateDateForRezervationMapping.csx +60 -0
- package/touch/Workflows/src/ValidateSlotForRandevuUpdateMapping.csx +211 -0
- package/touch/Workflows/src/ValidateSlotForRezervationMapping.csx +246 -0
- package/touch/Workflows/src/ValidateTransferMapping.csx +243 -0
- package/touch/Workflows/src/VideoCallUrlUpdateMergeMapping.csx +141 -0
- package/touch/Workflows/start-chat.json +217 -0
- package/touch/Workflows/start-video-call.http +93 -0
- package/touch/Workflows/start-video-call.json +206 -0
- package/vnext.config.json +58 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for remove-member-from-room HttpTask (Type 6) in the chat-room remove transition.
|
|
9
|
+
/// Kicks a member from the permanent room via native /_matrix/client/v3/rooms/{roomId}/kick.
|
|
10
|
+
/// APISIX converts X-Matrix-User header to Bearer token automatically.
|
|
11
|
+
/// </summary>
|
|
12
|
+
public class ChatRoomRemoveMapping : ScriptBase, IMapping
|
|
13
|
+
{
|
|
14
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
15
|
+
{
|
|
16
|
+
var httpTask = task as HttpTask;
|
|
17
|
+
if (httpTask == null)
|
|
18
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
19
|
+
|
|
20
|
+
var data = context.Instance?.Data;
|
|
21
|
+
var user = GetString(data, "user");
|
|
22
|
+
var chatIntegration = data?.chatIntegration;
|
|
23
|
+
var roomId = GetString(chatIntegration, "roomId");
|
|
24
|
+
|
|
25
|
+
if (string.IsNullOrWhiteSpace(roomId))
|
|
26
|
+
return new ScriptResponse();
|
|
27
|
+
|
|
28
|
+
var removeMemberId = GetString(data, "removeMemberId");
|
|
29
|
+
if (string.IsNullOrWhiteSpace(removeMemberId))
|
|
30
|
+
return new ScriptResponse();
|
|
31
|
+
|
|
32
|
+
var matrixBaseUrl = await GetSecretAsync("vnext-secret", "workflow-secret", "MatrixBaseUrl");
|
|
33
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
34
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
35
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId) + "/kick";
|
|
36
|
+
httpTask.SetUrl(fullUrl);
|
|
37
|
+
|
|
38
|
+
var matrixUserId = removeMemberId.Trim().StartsWith("@") ? removeMemberId.Trim() : $"@{removeMemberId.Trim()}:localhost";
|
|
39
|
+
|
|
40
|
+
var headers = new Dictionary<string, string>
|
|
41
|
+
{
|
|
42
|
+
["Content-Type"] = "application/json",
|
|
43
|
+
["Accept"] = "application/json",
|
|
44
|
+
["X-Matrix-User"] = user
|
|
45
|
+
};
|
|
46
|
+
httpTask.SetHeaders(headers);
|
|
47
|
+
|
|
48
|
+
httpTask.SetBody(new { user_id = matrixUserId });
|
|
49
|
+
|
|
50
|
+
return new ScriptResponse();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
54
|
+
{
|
|
55
|
+
var result = new ScriptResponse();
|
|
56
|
+
var data = context.Instance?.Data;
|
|
57
|
+
|
|
58
|
+
var advisorId = GetString(data, "advisorId");
|
|
59
|
+
var removeMemberId = GetString(data, "removeMemberId");
|
|
60
|
+
var user = GetString(data, "user");
|
|
61
|
+
var advisorType = GetString(data, "advisorType");
|
|
62
|
+
|
|
63
|
+
string roomId = null;
|
|
64
|
+
if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
|
|
65
|
+
roomId = GetString(data.chatIntegration, "roomId");
|
|
66
|
+
|
|
67
|
+
var members = new List<object>();
|
|
68
|
+
if (HasProperty(data, "members") && data.members != null)
|
|
69
|
+
{
|
|
70
|
+
foreach (var m in data.members)
|
|
71
|
+
{
|
|
72
|
+
var mid = GetString(m, "memberId") ?? GetString(m, "advisorId");
|
|
73
|
+
if (!string.IsNullOrWhiteSpace(mid) && mid != removeMemberId)
|
|
74
|
+
members.Add(new { memberId = mid, role = GetString(m, "role") });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
result.Data = new
|
|
79
|
+
{
|
|
80
|
+
user,
|
|
81
|
+
advisorType,
|
|
82
|
+
advisorId,
|
|
83
|
+
chatIntegration = new { roomId },
|
|
84
|
+
members = members
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return Task.FromResult(result);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private string GetString(dynamic obj, string name)
|
|
91
|
+
{
|
|
92
|
+
if (obj == null) return null;
|
|
93
|
+
try
|
|
94
|
+
{
|
|
95
|
+
if (HasProperty(obj, name))
|
|
96
|
+
{
|
|
97
|
+
var v = GetPropertyValue(obj, name);
|
|
98
|
+
return v?.ToString();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch { }
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for invite-user-to-rezervation-room HttpTask (Type 6) in the chat-room transfer transition (invite step).
|
|
9
|
+
/// Invites the new advisor to the room after the old one was kicked.
|
|
10
|
+
/// Uses /_matrix/client/v3/rooms/{roomId}/invite.
|
|
11
|
+
/// APISIX converts X-Matrix-User header to Bearer token automatically.
|
|
12
|
+
/// MatrixBaseUrl is read from Vault (vnext-secret/workflow-secret).
|
|
13
|
+
/// Also updates instanceData.advisorId to the new advisor.
|
|
14
|
+
/// </summary>
|
|
15
|
+
public class ChatRoomTransferInviteMapping : ScriptBase, IMapping
|
|
16
|
+
{
|
|
17
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
18
|
+
{
|
|
19
|
+
var httpTask = task as HttpTask;
|
|
20
|
+
if (httpTask == null)
|
|
21
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
22
|
+
|
|
23
|
+
var data = context.Instance?.Data;
|
|
24
|
+
var user = GetString(data, "user");
|
|
25
|
+
var chatIntegration = data?.chatIntegration;
|
|
26
|
+
var roomId = GetString(chatIntegration, "roomId");
|
|
27
|
+
|
|
28
|
+
var newAdvisorId = GetString(data, "newAdvisorId");
|
|
29
|
+
|
|
30
|
+
if (string.IsNullOrWhiteSpace(roomId) || string.IsNullOrWhiteSpace(newAdvisorId))
|
|
31
|
+
return new ScriptResponse();
|
|
32
|
+
|
|
33
|
+
var matrixBaseUrl = await GetSecretAsync("vnext-secret", "workflow-secret", "MatrixBaseUrl");
|
|
34
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
35
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
36
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId) + "/invite";
|
|
37
|
+
httpTask.SetUrl(fullUrl);
|
|
38
|
+
|
|
39
|
+
var matrixUserId = newAdvisorId.Trim().StartsWith("@") ? newAdvisorId.Trim() : $"@{newAdvisorId.Trim()}:localhost";
|
|
40
|
+
|
|
41
|
+
var headers = new Dictionary<string, string>
|
|
42
|
+
{
|
|
43
|
+
["Content-Type"] = "application/json",
|
|
44
|
+
["Accept"] = "application/json",
|
|
45
|
+
["X-Matrix-User"] = user
|
|
46
|
+
};
|
|
47
|
+
httpTask.SetHeaders(headers);
|
|
48
|
+
|
|
49
|
+
httpTask.SetBody(new { user_id = matrixUserId });
|
|
50
|
+
|
|
51
|
+
return new ScriptResponse();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
55
|
+
{
|
|
56
|
+
var result = new ScriptResponse();
|
|
57
|
+
var data = context.Instance?.Data;
|
|
58
|
+
|
|
59
|
+
var newAdvisorId = GetString(data, "newAdvisorId");
|
|
60
|
+
var oldAdvisorId = GetString(data, "advisorId");
|
|
61
|
+
var user = GetString(data, "user");
|
|
62
|
+
var advisorType = GetString(data, "advisorType");
|
|
63
|
+
|
|
64
|
+
string roomId = null;
|
|
65
|
+
if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
|
|
66
|
+
roomId = GetString(data.chatIntegration, "roomId");
|
|
67
|
+
|
|
68
|
+
var members = new List<object>();
|
|
69
|
+
if (HasProperty(data, "members") && data.members != null)
|
|
70
|
+
{
|
|
71
|
+
foreach (var m in data.members)
|
|
72
|
+
{
|
|
73
|
+
var mid = GetString(m, "memberId") ?? GetString(m, "advisorId");
|
|
74
|
+
var role = GetString(m, "role");
|
|
75
|
+
if (mid == oldAdvisorId && role == "advisor" && !string.IsNullOrWhiteSpace(newAdvisorId))
|
|
76
|
+
members.Add(new { memberId = newAdvisorId.Trim(), role = "advisor" });
|
|
77
|
+
else
|
|
78
|
+
members.Add(new { memberId = mid, role = role });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
result.Data = new
|
|
83
|
+
{
|
|
84
|
+
user,
|
|
85
|
+
advisorType,
|
|
86
|
+
advisorId = !string.IsNullOrWhiteSpace(newAdvisorId) ? newAdvisorId.Trim() : oldAdvisorId,
|
|
87
|
+
chatIntegration = new { roomId },
|
|
88
|
+
members = members,
|
|
89
|
+
pendingJoinUserId = newAdvisorId
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return Task.FromResult(result);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private string GetString(dynamic obj, string name)
|
|
96
|
+
{
|
|
97
|
+
if (obj == null) return null;
|
|
98
|
+
try
|
|
99
|
+
{
|
|
100
|
+
if (HasProperty(obj, name))
|
|
101
|
+
{
|
|
102
|
+
var v = GetPropertyValue(obj, name);
|
|
103
|
+
return v?.ToString();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch { }
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for remove-member-from-room HttpTask (Type 6) in the chat-room transfer transition (kick step).
|
|
9
|
+
/// Kicks the current advisor from the room before inviting the new one.
|
|
10
|
+
/// Uses /_matrix/client/v3/rooms/{roomId}/kick.
|
|
11
|
+
/// APISIX converts X-Matrix-User header to Bearer token automatically.
|
|
12
|
+
/// </summary>
|
|
13
|
+
public class ChatRoomTransferRemoveMapping : ScriptBase, IMapping
|
|
14
|
+
{
|
|
15
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
16
|
+
{
|
|
17
|
+
var httpTask = task as HttpTask;
|
|
18
|
+
if (httpTask == null)
|
|
19
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
20
|
+
|
|
21
|
+
var matrixBaseUrl = await GetSecretAsync("vnext-secret", "workflow-secret", "MatrixBaseUrl");
|
|
22
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
23
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
24
|
+
|
|
25
|
+
var data = context.Instance?.Data;
|
|
26
|
+
var user = GetString(data, "user");
|
|
27
|
+
var chatIntegration = data?.chatIntegration;
|
|
28
|
+
var roomId = GetString(chatIntegration, "roomId");
|
|
29
|
+
var currentAdvisorId = GetString(data, "advisorId");
|
|
30
|
+
|
|
31
|
+
if (string.IsNullOrWhiteSpace(roomId) || string.IsNullOrWhiteSpace(currentAdvisorId))
|
|
32
|
+
return new ScriptResponse();
|
|
33
|
+
|
|
34
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId) + "/kick";
|
|
35
|
+
httpTask.SetUrl(fullUrl);
|
|
36
|
+
|
|
37
|
+
var matrixUserId = currentAdvisorId.Trim().StartsWith("@") ? currentAdvisorId.Trim() : $"@{currentAdvisorId.Trim()}:localhost";
|
|
38
|
+
|
|
39
|
+
var headers = new Dictionary<string, string>
|
|
40
|
+
{
|
|
41
|
+
["Content-Type"] = "application/json",
|
|
42
|
+
["Accept"] = "application/json",
|
|
43
|
+
["X-Matrix-User"] = user
|
|
44
|
+
};
|
|
45
|
+
httpTask.SetHeaders(headers);
|
|
46
|
+
|
|
47
|
+
httpTask.SetBody(new { user_id = matrixUserId });
|
|
48
|
+
|
|
49
|
+
return new ScriptResponse();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
53
|
+
{
|
|
54
|
+
return Task.FromResult(new ScriptResponse());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private string GetString(dynamic obj, string name)
|
|
58
|
+
{
|
|
59
|
+
if (obj == null) return null;
|
|
60
|
+
try
|
|
61
|
+
{
|
|
62
|
+
if (HasProperty(obj, name))
|
|
63
|
+
{
|
|
64
|
+
var v = GetPropertyValue(obj, name);
|
|
65
|
+
return v?.ToString();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for invite-user-to-rezervation-room HttpTask (Type 6) in the chat-room update transition.
|
|
9
|
+
/// Invites a new member to the permanent room via native /_matrix/client/v3/rooms/{roomId}/invite.
|
|
10
|
+
/// APISIX converts X-Matrix-User header to Bearer token automatically.
|
|
11
|
+
/// MatrixBaseUrl is read from Vault (vnext-secret/workflow-secret).
|
|
12
|
+
/// </summary>
|
|
13
|
+
public class ChatRoomUpdateMapping : ScriptBase, IMapping
|
|
14
|
+
{
|
|
15
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
16
|
+
{
|
|
17
|
+
var httpTask = task as HttpTask;
|
|
18
|
+
if (httpTask == null)
|
|
19
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
20
|
+
|
|
21
|
+
var data = context.Instance?.Data;
|
|
22
|
+
var user = GetString(data, "user");
|
|
23
|
+
var chatIntegration = data?.chatIntegration;
|
|
24
|
+
var roomId = GetString(chatIntegration, "roomId");
|
|
25
|
+
|
|
26
|
+
if (string.IsNullOrWhiteSpace(roomId))
|
|
27
|
+
return new ScriptResponse();
|
|
28
|
+
|
|
29
|
+
var newMemberId = GetString(data, "newMemberId");
|
|
30
|
+
if (string.IsNullOrWhiteSpace(newMemberId))
|
|
31
|
+
return new ScriptResponse();
|
|
32
|
+
|
|
33
|
+
var matrixBaseUrl = await GetSecretAsync("vnext-secret", "workflow-secret", "MatrixBaseUrl");
|
|
34
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
35
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
36
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId) + "/invite";
|
|
37
|
+
httpTask.SetUrl(fullUrl);
|
|
38
|
+
|
|
39
|
+
var matrixUserId = newMemberId.Trim().StartsWith("@") ? newMemberId.Trim() : $"@{newMemberId.Trim()}:localhost";
|
|
40
|
+
|
|
41
|
+
var headers = new Dictionary<string, string>
|
|
42
|
+
{
|
|
43
|
+
["Content-Type"] = "application/json",
|
|
44
|
+
["Accept"] = "application/json",
|
|
45
|
+
["X-Matrix-User"] = user
|
|
46
|
+
};
|
|
47
|
+
httpTask.SetHeaders(headers);
|
|
48
|
+
|
|
49
|
+
httpTask.SetBody(new { user_id = matrixUserId });
|
|
50
|
+
|
|
51
|
+
return new ScriptResponse();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
55
|
+
{
|
|
56
|
+
var result = new ScriptResponse();
|
|
57
|
+
var data = context.Instance?.Data;
|
|
58
|
+
|
|
59
|
+
var advisorId = GetString(data, "advisorId");
|
|
60
|
+
var newMemberId = GetString(data, "newMemberId");
|
|
61
|
+
var user = GetString(data, "user");
|
|
62
|
+
var advisorType = GetString(data, "advisorType");
|
|
63
|
+
|
|
64
|
+
string roomId = null;
|
|
65
|
+
if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
|
|
66
|
+
roomId = GetString(data.chatIntegration, "roomId");
|
|
67
|
+
|
|
68
|
+
var members = new List<object>();
|
|
69
|
+
if (HasProperty(data, "members") && data.members != null)
|
|
70
|
+
{
|
|
71
|
+
foreach (var m in data.members)
|
|
72
|
+
{
|
|
73
|
+
var mid = GetString(m, "memberId") ?? GetString(m, "advisorId");
|
|
74
|
+
members.Add(new { memberId = mid, role = GetString(m, "role") });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!string.IsNullOrWhiteSpace(newMemberId))
|
|
78
|
+
members.Add(new { memberId = newMemberId, role = "member" });
|
|
79
|
+
|
|
80
|
+
result.Data = new
|
|
81
|
+
{
|
|
82
|
+
user,
|
|
83
|
+
advisorType,
|
|
84
|
+
advisorId,
|
|
85
|
+
chatIntegration = new { roomId },
|
|
86
|
+
members = members,
|
|
87
|
+
pendingJoinUserId = newMemberId
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return Task.FromResult(result);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private string GetString(dynamic obj, string name)
|
|
94
|
+
{
|
|
95
|
+
if (obj == null) return null;
|
|
96
|
+
try
|
|
97
|
+
{
|
|
98
|
+
if (HasProperty(obj, name))
|
|
99
|
+
{
|
|
100
|
+
var v = GetPropertyValue(obj, name);
|
|
101
|
+
return v?.ToString();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch { }
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for check-already-completed-chat-room (DaprServiceTask - Type 3).
|
|
9
|
+
/// Queries chat-room workflow instances to check if a completed instance
|
|
10
|
+
/// already exists for the same user and advisorType. Used in creating-room state onEntry with errorBoundary.
|
|
11
|
+
/// </summary>
|
|
12
|
+
public class CheckAlreadyCompletedChatRoomMapping : ScriptBase, IMapping
|
|
13
|
+
{
|
|
14
|
+
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
15
|
+
{
|
|
16
|
+
var serviceTask = task as DaprServiceTask;
|
|
17
|
+
if (serviceTask == null)
|
|
18
|
+
throw new InvalidOperationException("Task must be a DaprServiceTask");
|
|
19
|
+
|
|
20
|
+
var appId = GetConfigValue("DAPR_APP_ID");
|
|
21
|
+
if (!string.IsNullOrEmpty(appId))
|
|
22
|
+
serviceTask.SetAppId(appId);
|
|
23
|
+
|
|
24
|
+
var data = context.Instance?.Data;
|
|
25
|
+
if (data == null || !HasProperty(data, "user") || data.user == null)
|
|
26
|
+
throw new InvalidOperationException("ALREADY_COMPLETED: User alanı zorunludur.");
|
|
27
|
+
|
|
28
|
+
var user = data.user.ToString();
|
|
29
|
+
if (string.IsNullOrWhiteSpace(user))
|
|
30
|
+
throw new InvalidOperationException("ALREADY_COMPLETED: User alanı zorunludur.");
|
|
31
|
+
|
|
32
|
+
var advisorType = data?.advisorType?.ToString();
|
|
33
|
+
|
|
34
|
+
var userEscaped = user.Replace("\\", "\\\\").Replace("\"", "\\\"");
|
|
35
|
+
var filterParts = new List<string>
|
|
36
|
+
{
|
|
37
|
+
"{\"attributes\":{\"user\":{\"eq\":\"" + userEscaped + "\"}}}"
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (!string.IsNullOrWhiteSpace(advisorType))
|
|
41
|
+
{
|
|
42
|
+
var typeEscaped = advisorType.Replace("\\", "\\\\").Replace("\"", "\\\"");
|
|
43
|
+
filterParts.Add("{\"attributes\":{\"advisorType\":{\"eq\":\"" + typeEscaped + "\"}}}");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
filterParts.Add("{\"attributes\":{\"roomType\":{\"eq\":\"permanent\"}}}");
|
|
47
|
+
filterParts.Add("{\"currentState\":{\"eq\":\"activated\"}}");
|
|
48
|
+
|
|
49
|
+
var queryParams = new List<string>
|
|
50
|
+
{
|
|
51
|
+
"pageSize=10",
|
|
52
|
+
"filter={\"and\":[" + string.Join(",", filterParts) + "]}"
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
serviceTask.SetQueryString(string.Join("&", queryParams));
|
|
56
|
+
|
|
57
|
+
return Task.FromResult(new ScriptResponse());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
61
|
+
{
|
|
62
|
+
var response = context.Body;
|
|
63
|
+
|
|
64
|
+
if (response?.isSuccess == false)
|
|
65
|
+
{
|
|
66
|
+
var errorMessage = response?.errorMessage?.ToString() ?? "Service call failed";
|
|
67
|
+
throw new Exception($"SERVICE_ERROR: {errorMessage}");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var responseData = response?.data;
|
|
71
|
+
var items = responseData?.items;
|
|
72
|
+
|
|
73
|
+
int existingCount = 0;
|
|
74
|
+
if (items != null && items.Count > 0)
|
|
75
|
+
existingCount = items.Count;
|
|
76
|
+
|
|
77
|
+
var data = context.Instance?.Data;
|
|
78
|
+
var roomType = GetString(data, "roomType");
|
|
79
|
+
|
|
80
|
+
if (existingCount > 0 && string.Equals(roomType, "permanent", StringComparison.OrdinalIgnoreCase))
|
|
81
|
+
throw new Exception("ALREADY_COMPLETED: Bu kullanıcı ve danışman tipi için sohbet odası zaten mevcut.");
|
|
82
|
+
|
|
83
|
+
return Task.FromResult(new ScriptResponse { Data = new { } });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private string GetString(dynamic obj, string name)
|
|
87
|
+
{
|
|
88
|
+
if (obj == null) return null;
|
|
89
|
+
try
|
|
90
|
+
{
|
|
91
|
+
if (HasProperty(obj, name))
|
|
92
|
+
{
|
|
93
|
+
var v = GetPropertyValue(obj, name);
|
|
94
|
+
return v?.ToString();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch { }
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for CheckDuplicatePortfolioManager (DaprServiceTask - Type 3)
|
|
9
|
+
/// Queries portfolio-manager workflow instances to check if a record already exists
|
|
10
|
+
/// for the same user. Used in draft state onEntry with errorBoundary.
|
|
11
|
+
///
|
|
12
|
+
/// Flow:
|
|
13
|
+
/// 1. InputHandler: Builds query to filter by user and state (excluding draft)
|
|
14
|
+
/// 2. OutputHandler: If duplicate found, throws exception → errorBoundary catches → rejected state
|
|
15
|
+
///
|
|
16
|
+
/// Filter criteria:
|
|
17
|
+
/// - attributes.user = current instance's user value
|
|
18
|
+
/// - key != current instance key
|
|
19
|
+
/// - status not draft and not rejected
|
|
20
|
+
/// - currentState in (online, offline, busy, away, inactive) - excludes draft
|
|
21
|
+
/// </summary>
|
|
22
|
+
public class CheckDuplicatePortfolioManagerMapping : ScriptBase, IMapping
|
|
23
|
+
{
|
|
24
|
+
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
25
|
+
{
|
|
26
|
+
try
|
|
27
|
+
{
|
|
28
|
+
var serviceTask = task as DaprServiceTask;
|
|
29
|
+
if (serviceTask == null)
|
|
30
|
+
throw new InvalidOperationException("Task must be a DaprServiceTask");
|
|
31
|
+
|
|
32
|
+
var appId = GetConfigValue("DAPR_APP_ID");
|
|
33
|
+
if (!string.IsNullOrEmpty(appId))
|
|
34
|
+
serviceTask.SetAppId(appId);
|
|
35
|
+
|
|
36
|
+
// Get user from current instance data
|
|
37
|
+
var data = context.Instance?.Data;
|
|
38
|
+
if (data == null || !HasProperty(data, "user") || data.user == null)
|
|
39
|
+
{
|
|
40
|
+
throw new InvalidOperationException("DUPLICATE_USER: User field is required for duplicate check");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var user = data.user.ToString();
|
|
44
|
+
|
|
45
|
+
// Get current instance key to exclude it from results
|
|
46
|
+
var currentKey = context.Instance?.Key;
|
|
47
|
+
|
|
48
|
+
// Build query string for filtering
|
|
49
|
+
// Filter: user matches AND key != currentKey AND status not draft/rejected AND state is not draft (online, offline, busy, away, inactive)
|
|
50
|
+
var queryParams = new List<string>
|
|
51
|
+
{
|
|
52
|
+
"pageSize=10",
|
|
53
|
+
"currentState=online,offline,busy,away,inactive",
|
|
54
|
+
$"filter={{\"and\": [{{\"attributes\": {{\"user\": {{\"eq\":\"{user}\"}}}}}}, {{\"key\": {{\"ne\":\"{currentKey}\"}}}}, {{\"currentState\": {{\"ne\":\"draft\"}}}}, {{\"currentState\": {{\"ne\":\"rejected\"}}}}]}}"
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
serviceTask.SetQueryString(string.Join("&", queryParams));
|
|
58
|
+
|
|
59
|
+
return Task.FromResult(new ScriptResponse());
|
|
60
|
+
}
|
|
61
|
+
catch (Exception ex)
|
|
62
|
+
{
|
|
63
|
+
// Re-throw to trigger errorBoundary
|
|
64
|
+
throw;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
69
|
+
{
|
|
70
|
+
try
|
|
71
|
+
{
|
|
72
|
+
// Get Dapr Service response
|
|
73
|
+
var response = context.Body;
|
|
74
|
+
|
|
75
|
+
// Check if service call was successful
|
|
76
|
+
if (response?.isSuccess == false)
|
|
77
|
+
{
|
|
78
|
+
var errorMessage = response?.errorMessage?.ToString() ?? "Service call failed";
|
|
79
|
+
throw new Exception($"SERVICE_ERROR: {errorMessage}");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Get items from service response
|
|
83
|
+
// Response structure: { data: { items: [...] }, isSuccess: true, ... }
|
|
84
|
+
var responseData = response?.data;
|
|
85
|
+
var items = responseData?.items;
|
|
86
|
+
|
|
87
|
+
// Count existing records
|
|
88
|
+
int existingCount = 0;
|
|
89
|
+
string existingKey = null;
|
|
90
|
+
string existingState = null;
|
|
91
|
+
|
|
92
|
+
if (items != null)
|
|
93
|
+
{
|
|
94
|
+
if(items.Count>0)
|
|
95
|
+
{
|
|
96
|
+
existingCount++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// If duplicate found, throw exception to trigger errorBoundary
|
|
101
|
+
if (existingCount > 0)
|
|
102
|
+
{
|
|
103
|
+
var user = context.Instance?.Data?.user?.ToString() ?? "unknown";
|
|
104
|
+
throw new Exception($"DUPLICATE_USER: A portfolio manager record already exists for user '{user}'. Existing record: {existingKey} (state: {existingState})");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// No duplicate found - continue normally
|
|
108
|
+
return Task.FromResult(new ScriptResponse
|
|
109
|
+
{
|
|
110
|
+
Data = new { }
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch (Exception)
|
|
114
|
+
{
|
|
115
|
+
// Re-throw to trigger errorBoundary
|
|
116
|
+
throw;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|