@burgan-tech/morph-touch-runtime 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/burgan-tech-morph-touch-runtime-0.0.6.tgz +0 -0
  2. package/morph-touch/Functions/get-matrix-sync.1.0.0.json +1 -1
  3. package/morph-touch/Functions/get-room-messages.1.0.0.json +1 -1
  4. package/morph-touch/Functions/send-room-message.1.0.0.json +1 -1
  5. package/morph-touch/Functions/src/GetMatrixSyncMapping.csx +5 -1
  6. package/morph-touch/Functions/src/GetRoomMessagesMapping.csx +5 -1
  7. package/morph-touch/Functions/src/SendRoomMessageMapping.csx +5 -1
  8. package/morph-touch/Workflows/chat-room.json +9 -9
  9. package/morph-touch/Workflows/notification-sender.json +2 -2
  10. package/morph-touch/Workflows/rezervation-start.json +1 -1
  11. package/morph-touch/Workflows/rezervation-transfer.json +3 -3
  12. package/morph-touch/Workflows/rezervation.json +1 -1
  13. package/morph-touch/Workflows/src/ChatRoomRemoveMapping.csx +5 -1
  14. package/morph-touch/Workflows/src/ChatRoomTransferInviteMapping.csx +6 -2
  15. package/morph-touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +5 -1
  16. package/morph-touch/Workflows/src/ChatRoomUpdateMapping.csx +6 -2
  17. package/morph-touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +5 -1
  18. package/morph-touch/Workflows/src/CreatePermanentChatRoomMapping.csx +5 -1
  19. package/morph-touch/Workflows/src/FetchRoomMessagesForSummaryMapping.csx +5 -1
  20. package/morph-touch/Workflows/src/GetUserInfoForRezervationMapping.csx +5 -1
  21. package/morph-touch/Workflows/src/GetVideoCallUrlMapping.csx +5 -1
  22. package/morph-touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +5 -1
  23. package/morph-touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +5 -1
  24. package/morph-touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +5 -1
  25. package/morph-touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +5 -1
  26. package/morph-touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +5 -1
  27. package/morph-touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +5 -1
  28. package/morph-touch/Workflows/src/JoinMatrixRoomMapping.csx +5 -1
  29. package/morph-touch/Workflows/src/JoinUserToRoomMapping.csx +5 -1
  30. package/morph-touch/Workflows/src/SendPushNotificationMapping.csx +5 -1
  31. package/morph-touch/Workflows/src/SendSmsNotificationMapping.csx +5 -1
  32. package/morph-touch/Workflows/src/SendSummaryToNewRoomMapping.csx +5 -1
  33. package/morph-touch/Workflows/src/SetRoomHistoryVisibilityMapping.csx +5 -1
  34. package/morph-touch/Workflows/src/SummarizeChatWithOpenAIMapping.csx +5 -1
  35. package/morph-touch/Workflows/start-video-call.json +1 -1
  36. package/morph-touch/doc/morph-touch-domain.en.md +328 -0
  37. package/morph-touch/doc/morph-touch-domain.md +328 -0
  38. package/package.json +1 -1
  39. package/vnext.config.json +2 -2
  40. package/burgan-tech-morph-touch-runtime-0.0.4.tgz +0 -0
@@ -0,0 +1,328 @@
1
+ # Morph-touch domain — technical overview
2
+
3
+ This document summarizes appointment (rezervation), absence, chat room, notification, and transfer flows in the `morph-touch` domain, based on workflow definitions and task mapping behaviour. API examples align with the [postman_collection.json](../../postman_collection.json) collection.
4
+
5
+ Turkish version: [morph-touch-domain.md](morph-touch-domain.md).
6
+
7
+ ---
8
+
9
+ ## 1. Overview and terminology
10
+
11
+ - **Domain:** `morph-touch`
12
+ - **Workflow instance:** vNext instance model with `key`, `flow` (`sys-flows`), `domain`, and `version`; started over HTTP at `.../workflows/{flowKey}/instances/...`, transitions at `.../transitions/{transitionKey}`.
13
+ - **Integrations:**
14
+ - **DAPR / application API:** `api/v{version}/{domain}/...` (paths such as `functions/state`, `functions/data` in mappings).
15
+ - **Matrix:** `MatrixBaseUrl` (secret); room creation, join, invite, kick, history visibility.
16
+ - **MessagingGateway:** SMS and push notifications ([notification-sender](../Workflows/notification-sender.json)).
17
+
18
+ ### High-level relationships
19
+
20
+ ```mermaid
21
+ flowchart LR
22
+ subgraph absence [absence-entry]
23
+ A1[complete]
24
+ A2[complete-with-transfer]
25
+ end
26
+ subgraph rez [rezervation]
27
+ R1[validating]
28
+ R2[appointment-form]
29
+ R3[active]
30
+ R4[in-meet]
31
+ end
32
+ subgraph transfer [rezervation-transfer]
33
+ T1[awaiting-assignment]
34
+ end
35
+ subgraph notify [notification-sender]
36
+ N1[pending to complete]
37
+ end
38
+ subgraph room [chat-room]
39
+ C1[permanent or reservation room]
40
+ end
41
+ R1 --> R2 --> R3
42
+ R3 --> N1
43
+ R3 --> absence
44
+ R3 --> R4
45
+ R4 --> room
46
+ A1 -->|start-transfer personal-leave| transfer
47
+ startChat[start-chat] --> room
48
+ resStart[rezervation-start] --> room
49
+ resStart --> R4
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 2. absence-entry
55
+
56
+ **File:** [Workflows/absence-entry.json](../Workflows/absence-entry.json)
57
+
58
+ ### Purpose
59
+
60
+ - **Absence** records such as personal leave, customer meeting, etc.
61
+ - **Public holiday** (`public-holiday`).
62
+ - **Company working hours** and **advisor-specific working hours** (`working-hours-change` — with or without advisor for company-wide scope).
63
+
64
+ Records are usually kept in `complete`; updated via `update`, moved to `cancelled` via `cancel`.
65
+
66
+ ### Link to appointment transfer
67
+
68
+ - Transition **`start-transfer`** is evaluated only when `absenceType == "personal-leave"` (`CanStartTransferMapping` — [Workflows/src/CanStartTransferMapping.csx](../Workflows/src/CanStartTransferMapping.csx)).
69
+ - When conditions hold, task `start-transfer-from-absence-entry` starts the **`rezervation-transfer`** subflow (`StartTransferFromAbsenceEntryMapping`).
70
+ - If **`endDateTime` is set**, transfer type is **annual leave** (`annual-leave`).
71
+ - If **`endDateTime` is empty**, type is **termination** (`termination`).
72
+ - Instance data must include **`advisor`**, **`advisorType`**, and **`startDateTime`**; otherwise the transfer task is skipped (`skipped` + reason).
73
+
74
+ Final state: `complete-with-transfer` (transfer started).
75
+
76
+ ---
77
+
78
+ ## 3. rezervation-transfer
79
+
80
+ **File:** [Workflows/rezervation-transfer.json](../Workflows/rezervation-transfer.json)
81
+
82
+ ### Purpose
83
+
84
+ Move the source advisor’s appointments in a date range to suitable target advisors; run required Matrix operations on permanent chat rooms (per transfer vs update plan).
85
+
86
+ ### Initial tasks (summary)
87
+
88
+ 1. **Transfer type:** Without `endDate`, `termination` and a default far end date; with `endDate`, `annual-leave`.
89
+ 2. **Source appointments:** `get-rezervations`-style query (`FetchRezervationsForTransferMapping`).
90
+ 3. **Advisor list:** Active instances, workflow key resolution from `advisorType` / source id (`FetchAdvisorsForTransferMapping`).
91
+ 4. **Absence records:** Completed `public-holiday`, `working-hours-change`, `personal-leave` (`FetchAbsenceEntriesForTransferMapping`).
92
+ 5. **Enrichment:** All active appointments + slot validity (holiday, working hours, personal leave, conflicts) — `EnrichRezervationsForTransferMapping`.
93
+
94
+ ### Key checks
95
+
96
+ - **`confirm-transfer`:** `validate-transfer-availability` — ensures the target advisor has no conflicting **active / in-meet** reservation in that slot; produces `validationResult.allValid` / `details`.
97
+ - **`transferPlan`:** Postman example: each row has `rezervationKey` + `targetAdvisor` ([postman_collection.json](../../postman_collection.json) — “Confirm Transfer”).
98
+ - Steps for permanent rooms using **`permanentRoomPlan`** (room `roomId` + `newAdvisorId`) are described in the collection notes.
99
+
100
+ ---
101
+
102
+ ## 4. rezervation
103
+
104
+ **File:** [Workflows/rezervation.json](../Workflows/rezervation.json)
105
+
106
+ ### State outline
107
+
108
+ `validating` → `appointment-form` or `slot-unavailable` → `active` → `in-meet` → `meet-completed`
109
+ Cancellations: `user-cancelled`, `advisor-cancelled`, `timeout`, etc.
110
+
111
+ ### Controls
112
+
113
+ | Topic | Source | Description |
114
+ |------|--------|-------------|
115
+ | At most 2 reservations | `check-duplicate-rezervation` | For the same user, in certain confirmed states, at most **2** active reservations; **no overlapping** slots. |
116
+ | Slot validity | `validate-slot-for-rezervation` | If the chosen range is missing from `get-available-slots` output → `slot-unavailable`; **`appointment-form-retry`** resubmits new date/time for re-validation. |
117
+ | Date | `validate-date-for-rezervation` | Past or invalid dates are rejected. |
118
+ | User | `set-user-from-headers-for-rezervation` | Request **`sub`** header is written to the instance. |
119
+ | Confirm → active | `create-appointment` / confirmation chain | Order in workflow: previous advisor info, user info (`get-user-info-for-rezervation`), start **`notification-sender`**, create **`absence-entry`** (reservation record). |
120
+
121
+ ### Notification (when appointment is created)
122
+
123
+ The `notification-sender` subflow starts during reservation confirmation. **Advisor** SMS/push body (summary):
124
+
125
+ `Sayın " + (advisorName ?? "Danisman") + ", " + formattedDate + " tarihli randevunuz olusturulmustur."`
126
+
127
+ **Customer** uses different copy (`SendSmsNotificationMapping` / `SendPushNotificationMapping` — [Workflows/src/SendSmsNotificationMapping.csx](../Workflows/src/SendSmsNotificationMapping.csx), [Workflows/src/SendPushNotificationMapping.csx](../Workflows/src/SendPushNotificationMapping.csx)). For channel selection and state transitions, see the **notification-sender** section (section 5 in this document).
128
+
129
+ ### Shared transitions
130
+
131
+ - **`user-cancel` / `advisor-cancel` (active):** Triggers `cancel` on the related **`absence-entry`**; advisor cancel also sends a **cancellation notification**.
132
+ - **`add-invited-participant`**, **`video-call-url-update`:** Merge invited-user list and video URL list.
133
+
134
+ ---
135
+
136
+ ## 5. notification-sender
137
+
138
+ **File:** [Workflows/notification-sender.json](../Workflows/notification-sender.json)
139
+
140
+ Subflow: started synchronously from reservation confirmation and other triggers. SMS (`/Messaging/sms/message/string`) and push (`/Messaging/push-notification/message`) calls are built in mappings against the `MessagingBaseUrl` secret.
141
+
142
+ ### States and automatic transitions
143
+
144
+ | Source | Transition | Target | Condition (summary) |
145
+ |--------|------------|--------|----------------------|
146
+ | `pending` | `to-sms-sending` | `sms-sending` | `channels.sms == true` |
147
+ | `pending` | `to-push-sending-from-pending` | `push-sending` | SMS not requested, `channels.push == true`, `hasRegisteredDevice == true` |
148
+ | `pending` | `to-complete-from-pending` | `complete` | No applicable channel (push requested but no device, or no channel) |
149
+ | `sms-sending` | (onEntry) | — | `send-sms-notification` task; `recipient.phone` (countryCode, prefix, number) required |
150
+ | `sms-sending` | `to-push-sending-from-sms` | `push-sending` | `channels.push == true` and `hasRegisteredDevice == true` |
151
+ | `sms-sending` | `to-complete-from-sms` | `complete` | Push not requested or no registered device |
152
+ | `push-sending` | (onEntry) | — | `send-push-notification`; `recipient` uses `citizenshipNo` / `customerNo` |
153
+ | `push-sending` | `to-complete-from-push` | `complete` | Always after push |
154
+
155
+ **Copy:** `userType == "advisor"` uses advisor SMS/push text; `user` uses customer text (mapping summaries in the CSX files above).
156
+
157
+ Postman: folder **Notification Sender Subprocess** — SMS only, push only, no channel, no device scenarios.
158
+
159
+ ---
160
+
161
+ ## 6. rezervation-start
162
+
163
+ **File:** [Workflows/rezervation-start.json](../Workflows/rezervation-start.json)
164
+
165
+ Both customer and advisor can start the meeting; the **first starter** takes the path that creates the reservation room; the other **joins**.
166
+
167
+ ### Requirements / checks
168
+
169
+ - **`randevuKey`** required; state and data read via DAPR (`GetRezervationStateMapping`, `GetRezervationDataMapping`).
170
+ - **Invited:** If `participantType == "invited"` and `invitedUserId` is not in the reservation `invitedUser` list → **`not-allowed`**.
171
+ - If reservation state is not **`active`** or **`in-meet`** → **`meet-not-active`**.
172
+ - **Time window (`check-randevu-time`):** Start allowed at most **15 minutes** before appointment start (script compares with `UtcNow + 3`); otherwise an error like `MEET_NOT_STARTED`.
173
+ - **Invited and not yet in-meet:** `meet-not-started` branch.
174
+
175
+ ### Room and in-meet
176
+
177
+ - If state is **`active`:** **`create-room-and-trigger`** — starts **`chat-room`** synchronously (`roomType: rezervation`), loads room data, fires **`to-in-meet`** on the main **`rezervation`**.
178
+ - If state is already **`in-meet`:** **`join-room`** — Matrix `join`, `x-matrix-user` by participant type (user / advisor / invited).
179
+
180
+ ### End
181
+
182
+ In `end` state, **`start-video-call`** subflow runs (LiveKit, etc.).
183
+
184
+ ---
185
+
186
+ ## 7. chat-room
187
+
188
+ **File:** [Workflows/chat-room.json](../Workflows/chat-room.json)
189
+
190
+ ### Purpose
191
+
192
+ - **Permanent room** (`roomType: permanent`): Matrix room keyed by user + advisor type + advisor.
193
+ - **Reservation room** (`roomType: rezervation`): Process room tied to reservation key.
194
+
195
+ ### Behaviour summary
196
+
197
+ - Creation: Matrix `createRoom`, invite, `join-user-to-room`.
198
+ - **`activated`:** add member (`update`), remove member (`remove`), advisor **`transfer`** (kick + invite + join).
199
+ - **`deactivate` / `activate`** states.
200
+ - Second room creation blocked for same **user + advisorType + activated** on permanent rooms (`ALREADY_COMPLETED`).
201
+
202
+ ### Domain functions (via workflow)
203
+
204
+ `get-chat-rooms`, `get-room-messages`, `send-room-message`, `get-matrix-sync` ([chat-room.json](../Workflows/chat-room.json) `attributes.functions`).
205
+
206
+ ---
207
+
208
+ ## 8. start-chat
209
+
210
+ **File:** [Workflows/start-chat.json](../Workflows/start-chat.json)
211
+
212
+ ### Purpose
213
+
214
+ Open permanent advisor chat: create room if missing, otherwise go straight to chat.
215
+
216
+ ### Flow
217
+
218
+ 1. **`check-existing-permanent-chat-room`:** Whether the user already has a permanent room for the same `advisorType`; `advisorId` match kept in a separate flag.
219
+ 2. **Existing room + same advisor** → **`in-chat`** (`open-existing-room`).
220
+ 3. **Existing room + different advisor** → **`to-change-advisor`:** fire **`transfer`** on `chat-room`, then **`in-chat`**.
221
+ 4. **No room** → **`start-permanent-chat-room`** starts **`chat-room`** synchronously, then **`in-chat`**.
222
+
223
+ ---
224
+
225
+ ## 9. add-participant-to-rezervation
226
+
227
+ **File:** [Workflows/add-participant-to-rezervation.json](../Workflows/add-participant-to-rezervation.json)
228
+
229
+ ### Prerequisite
230
+
231
+ Reservation state **`active`** or **`in-meet`**; otherwise **`state-not-valid`**.
232
+
233
+ ### Branches
234
+
235
+ - **`in-meet`:** **update** on `chat-room` (new member) + **`add-invited-participant`** on `rezervation` + **`start-video-call`** subflow (invited customer path).
236
+ - **`active`:** **`update-invited`** → **`end`** (invited update only).
237
+
238
+ `newUserId` / `randevuKey` are required in task mappings.
239
+
240
+ ---
241
+
242
+ ## 10. Domain functions (summary)
243
+
244
+ | Function | File | Purpose / notes |
245
+ |----------|------|------------------|
246
+ | `check-livekit-room-access` | [Functions/check-livekit-room-access.1.0.0.json](../Functions/check-livekit-room-access.1.0.0.json) | Query `access_token` (JWT or `prefix:roomName:participantName`). Participant validation on a single matching **active/in-meet** reservation; error on multiple matches. |
247
+ | `get-absence-entry` | [Functions/get-absence-entry.1.0.0.json](../Functions/get-absence-entry.1.0.0.json) | Required `absenceType`: `public-holiday`, `personal-leave`, `working-hours-change`, `rezervation`. Optional `advisor`, `startDate`, `endDate`, `pageSize`. |
248
+ | `get-advisor-stats` | [Functions/get-advisor-stats.1.0.0.json](../Functions/get-advisor-stats.1.0.0.json) | Advisor presence (Matrix: online, offline, busy, away). |
249
+ | `get-available-slots` | [Functions/get-available-slots.1.0.0.json](../Functions/get-available-slots.1.0.0.json) | `advisorId`, `date`, optional `duration` (minutes). |
250
+ | `get-chat-rooms` | [Functions/get-chat-rooms.1.0.0.json](../Functions/get-chat-rooms.1.0.0.json) | **`user` OR `advisor`** (mutually exclusive). |
251
+ | `get-customer-info` | [Functions/get-customer-info.1.0.0.json](../Functions/get-customer-info.1.0.0.json) | Customer profile. |
252
+ | `get-matrix-sync` | [Functions/get-matrix-sync.1.0.0.json](../Functions/get-matrix-sync.1.0.0.json) | Matrix sync payload. |
253
+ | `get-rezervations` | [Functions/get-rezervations.1.0.0.json](../Functions/get-rezervations.1.0.0.json) | Filtered reservation list. |
254
+ | `get-room-messages` | [Functions/get-room-messages.1.0.0.json](../Functions/get-room-messages.1.0.0.json) | Room messages. |
255
+ | `send-room-message` | [Functions/send-room-message.1.0.0.json](../Functions/send-room-message.1.0.0.json) | Send message to Matrix. |
256
+
257
+ See [Functions/get-room-messages.http](../Functions/get-room-messages.http) for detailed HTTP examples.
258
+
259
+ ---
260
+
261
+ ## 11. Postman collection
262
+
263
+ **File:** [postman_collection.json](../../postman_collection.json) (workspace root)
264
+ **Collection name:** vNext Touch Domain
265
+
266
+ ### Shared variables (defaults)
267
+
268
+ | Variable | Example value |
269
+ |----------|----------------|
270
+ | `baseUrl` | `http://localhost:4201` |
271
+ | `apiVersion` | `1` |
272
+ | `domain` | `morph-touch` |
273
+ | `instanceKey` / `user` | `core.user.user-001` |
274
+ | `advisor` / `advisorId` | `morph-touch.portfolio-manager.pm-001` |
275
+
276
+ ### Workflow API templates
277
+
278
+ - **Start instance:**
279
+ `POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{flowKey}/instances/start?sync=true`
280
+ Examples: `rezervation`, `absence-entry`, `rezervation-start`, `chat-room`, `start-chat`, `rezervation-transfer`, `notification-sender` (subflow).
281
+ - **Get instance:**
282
+ `GET .../workflows/{flowKey}/instances/{{instanceId}}`
283
+ - **Transition:**
284
+ `PATCH .../workflows/{flowKey}/instances/{{instanceId}}/transitions/{transitionKey}?sync=true`
285
+ Body is usually `{ "attributes": { ... } }`.
286
+
287
+ ### Sample requests (collection folders)
288
+
289
+ | Folder / request | Method | Notes |
290
+ |------------------|--------|-------|
291
+ | **Reservation Workflow → Start Rezervation** | POST | `sub` header; body: `user`, `advisor`, `startDateTime`, `endDateTime`. |
292
+ | **Confirm Selection** | PATCH | `transitions/confirm-selection` — slot validation step. |
293
+ | **Appointment Form Retry** | PATCH | `appointment-form-retry` + new `startDateTime` / `endDateTime`. |
294
+ | **Create Appointment** | PATCH | `create-appointment` → `active`. |
295
+ | **Rezervation Start Workflow** | POST | `randevuKey`, `participantType` (advisor / customer / invited). |
296
+ | **Chat Room Workflow** | POST / PATCH | Permanent PM/IA start; `update`, `remove`, `transfer`. |
297
+ | **Start Chat Workflow** | POST | Creates permanent room if missing, else `in-chat`. |
298
+ | **Rezervation Transfer** | POST + PATCH | `startDate`/`endDate`; `confirm-transfer` with `transferPlan`. |
299
+ | **Get Absence Entry Function** | GET | `.../functions/get-absence-entry?absenceType=...` |
300
+ | **Get Available Slots** | GET | `advisorId`, `date`, `duration`. |
301
+ | **Get Chat Rooms** | GET | `user=...` or `advisor=...` |
302
+ | **Matrix Synapse API** | various | `http://localhost:9080/...` — presence, createRoom (manual test). |
303
+ | **Notification Sender Subprocess** | POST | `workflows/notification-sender/instances/start` — channel flags and recipient shape examples. |
304
+
305
+ Collection descriptions reference [vNext documentation](https://github.com/burgan-tech/vnext-runtime/tree/main/doc/en) for instance filtering and task types.
306
+
307
+ ---
308
+
309
+ ## 12. Extra checks and edge cases
310
+
311
+ - **Reservation cancel:** Triggers `absence-entry` cancel; on older instances without `absenceEntryKey`, cancel may no-op.
312
+ - **Multiple invitees / video URLs:** List merge via `merge-invited-user`, `merge-video-call-urls`.
313
+ - **check-livekit-room-access:** Token format JWT or `room:participant`; multiple matches yield an unusable result.
314
+ - **notification-sender:** SMS requires phone structure; push uses `citizenshipNo` / `customerNo` and registered-device flag.
315
+ - **chat-room:** Matrix `M_ROOM_IN_USE`; history visibility limited to allowed values (`shared`, `invited`, `joined`, `world_readable`) in mappings.
316
+
317
+ ---
318
+
319
+ ## 13. Related source files
320
+
321
+ - Workflow JSON: [Workflows/](../Workflows/)
322
+ - C# mappings: [Workflows/src/](../Workflows/src/)
323
+ - Function definitions: [Functions/](../Functions/)
324
+ - Project rules: [.cursorrules](../../.cursorrules)
325
+
326
+ ---
327
+
328
+ *This document is derived from code and workflow definitions; runtime URLs and auth may vary by environment.*
@@ -0,0 +1,328 @@
1
+ # Morph-touch domain — teknik özet
2
+
3
+ Bu doküman, `morph-touch` domain’indeki randevu (rezervation), yokluk/absence, sohbet odası, bildirim ve transfer akışlarını; workflow tanımları ve görev mapping’lerindeki davranışa dayanarak özetler. API örnekleri [postman_collection.json](../../postman_collection.json) koleksiyonu ile uyumludur.
4
+
5
+ İngilizce sürüm: [morph-touch-domain.en.md](morph-touch-domain.en.md).
6
+
7
+ ---
8
+
9
+ ## 1. Genel bakış ve terminoloji
10
+
11
+ - **Domain:** `morph-touch`
12
+ - **Workflow instance:** `key`, `flow` (`sys-flows`), `domain`, `version` ile tanımlı vNext instance modeli; HTTP üzerinden `.../workflows/{flowKey}/instances/...` ile başlatılır ve geçişler `.../transitions/{transitionKey}` ile tetiklenir.
13
+ - **Entegrasyonlar:**
14
+ - **DAPR / uygulama API:** `api/v{version}/{domain}/...` (mapping’lerde geçen `functions/state`, `functions/data` yolları).
15
+ - **Matrix:** `MatrixBaseUrl` (secret); oda oluşturma, join, invite, kick, history visibility.
16
+ - **MessagingGateway:** SMS ve push bildirimleri ([notification-sender](../Workflows/notification-sender.json)).
17
+
18
+ ### Yüksek seviye ilişki
19
+
20
+ ```mermaid
21
+ flowchart LR
22
+ subgraph absence [absence-entry]
23
+ A1[complete]
24
+ A2[complete-with-transfer]
25
+ end
26
+ subgraph rez [rezervation]
27
+ R1[validating]
28
+ R2[appointment-form]
29
+ R3[active]
30
+ R4[in-meet]
31
+ end
32
+ subgraph transfer [rezervation-transfer]
33
+ T1[awaiting-assignment]
34
+ end
35
+ subgraph notify [notification-sender]
36
+ N1[pending to complete]
37
+ end
38
+ subgraph room [chat-room]
39
+ C1[permanent or reservation room]
40
+ end
41
+ R1 --> R2 --> R3
42
+ R3 --> N1
43
+ R3 --> absence
44
+ R3 --> R4
45
+ R4 --> room
46
+ A1 -->|start-transfer personal-leave| transfer
47
+ startChat[start-chat] --> room
48
+ resStart[rezervation-start] --> room
49
+ resStart --> R4
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 2. absence-entry
55
+
56
+ **Dosya:** [Workflows/absence-entry.json](../Workflows/absence-entry.json)
57
+
58
+ ### Amaç
59
+
60
+ - Kişisel izin, müşteri toplantısı vb. **yokluk** kayıtları.
61
+ - **Resmi tatil** (`public-holiday`).
62
+ - **Şirket çalışma saatleri** ve **danışmana özel çalışma saati** (`working-hours-change` — advisor’lı veya şirket geneli).
63
+
64
+ Kayıtlar çoğunlukla `complete` durumunda tutulur; `update` ile güncellenir, `cancel` ile `cancelled` olur.
65
+
66
+ ### Randevu transferi ile bağlantı
67
+
68
+ - Geçiş **`start-transfer`** yalnızca `absenceType == "personal-leave"` iken değerlendirilir (`CanStartTransferMapping` — [Workflows/src/CanStartTransferMapping.csx](../Workflows/src/CanStartTransferMapping.csx)).
69
+ - Koşullar sağlanırsa `start-transfer-from-absence-entry` görevi **`rezervation-transfer`** alt akışını başlatır (`StartTransferFromAbsenceEntryMapping`).
70
+ - `endDateTime` **dolu** ise transfer tipi **yıllık izin** (`annual-leave`).
71
+ - `endDateTime` **boş** ise **işten çıkış / termination** (`termination`).
72
+ - Instance verisinde **`advisor`**, **`advisorType`**, **`startDateTime`** zorunludur; aksi halde transfer görevi atlanır (`skipped` + reason).
73
+
74
+ Son durum: `complete-with-transfer` (transfer başlatıldı).
75
+
76
+ ---
77
+
78
+ ## 3. rezervation-transfer
79
+
80
+ **Dosya:** [Workflows/rezervation-transfer.json](../Workflows/rezervation-transfer.json)
81
+
82
+ ### Amaç
83
+
84
+ Kaynak danışmanın belirli tarih aralığındaki randevularını, uygun hedef danışmanlara aktarmak; kalıcı sohbet odalarında gerekli Matrix işlemlerini (transfer / update planına göre) yürütmek.
85
+
86
+ ### Başlangıç görevleri (özet)
87
+
88
+ 1. **Transfer tipi:** `endDate` yoksa `termination` ve varsayılan uzun uç tarih; varsa `annual-leave`.
89
+ 2. **Kaynak rezervasyonlar:** `get-rezervations` benzeri sorgu (`FetchRezervationsForTransferMapping`).
90
+ 3. **Danışman listesi:** Aktif instance’lar, `advisorType` / kaynak id ile workflow anahtarı çözümü (`FetchAdvisorsForTransferMapping`).
91
+ 4. **Absence kayıtları:** Tamamlanmış `public-holiday`, `working-hours-change`, `personal-leave` (`FetchAbsenceEntriesForTransferMapping`).
92
+ 5. **Zenginleştirme:** Tüm aktif randevular + slot uygunluğu (tatil, çalışma saati, kişisel izin, çakışma) — `EnrichRezervationsForTransferMapping`.
93
+
94
+ ### Önemli kontroller
95
+
96
+ - **`confirm-transfer`:** `validate-transfer-availability` — hedef danışmanın ilgili rezervasyon zamanında başka **active / in-meet** çakışması var mı diye kontrol edilir; `validationResult.allValid` / `details` üretilir.
97
+ - **`transferPlan`:** Postman’da örnek: her satırda `rezervationKey` + `targetAdvisor` ([postman_collection.json](../../postman_collection.json) — “Confirm Transfer”).
98
+ - Kalıcı odalar için **`permanentRoomPlan`** (oda `roomId` + `newAdvisorId`) ile devam eden adımlar koleksiyon açıklamasında anlatılır.
99
+
100
+ ---
101
+
102
+ ## 4. rezervation
103
+
104
+ **Dosya:** [Workflows/rezervation.json](../Workflows/rezervation.json)
105
+
106
+ ### Durum özeti (ana hat)
107
+
108
+ `validating` → `appointment-form` veya `slot-unavailable` → `active` → `in-meet` → `meet-completed`
109
+ İptaller: `user-cancelled`, `advisor-cancelled`, `timeout` vb.
110
+
111
+ ### Kontroller
112
+
113
+ | Konu | Kaynak | Açıklama |
114
+ |------|--------|----------|
115
+ | En fazla 2 rezervasyon | `check-duplicate-rezervation` | Aynı kullanıcı için belirli onaylı durumlarda en fazla **2** aktif rezervasyon; **zaman çakışması** yok. |
116
+ | Slot uygunluğu | `validate-slot-for-rezervation` | `get-available-slots` çıktısında seçilen aralık yoksa `slot-unavailable`; **`appointment-form-retry`** ile yeni tarih/saat gönderilip tekrar doğrulanır. |
117
+ | Tarih | `validate-date-for-rezervation` | Geçmiş veya geçersiz tarih reddedilir. |
118
+ | Kullanıcı | `set-user-from-headers-for-rezervation` | İstek **`sub`** header’ından kullanıcıyı instance’a yazar. |
119
+ | Onay → active | `create-appointment` / onay zinciri | Önceki danışman bilgisi, kullanıcı bilgisi (`get-user-info-for-rezervation`), **`notification-sender`** başlatma, **`absence-entry`** (rezervasyon kaydı) oluşturma sırası workflow’ta tanımlıdır. |
120
+
121
+ ### Bildirim (randevu oluşunca)
122
+
123
+ `notification-sender` alt akışı, rezervasyon onayı sırasında başlatılır. **Danışman** için SMS/push içeriği (özet):
124
+
125
+ `Sayın " + (advisorName ?? "Danisman") + ", " + formattedDate + " tarihli randevunuz olusturulmustur."`
126
+
127
+ **Müşteri** için farklı metin kullanılır (`SendSmsNotificationMapping` / `SendPushNotificationMapping` — [Workflows/src/SendSmsNotificationMapping.csx](../Workflows/src/SendSmsNotificationMapping.csx), [Workflows/src/SendPushNotificationMapping.csx](../Workflows/src/SendPushNotificationMapping.csx)). Kanal seçimi ve durum geçişleri için **notification-sender** bölümüne (bu dokümanda 5) bakın.
128
+
129
+ ### Paylaşımlı geçişler
130
+
131
+ - **`user-cancel` / `advisor-cancel` (active):** İlgili **`absence-entry`** üzerinde `cancel` tetiklenir; danışman iptalinde ek olarak **iptal bildirimi** gönderilir.
132
+ - **`add-invited-participant`**, **`video-call-url-update`:** Davetli listesi ve video URL listesi birleştirme.
133
+
134
+ ---
135
+
136
+ ## 5. notification-sender
137
+
138
+ **Dosya:** [Workflows/notification-sender.json](../Workflows/notification-sender.json)
139
+
140
+ Alt süreç (subflow): randevu onayı ve diğer tetikleyicilerden senkron başlatılır. **MessagingGateway** üzerinden SMS (`/Messaging/sms/message/string`) ve push (`/Messaging/push-notification/message`) çağrıları mapping’lerde `MessagingBaseUrl` secret’ına göre kurulur.
141
+
142
+ ### Durumlar ve otomatik geçişler
143
+
144
+ | Kaynak | Geçiş | Hedef | Koşul (özet) |
145
+ |--------|--------|-------|----------------|
146
+ | `pending` | `to-sms-sending` | `sms-sending` | `channels.sms == true` |
147
+ | `pending` | `to-push-sending-from-pending` | `push-sending` | SMS istenmiyor, `channels.push == true`, `hasRegisteredDevice == true` |
148
+ | `pending` | `to-complete-from-pending` | `complete` | Uygulanabilir kanal yok (push istenmiş ama cihaz yok, veya hiç kanal yok) |
149
+ | `sms-sending` | (onEntry) | — | `send-sms-notification` görevi; `recipient.phone` (countryCode, prefix, number) zorunlu |
150
+ | `sms-sending` | `to-push-sending-from-sms` | `push-sending` | `channels.push == true` ve `hasRegisteredDevice == true` |
151
+ | `sms-sending` | `to-complete-from-sms` | `complete` | Push istenmiyor veya kayıtlı cihaz yok |
152
+ | `push-sending` | (onEntry) | — | `send-push-notification`; `recipient` içinde `citizenshipNo` / `customerNo` kullanımı |
153
+ | `push-sending` | `to-complete-from-push` | `complete` | Push sonrası her zaman |
154
+
155
+ **İçerik:** `userType == "advisor"` için danışman SMS/push metni; `user` için müşteri metni (mapping özetleri yukarıdaki CSX dosyalarında).
156
+
157
+ Postman: klasör **Notification Sender Subprocess** — SMS only, push only, kanal yok, cihaz yok senaryoları.
158
+
159
+ ---
160
+
161
+ ## 6. rezervation-start
162
+
163
+ **Dosya:** [Workflows/rezervation-start.json](../Workflows/rezervation-start.json)
164
+
165
+ Hem müşteri hem danışman görüşmeyi başlatabilir; **ilk başlatan** rezervasyon odasını oluşturma yoluna girer, diğer taraf **join** eder.
166
+
167
+ ### Zorunlu / kontroller
168
+
169
+ - **`randevuKey`** zorunlu; state ve data DAPR üzerinden okunur (`GetRezervationStateMapping`, `GetRezervationDataMapping`).
170
+ - **Davetli:** `participantType == "invited"` ve `invitedUserId`, rezervasyondaki `invitedUser` listesinde değilse → **`not-allowed`**.
171
+ - Rezervasyon state **`active`** veya **`in-meet`** değilse → **`meet-not-active`**.
172
+ - **Zaman penceresi (`check-randevu-time`):** Randevu başlangıcına en fazla **15 dakika** kala başlatılabilir (script’te saat dilimi `UtcNow + 3` ile karşılaştırma); aksi halde `MEET_NOT_STARTED` benzeri hata.
173
+ - **Davetli ve henüz in-meet değilse:** `meet-not-started` dalı.
174
+
175
+ ### Oda ve in-meet
176
+
177
+ - State **`active`** ise: **`create-room-and-trigger`** — senkron **`chat-room`** başlatılır (`roomType: rezervation`), oda verisi alınır, ana **`rezervation`** üzerinde **`to-in-meet`** tetiklenir.
178
+ - State zaten **`in-meet`** ise: **`join-room`** — Matrix `join`, `x-matrix-user` katılımcı tipine göre (user / advisor / invited).
179
+
180
+ ### Bitiş
181
+
182
+ `end` state’inde **`start-video-call`** alt akışı (LiveKit vb.) çalışır.
183
+
184
+ ---
185
+
186
+ ## 7. chat-room
187
+
188
+ **Dosya:** [Workflows/chat-room.json](../Workflows/chat-room.json)
189
+
190
+ ### Amaç
191
+
192
+ - **Kalıcı oda** (`roomType: permanent`): kullanıcı + danışman tipi + danışman ile tekilleştirilmiş Matrix odası.
193
+ - **Randevu odası** (`roomType: rezervation`): rezervasyon anahtarı ile ilişkili geçici süreç odası.
194
+
195
+ ### Davranış özeti
196
+
197
+ - Oluşturma: Matrix `createRoom`, davet, `join-user-to-room`.
198
+ - **`activated`:** üye ekleme (`update`), üye çıkarma (`remove`), danışman **`transfer`** (kick + invite + join).
199
+ - **`deactivate` / `activate`** durumları.
200
+ - Kalıcı oda için aynı **user + advisorType + activated** ile ikinci oda oluşturma engeli (`ALREADY_COMPLETED`).
201
+
202
+ ### Domain fonksiyonları (workflow üzerinden)
203
+
204
+ `get-chat-rooms`, `get-room-messages`, `send-room-message`, `get-matrix-sync` ([chat-room.json](../Workflows/chat-room.json) `attributes.functions`).
205
+
206
+ ---
207
+
208
+ ## 8. start-chat
209
+
210
+ **Dosya:** [Workflows/start-chat.json](../Workflows/start-chat.json)
211
+
212
+ ### Amaç
213
+
214
+ Kalıcı danışman sohbetini açmak: oda yoksa oluştur, varsa doğrudan sohbete geç.
215
+
216
+ ### Akış
217
+
218
+ 1. **`check-existing-permanent-chat-room`:** Kullanıcının aynı `advisorType` için kalıcı odası var mı; `advisorId` eşleşmesi ayrı bayrakta tutulur.
219
+ 2. **Mevcut oda + aynı danışman** → **`in-chat`** (`open-existing-room`).
220
+ 3. **Mevcut oda + farklı danışman** → **`to-change-advisor`:** `chat-room` üzerinde **`transfer`** tetiklenir, sonra **`in-chat`**.
221
+ 4. **Oda yok** → **`start-permanent-chat-room`** ile **`chat-room`** senkron başlatılır, sonra **`in-chat`**.
222
+
223
+ ---
224
+
225
+ ## 9. add-participant-to-rezervation
226
+
227
+ **Dosya:** [Workflows/add-participant-to-rezervation.json](../Workflows/add-participant-to-rezervation.json)
228
+
229
+ ### Önkoşul
230
+
231
+ Rezervasyon state **`active`** veya **`in-meet`**; aksi halde **`state-not-valid`**.
232
+
233
+ ### Dallar
234
+
235
+ - **`in-meet`:** `chat-room` üzerinde **update** (yeni üye) + `rezervation` üzerinde **`add-invited-participant`** tetikleri + **`start-video-call`** alt akışı (davetli müşteri gibi).
236
+ - **`active`:** **`update-invited`** → **`end`** (davetli güncelleme).
237
+
238
+ `newUserId` / `randevuKey` görev mapping’lerinde zorunludur.
239
+
240
+ ---
241
+
242
+ ## 10. Domain fonksiyonları (özet)
243
+
244
+ | Fonksiyon | Dosya | Amaç / not |
245
+ |-----------|--------|------------|
246
+ | `check-livekit-room-access` | [Functions/check-livekit-room-access.1.0.0.json](../Functions/check-livekit-room-access.1.0.0.json) | Query `access_token` (JWT veya `prefix:roomName:participantName`). Tek eşleşen **active/in-meet** rezervasyonda katılımcı doğrulaması; çoklu eşleşmede hata. |
247
+ | `get-absence-entry` | [Functions/get-absence-entry.1.0.0.json](../Functions/get-absence-entry.1.0.0.json) | Zorunlu `absenceType`: `public-holiday`, `personal-leave`, `working-hours-change`, `rezervation`. Opsiyonel `advisor`, `startDate`, `endDate`, `pageSize`. |
248
+ | `get-advisor-stats` | [Functions/get-advisor-stats.1.0.0.json](../Functions/get-advisor-stats.1.0.0.json) | Danışman presence (Matrix: online, offline, busy, away). |
249
+ | `get-available-slots` | [Functions/get-available-slots.1.0.0.json](../Functions/get-available-slots.1.0.0.json) | `advisorId`, `date`, isteğe bağlı `duration` (dakika). |
250
+ | `get-chat-rooms` | [Functions/get-chat-rooms.1.0.0.json](../Functions/get-chat-rooms.1.0.0.json) | **`user` VEYA `advisor`** (birbirini dışlar). |
251
+ | `get-customer-info` | [Functions/get-customer-info.1.0.0.json](../Functions/get-customer-info.1.0.0.json) | Müşteri bilgisi. |
252
+ | `get-matrix-sync` | [Functions/get-matrix-sync.1.0.0.json](../Functions/get-matrix-sync.1.0.0.json) | Matrix sync yanıtı. |
253
+ | `get-rezervations` | [Functions/get-rezervations.1.0.0.json](../Functions/get-rezervations.1.0.0.json) | Filtreli rezervasyon listesi. |
254
+ | `get-room-messages` | [Functions/get-room-messages.1.0.0.json](../Functions/get-room-messages.1.0.0.json) | Oda mesajları. |
255
+ | `send-room-message` | [Functions/send-room-message.1.0.0.json](../Functions/send-room-message.1.0.0.json) | Matrix’e mesaj gönderimi. |
256
+
257
+ Detaylı HTTP örnekleri için [Functions/get-room-messages.http](../Functions/get-room-messages.http) dosyasına bakılabilir.
258
+
259
+ ---
260
+
261
+ ## 11. Postman koleksiyonu
262
+
263
+ **Dosya:** [postman_collection.json](../../postman_collection.json) (workspace kökü)
264
+ **Koleksiyon adı:** vNext Touch Domain
265
+
266
+ ### Ortak değişkenler (varsayılanlar)
267
+
268
+ | Değişken | Örnek değer |
269
+ |----------|-------------|
270
+ | `baseUrl` | `http://localhost:4201` |
271
+ | `apiVersion` | `1` |
272
+ | `domain` | `morph-touch` |
273
+ | `instanceKey` / `user` | `core.user.user-001` |
274
+ | `advisor` / `advisorId` | `morph-touch.portfolio-manager.pm-001` |
275
+
276
+ ### Workflow API şablonları
277
+
278
+ - **Instance başlat:**
279
+ `POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{flowKey}/instances/start?sync=true`
280
+ Örnek: `rezervation`, `absence-entry`, `rezervation-start`, `chat-room`, `start-chat`, `rezervation-transfer`, `notification-sender` (alt süreç).
281
+ - **Instance oku:**
282
+ `GET .../workflows/{flowKey}/instances/{{instanceId}}`
283
+ - **Geçiş:**
284
+ `PATCH .../workflows/{flowKey}/instances/{{instanceId}}/transitions/{transitionKey}?sync=true`
285
+ Gövde genelde `{ "attributes": { ... } }`.
286
+
287
+ ### Örnek istekler (koleksiyon klasörleri)
288
+
289
+ | Klasör / istek | Metod | Not |
290
+ |----------------|-------|-----|
291
+ | **Reservation Workflow → Start Rezervation** | POST | `sub` header; body’de `user`, `advisor`, `startDateTime`, `endDateTime`. |
292
+ | **Confirm Selection** | PATCH | `transitions/confirm-selection` — slot doğrulama adımı. |
293
+ | **Appointment Form Retry** | PATCH | `appointment-form-retry` + yeni `startDateTime` / `endDateTime`. |
294
+ | **Create Appointment** | PATCH | `create-appointment` → `active`. |
295
+ | **Rezervation Start Workflow** | POST | `randevuKey`, `participantType` (advisor / customer / invited). |
296
+ | **Chat Room Workflow** | POST / PATCH | Kalıcı PM/IA başlatma; `update`, `remove`, `transfer`. |
297
+ | **Start Chat Workflow** | POST | Kalıcı oda yoksa oluşturur, varsa `in-chat`. |
298
+ | **Rezervation Transfer** | POST + PATCH | `startDate`/`endDate`; `confirm-transfer` ile `transferPlan`. |
299
+ | **Get Absence Entry Function** | GET | `.../functions/get-absence-entry?absenceType=...` |
300
+ | **Get Available Slots** | GET | `advisorId`, `date`, `duration`. |
301
+ | **Get Chat Rooms** | GET | `user=...` veya `advisor=...` |
302
+ | **Matrix Synapse API** | çeşitli | `http://localhost:9080/...` — presence, createRoom (manuel test). |
303
+ | **Notification Sender Subprocess** | POST | `workflows/notification-sender/instances/start` — kanal bayrakları ve recipient yapısı örnekleri. |
304
+
305
+ Koleksiyon içi açıklamalar: instance filtreleme ve görev tipleri için [vNext dokümantasyonu](https://github.com/burgan-tech/vnext-runtime/tree/main/doc/en) referans verilir.
306
+
307
+ ---
308
+
309
+ ## 12. Ek kontroller ve kenar durumları
310
+
311
+ - **Rezervasyon iptali:** `absence-entry` iptali tetiklenir; eski instance’larda `absenceEntryKey` yoksa cancel no-op olabilir.
312
+ - **Çoklu davetli / video URL:** `merge-invited-user`, `merge-video-call-urls` ile liste birleştirme.
313
+ - **check-livekit-room-access:** Token formatı JWT veya `room:participant`; birden fazla eşleşmede anlamlı olmayan sonuç döner.
314
+ - **notification-sender:** SMS için telefon yapısı zorunlu; push için `citizenshipNo` / `customerNo` ve kayıtlı cihaz bayrağı.
315
+ - **chat-room:** Matrix `M_ROOM_IN_USE`; history visibility için izin verilen değerler (`shared`, `invited`, `joined`, `world_readable`) mapping’de sınırlı.
316
+
317
+ ---
318
+
319
+ ## 13. İlgili kaynak dosyalar
320
+
321
+ - Workflow JSON: [Workflows/](../Workflows/)
322
+ - C# mapping’ler: [Workflows/src/](../Workflows/src/)
323
+ - Fonksiyon tanımları: [Functions/](../Functions/)
324
+ - Proje kuralları: [.cursorrules](../../.cursorrules)
325
+
326
+ ---
327
+
328
+ *Bu doküman, kod ve workflow tanımlarına göre oluşturulmuştur; çalışma zamanı URL’leri ve auth şeması ortamınıza göre değişebilir.*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burgan-tech/morph-touch-runtime",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "morph-touch - Runtime Package for engine deployment",
5
5
  "main": "index.js",
6
6
  "type": "module",