@burgan-tech/morph-touch-runtime 0.0.5 → 0.0.7

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 (41) hide show
  1. package/burgan-tech-morph-touch-runtime-0.0.7.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/GetRezervationsMapping.csx +27 -7
  7. package/morph-touch/Functions/src/GetRoomMessagesMapping.csx +5 -1
  8. package/morph-touch/Functions/src/SendRoomMessageMapping.csx +5 -1
  9. package/morph-touch/Workflows/chat-room.json +9 -9
  10. package/morph-touch/Workflows/notification-sender.json +2 -2
  11. package/morph-touch/Workflows/rezervation-start.json +1 -1
  12. package/morph-touch/Workflows/rezervation-transfer.json +3 -3
  13. package/morph-touch/Workflows/rezervation.json +1 -1
  14. package/morph-touch/Workflows/src/ChatRoomRemoveMapping.csx +5 -1
  15. package/morph-touch/Workflows/src/ChatRoomTransferInviteMapping.csx +6 -2
  16. package/morph-touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +5 -1
  17. package/morph-touch/Workflows/src/ChatRoomUpdateMapping.csx +6 -2
  18. package/morph-touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +5 -1
  19. package/morph-touch/Workflows/src/CreatePermanentChatRoomMapping.csx +5 -1
  20. package/morph-touch/Workflows/src/FetchRoomMessagesForSummaryMapping.csx +5 -1
  21. package/morph-touch/Workflows/src/GetUserInfoForRezervationMapping.csx +5 -1
  22. package/morph-touch/Workflows/src/GetVideoCallUrlMapping.csx +5 -1
  23. package/morph-touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +5 -1
  24. package/morph-touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +5 -1
  25. package/morph-touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +5 -1
  26. package/morph-touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +5 -1
  27. package/morph-touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +5 -1
  28. package/morph-touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +5 -1
  29. package/morph-touch/Workflows/src/JoinMatrixRoomMapping.csx +5 -1
  30. package/morph-touch/Workflows/src/JoinUserToRoomMapping.csx +5 -1
  31. package/morph-touch/Workflows/src/SendPushNotificationMapping.csx +5 -1
  32. package/morph-touch/Workflows/src/SendSmsNotificationMapping.csx +5 -1
  33. package/morph-touch/Workflows/src/SendSummaryToNewRoomMapping.csx +5 -1
  34. package/morph-touch/Workflows/src/SetRoomHistoryVisibilityMapping.csx +5 -1
  35. package/morph-touch/Workflows/src/SummarizeChatWithOpenAIMapping.csx +5 -1
  36. package/morph-touch/Workflows/start-video-call.json +1 -1
  37. package/morph-touch/doc/morph-touch-domain.en.md +742 -0
  38. package/morph-touch/doc/morph-touch-domain.md +745 -0
  39. package/package.json +1 -1
  40. package/vnext.config.json +1 -1
  41. package/burgan-tech-morph-touch-runtime-0.0.5.tgz +0 -0
@@ -0,0 +1,745 @@
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. HTTP örnekleri **`{{BaseUrl}}/morph-touch/...`** şablonunu kullanır; [postman_collection.json](../../postman_collection.json) farklı değişkenlerle (`api/v{{apiVersion}}` vb.) tanımlı olabilir — ortamınızda `baseUrl` ve yol önekini gateway şemanıza göre hizalayın.
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. `instances/` sonrası yolda platform **instance id** (UUID) veya `start` isteğinde verilen instance **`key`** kullanılabilir.
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
+ Detaylı istek gövdeleri, anahtar kuralları ve cURL örnekleri için **§14**’e bakın.
67
+
68
+ ### Randevu transferi ile bağlantı
69
+
70
+ - Geçiş **`start-transfer`** yalnızca `absenceType == "personal-leave"` iken değerlendirilir (`CanStartTransferMapping` — [Workflows/src/CanStartTransferMapping.csx](../Workflows/src/CanStartTransferMapping.csx)).
71
+ - Koşullar sağlanırsa `start-transfer-from-absence-entry` görevi **`rezervation-transfer`** alt akışını başlatır (`StartTransferFromAbsenceEntryMapping`).
72
+ - `endDateTime` **dolu** ise transfer tipi **yıllık izin** (`annual-leave`).
73
+ - `endDateTime` **boş** ise **işten çıkış / termination** (`termination`).
74
+ - Instance verisinde **`advisor`**, **`advisorType`**, **`startDateTime`** zorunludur; aksi halde transfer görevi atlanır (`skipped` + reason).
75
+
76
+ Son durum: `complete-with-transfer` (transfer başlatıldı).
77
+
78
+ ---
79
+
80
+ ## 3. rezervation-transfer
81
+
82
+ **Dosya:** [Workflows/rezervation-transfer.json](../Workflows/rezervation-transfer.json)
83
+
84
+ ### Amaç
85
+
86
+ 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.
87
+
88
+ ### Başlangıç görevleri (özet)
89
+
90
+ 1. **Transfer tipi:** `endDate` yoksa `termination` ve varsayılan uzun uç tarih; varsa `annual-leave`.
91
+ 2. **Kaynak rezervasyonlar:** `get-rezervations` benzeri sorgu (`FetchRezervationsForTransferMapping`).
92
+ 3. **Danışman listesi:** Aktif instance’lar, `advisorType` / kaynak id ile workflow anahtarı çözümü (`FetchAdvisorsForTransferMapping`).
93
+ 4. **Absence kayıtları:** Tamamlanmış `public-holiday`, `working-hours-change`, `personal-leave` (`FetchAbsenceEntriesForTransferMapping`).
94
+ 5. **Zenginleştirme:** Tüm aktif randevular + slot uygunluğu (tatil, çalışma saati, kişisel izin, çakışma) — `EnrichRezervationsForTransferMapping`.
95
+
96
+ ### Önemli kontroller
97
+
98
+ - **`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.
99
+ - **`transferPlan`:** Postman’da örnek: her satırda `rezervationKey` + `targetAdvisor` ([postman_collection.json](../../postman_collection.json) — “Confirm Transfer”).
100
+ - Kalıcı odalar için **`permanentRoomPlan`** (oda `roomId` + `newAdvisorId`) ile devam eden adımlar koleksiyon açıklamasında anlatılır.
101
+
102
+ ---
103
+
104
+ ## 4. rezervation
105
+
106
+ **Dosya:** [Workflows/rezervation.json](../Workflows/rezervation.json)
107
+
108
+ ### Durum özeti (ana hat)
109
+
110
+ `validating` → `appointment-form` veya `slot-unavailable` → `active` → `in-meet` → `meet-completed`
111
+ İptaller: `user-cancelled`, `advisor-cancelled`, `timeout` vb.
112
+
113
+ ### Kontroller
114
+
115
+ | Konu | Kaynak | Açıklama |
116
+ |------|--------|----------|
117
+ | En fazla 2 rezervasyon | `check-duplicate-rezervation` | Aynı kullanıcı için belirli onaylı durumlarda en fazla **2** aktif rezervasyon; **zaman çakışması** yok. |
118
+ | 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. |
119
+ | Tarih | `validate-date-for-rezervation` | Geçmiş veya geçersiz tarih reddedilir. |
120
+ | Kullanıcı | `set-user-from-headers-for-rezervation` | İstek **`sub`** header’ından kullanıcıyı instance’a yazar. |
121
+ | 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. |
122
+
123
+ ### Bildirim (randevu oluşunca)
124
+
125
+ `notification-sender` alt akışı, rezervasyon onayı sırasında başlatılır. **Danışman** için SMS/push içeriği (özet):
126
+
127
+ `Sayın " + (advisorName ?? "Danisman") + ", " + formattedDate + " tarihli randevunuz olusturulmustur."`
128
+
129
+ **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.
130
+
131
+ ### Paylaşımlı geçişler
132
+
133
+ - **`user-cancel` / `advisor-cancel` (active):** İlgili **`absence-entry`** üzerinde `cancel` tetiklenir; danışman iptalinde ek olarak **iptal bildirimi** gönderilir.
134
+ - **`add-invited-participant`**, **`video-call-url-update`:** Davetli listesi ve video URL listesi birleştirme.
135
+
136
+ ---
137
+
138
+ ## 5. notification-sender
139
+
140
+ **Dosya:** [Workflows/notification-sender.json](../Workflows/notification-sender.json)
141
+
142
+ 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.
143
+
144
+ ### Durumlar ve otomatik geçişler
145
+
146
+ | Kaynak | Geçiş | Hedef | Koşul (özet) |
147
+ |--------|--------|-------|----------------|
148
+ | `pending` | `to-sms-sending` | `sms-sending` | `channels.sms == true` |
149
+ | `pending` | `to-push-sending-from-pending` | `push-sending` | SMS istenmiyor, `channels.push == true`, `hasRegisteredDevice == true` |
150
+ | `pending` | `to-complete-from-pending` | `complete` | Uygulanabilir kanal yok (push istenmiş ama cihaz yok, veya hiç kanal yok) |
151
+ | `sms-sending` | (onEntry) | — | `send-sms-notification` görevi; `recipient.phone` (countryCode, prefix, number) zorunlu |
152
+ | `sms-sending` | `to-push-sending-from-sms` | `push-sending` | `channels.push == true` ve `hasRegisteredDevice == true` |
153
+ | `sms-sending` | `to-complete-from-sms` | `complete` | Push istenmiyor veya kayıtlı cihaz yok |
154
+ | `push-sending` | (onEntry) | — | `send-push-notification`; `recipient` içinde `citizenshipNo` / `customerNo` kullanımı |
155
+ | `push-sending` | `to-complete-from-push` | `complete` | Push sonrası her zaman |
156
+
157
+ **İçerik:** `userType == "advisor"` için danışman SMS/push metni; `user` için müşteri metni (mapping özetleri yukarıdaki CSX dosyalarında).
158
+
159
+ Postman: klasör **Notification Sender Subprocess** — SMS only, push only, kanal yok, cihaz yok senaryoları.
160
+
161
+ ---
162
+
163
+ ## 6. rezervation-start
164
+
165
+ **Dosya:** [Workflows/rezervation-start.json](../Workflows/rezervation-start.json)
166
+
167
+ 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.
168
+
169
+ ### Zorunlu / kontroller
170
+
171
+ - **`randevuKey`** zorunlu; state ve data DAPR üzerinden okunur (`GetRezervationStateMapping`, `GetRezervationDataMapping`).
172
+ - **Davetli:** `participantType == "invited"` ve `invitedUserId`, rezervasyondaki `invitedUser` listesinde değilse → **`not-allowed`**.
173
+ - Rezervasyon state **`active`** veya **`in-meet`** değilse → **`meet-not-active`**.
174
+ - **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.
175
+ - **Davetli ve henüz in-meet değilse:** `meet-not-started` dalı.
176
+
177
+ ### Oda ve in-meet
178
+
179
+ - 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.
180
+ - State zaten **`in-meet`** ise: **`join-room`** — Matrix `join`, `x-matrix-user` katılımcı tipine göre (user / advisor / invited).
181
+
182
+ ### Bitiş
183
+
184
+ `end` state’inde **`start-video-call`** alt akışı (LiveKit vb.) çalışır.
185
+
186
+ ---
187
+
188
+ ## 7. chat-room
189
+
190
+ **Dosya:** [Workflows/chat-room.json](../Workflows/chat-room.json)
191
+
192
+ ### Amaç
193
+
194
+ - **Kalıcı oda** (`roomType: permanent`): kullanıcı + danışman tipi + danışman ile tekilleştirilmiş Matrix odası.
195
+ - **Randevu odası** (`roomType: rezervation`): rezervasyon anahtarı ile ilişkili geçici süreç odası.
196
+
197
+ ### Davranış özeti
198
+
199
+ - Oluşturma: Matrix `createRoom`, davet, `join-user-to-room`.
200
+ - **`activated`:** üye ekleme (`update`), üye çıkarma (`remove`), danışman **`transfer`** (kick + invite + join).
201
+ - **`deactivate` / `activate`** durumları.
202
+ - Kalıcı oda için aynı **user + advisorType + activated** ile ikinci oda oluşturma engeli (`ALREADY_COMPLETED`).
203
+
204
+ ### Domain fonksiyonları (workflow üzerinden)
205
+
206
+ `get-chat-rooms`, `get-room-messages`, `send-room-message`, `get-matrix-sync` ([chat-room.json](../Workflows/chat-room.json) `attributes.functions`).
207
+
208
+ ---
209
+
210
+ ## 8. start-chat
211
+
212
+ **Dosya:** [Workflows/start-chat.json](../Workflows/start-chat.json)
213
+
214
+ ### Amaç
215
+
216
+ Kalıcı danışman sohbetini açmak: oda yoksa oluştur, varsa doğrudan sohbete geç.
217
+
218
+ ### Akış
219
+
220
+ 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.
221
+ 2. **Mevcut oda + aynı danışman** → **`in-chat`** (`open-existing-room`).
222
+ 3. **Mevcut oda + farklı danışman** → **`to-change-advisor`:** `chat-room` üzerinde **`transfer`** tetiklenir, sonra **`in-chat`**.
223
+ 4. **Oda yok** → **`start-permanent-chat-room`** ile **`chat-room`** senkron başlatılır, sonra **`in-chat`**.
224
+
225
+ ---
226
+
227
+ ## 9. add-participant-to-rezervation
228
+
229
+ **Dosya:** [Workflows/add-participant-to-rezervation.json](../Workflows/add-participant-to-rezervation.json)
230
+
231
+ ### Önkoşul
232
+
233
+ Rezervasyon state **`active`** veya **`in-meet`**; aksi halde **`state-not-valid`**.
234
+
235
+ ### Dallar
236
+
237
+ - **`in-meet`:** `chat-room` üzerinde **update** (yeni üye) + `rezervation` üzerinde **`add-invited-participant`** tetikleri + **`start-video-call`** alt akışı (davetli müşteri gibi).
238
+ - **`active`:** **`update-invited`** → **`end`** (davetli güncelleme).
239
+
240
+ `newUserId` / `randevuKey` görev mapping’lerinde zorunludur.
241
+
242
+ ---
243
+
244
+ ## 10. Domain fonksiyonları (özet)
245
+
246
+ | Fonksiyon | Dosya | Amaç / not |
247
+ |-----------|--------|------------|
248
+ | `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. |
249
+ | `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`. |
250
+ | `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). |
251
+ | `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). |
252
+ | `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). |
253
+ | `get-customer-info` | [Functions/get-customer-info.1.0.0.json](../Functions/get-customer-info.1.0.0.json) | Müşteri bilgisi. |
254
+ | `get-matrix-sync` | [Functions/get-matrix-sync.1.0.0.json](../Functions/get-matrix-sync.1.0.0.json) | Matrix sync yanıtı. |
255
+ | `get-rezervations` | [Functions/get-rezervations.1.0.0.json](../Functions/get-rezervations.1.0.0.json) | Filtreli rezervasyon listesi. |
256
+ | `get-room-messages` | [Functions/get-room-messages.1.0.0.json](../Functions/get-room-messages.1.0.0.json) | Oda mesajları. |
257
+ | `send-room-message` | [Functions/send-room-message.1.0.0.json](../Functions/send-room-message.1.0.0.json) | Matrix’e mesaj gönderimi. |
258
+
259
+ Detaylı HTTP örnekleri için [Functions/get-room-messages.http](../Functions/get-room-messages.http) dosyasına bakılabilir.
260
+
261
+ ---
262
+
263
+ ## 11. Postman koleksiyonu
264
+
265
+ **Dosya:** [postman_collection.json](../../postman_collection.json) (workspace kökü)
266
+ **Koleksiyon adı:** vNext Touch Domain
267
+
268
+ ### Ortak değişkenler (varsayılanlar)
269
+
270
+ | Değişken | Örnek değer |
271
+ |----------|-------------|
272
+ | `baseUrl` | `http://localhost:4201` |
273
+ | `apiVersion` | `1` |
274
+ | `domain` | `morph-touch` |
275
+ | `instanceKey` / `user` | `core.user.user-001` |
276
+ | `advisor` / `advisorId` | `morph-touch.portfolio-manager.pm-001` |
277
+
278
+ ### Workflow API şablonları
279
+
280
+ - **Instance başlat:**
281
+ `POST {{baseUrl}}/morph-touch/workflows/{flowKey}/instances/start?sync=true`
282
+ Örnek: `rezervation`, `absence-entry`, `rezervation-start`, `chat-room`, `start-chat`, `rezervation-transfer`, `notification-sender` (alt süreç).
283
+ - **Instance oku:**
284
+ `GET {{baseUrl}}/morph-touch/workflows/{flowKey}/instances/{{instanceIdOrKey}}`
285
+ Yol segmenti: platform **instance `id`** (UUID) veya `start` isteğinde verilen instance **`key`** (ör. `working-hour`, `rez-...`).
286
+ - **Geçiş:**
287
+ `PATCH {{baseUrl}}/morph-touch/workflows/{flowKey}/instances/{{instanceIdOrKey}}/transitions/{transitionKey}?sync=true`
288
+ Aynı şekilde **id** veya **`key`** kullanılabilir. Gövde genelde `{ "attributes": { ... } }`.
289
+
290
+ ### Örnek istekler (koleksiyon klasörleri)
291
+
292
+ | Klasör / istek | Metod | Not |
293
+ |----------------|-------|-----|
294
+ | **Reservation Workflow → Start Rezervation** | POST | `sub` header; body’de `user`, `advisor`, `startDateTime`, `endDateTime`. |
295
+ | **Confirm Selection** | PATCH | `transitions/confirm-selection` — slot doğrulama adımı. |
296
+ | **Appointment Form Retry** | PATCH | `appointment-form-retry` + yeni `startDateTime` / `endDateTime`. |
297
+ | **Create Appointment** | PATCH | `create-appointment` → `active`. |
298
+ | **Rezervation Start Workflow** | POST | `randevuKey`, `participantType` (advisor / customer / invited). |
299
+ | **Chat Room Workflow** | POST / PATCH | Kalıcı PM/IA başlatma; `update`, `remove`, `transfer`. |
300
+ | **Start Chat Workflow** | POST | Kalıcı oda yoksa oluşturur, varsa `in-chat`. |
301
+ | **Rezervation Transfer** | POST + PATCH | `startDate`/`endDate`; `confirm-transfer` ile `transferPlan`. |
302
+ | **Get Absence Entry Function** | GET | `.../functions/get-absence-entry?absenceType=...` |
303
+ | **Get Available Slots** | GET | `advisorId`, `date`, `duration`. |
304
+ | **Get Chat Rooms** | GET | `user=...` veya `advisor=...` |
305
+ | **Matrix Synapse API** | çeşitli | `http://localhost:9080/...` — presence, createRoom (manuel test). |
306
+ | **Notification Sender Subprocess** | POST | `workflows/notification-sender/instances/start` — kanal bayrakları ve recipient yapısı örnekleri. |
307
+
308
+ 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.
309
+
310
+ ---
311
+
312
+ ## 12. Ek kontroller ve kenar durumları
313
+
314
+ - **Rezervasyon iptali:** `absence-entry` iptali tetiklenir; eski instance’larda `absenceEntryKey` yoksa cancel no-op olabilir.
315
+ - **Çoklu davetli / video URL:** `merge-invited-user`, `merge-video-call-urls` ile liste birleştirme.
316
+ - **check-livekit-room-access:** Token formatı JWT veya `room:participant`; birden fazla eşleşmede anlamlı olmayan sonuç döner.
317
+ - **notification-sender:** SMS için telefon yapısı zorunlu; push için `citizenshipNo` / `customerNo` ve kayıtlı cihaz bayrağı.
318
+ - **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ı.
319
+
320
+ ---
321
+
322
+ ## 13. İlgili kaynak dosyalar
323
+
324
+ - Workflow JSON: [Workflows/](../Workflows/)
325
+ - C# mapping’ler: [Workflows/src/](../Workflows/src/)
326
+ - Fonksiyon tanımları: [Functions/](../Functions/)
327
+ - Proje kuralları: [.cursorrules](../../.cursorrules)
328
+
329
+ ---
330
+
331
+ ## 14. API kullanım kılavuzu (cURL ve alan kuralları)
332
+
333
+ ### 14.1 Ön koşul ve sıra
334
+
335
+ Randevu ve **get-available-slots** mantığı için önce **şirket çalışma saatleri** kaydının oluşturulması önerilir (`absenceType: working-hours-change`, instance `key: "working-hour"`, tags `working-hours-change` + `company`). Ardından resmi tatiller, danışman izinleri / özel çalışma saatleri ve rezervasyon akışı kullanılabilir.
336
+
337
+ ### 14.2 `{{BaseUrl}}`, yol şablonu ve kimlik doğrulama
338
+
339
+ - Tüm örneklerde **`{{BaseUrl}}`**, ortamınızdaki API gateway **kökünü** temsil eder (örneğin `https://<host>` veya kurulumunuza göre `https://<host>/ebanking`). Değeri APISIX / ortam dokümantasyonunuza göre ayarlayın; kökün sonunda `/` bırakmayın veya birleştirmede **çift slash** (`//morph-touch`) oluşmamasına dikkat edin.
340
+ - Standart şablon: **`{{BaseUrl}}/morph-touch/workflows/...`** ve **`{{BaseUrl}}/morph-touch/functions/...`** (örnek: `{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/start?sync=true`).
341
+ - Postman koleksiyonundaki `{{baseUrl}}` ile aynı rolde düşünülebilir; isimlendirme dokümanda `{{BaseUrl}}` olarak verilmiştir.
342
+ - **`Authorization: Bearer <access_token>`:** Erişim jetonu **ortama göre** verilir (geliştirme, test, üretim). Token’ı ilgili kimlik sağlayıcısından veya ortamınızın (APISIX, API portalı, güvenlik ekibi) verdiği yöntemle alın; örneklerdeki `<access_token>` yalnızca yer tutucudur. Gerçek token’ları repoya veya paylaşılan dokümana yapıştırmayın.
343
+ - `.../workflows/{flowKey}/instances/<segment>/...` adresindeki `<segment>`: **`{{instanceIdOrKey}}`** — ya platformun döndüğü **instance id** ya da instance **`key`** değeridir.
344
+
345
+ ### 14.3 Şirket çalışma saatleri — `absence-entry` start (tek sefer)
346
+
347
+ `key` **sabit** `working-hour` olmalıdır. `absenceType` **`working-hours-change`**. `customWorkingHours` altında haftanın günleri (`monday` … `sunday`) tanımlanır; her gün **dizi** olup elemanlar `{ "start": "HH:mm", "end": "HH:mm" }` şeklindedir.
348
+
349
+ ```bash
350
+ curl --location '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/start?sync=true' \
351
+ --header 'Content-Type: application/json' \
352
+ --header 'Accept-Language: tr-TR' \
353
+ --header 'X-Request-Id: <uuid>' \
354
+ --header 'Authorization: Bearer <access_token>' \
355
+ --data '{
356
+ "key": "working-hour",
357
+ "tags": ["working-hours-change", "company"],
358
+ "attributes": {
359
+ "absenceType": "working-hours-change",
360
+ "title": "Şirket Çalışma Saatleri",
361
+ "customWorkingHours": {
362
+ "monday": [{"start": "09:00", "end": "12:00"}, {"start": "13:30", "end": "18:00"}],
363
+ "tuesday": [{"start": "09:00", "end": "12:00"}, {"start": "13:30", "end": "18:00"}],
364
+ "wednesday": [{"start": "09:00", "end": "12:00"}, {"start": "13:30", "end": "18:00"}],
365
+ "thursday": [{"start": "09:00", "end": "12:00"}, {"start": "13:30", "end": "18:00"}],
366
+ "friday": [{"start": "09:00", "end": "12:00"}, {"start": "13:30", "end": "17:00"}],
367
+ "saturday": [],
368
+ "sunday": []
369
+ }
370
+ }
371
+ }'
372
+ ```
373
+
374
+ ### 14.4 Şirket çalışma saatleri — sonraki güncellemeler (`update`)
375
+
376
+ Aynı domainde şirket kaydı genelde **bir kez** `start` ile açılır; sonrasında yalnızca **`PATCH .../transitions/update`** kullanılır. URL’de **`{{instanceIdOrKey}}`** olarak ya yanıttaki **platform instance id** (UUID) ya da şirket kaydı için sabit **`key`** (`working-hour`) kullanılabilir.
377
+
378
+ ```bash
379
+ curl --location --request PATCH '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/{{instanceIdOrKey}}/transitions/update?sync=true' \
380
+ --header 'Content-Type: application/json' \
381
+ --header 'Accept-Language: tr-TR' \
382
+ --header 'X-Request-Id: <uuid>' \
383
+ --header 'Authorization: Bearer <access_token>' \
384
+ --data '{
385
+ "attributes": {
386
+ "title": "Şirket Çalışma Saatleri (Güncellendi)",
387
+ "customWorkingHours": {
388
+ "monday": [{"start": "08:30", "end": "12:00"}, {"start": "13:00", "end": "17:30"}],
389
+ "tuesday": [{"start": "08:30", "end": "12:00"}, {"start": "13:00", "end": "17:30"}],
390
+ "wednesday": [{"start": "08:30", "end": "12:00"}, {"start": "13:00", "end": "17:30"}],
391
+ "thursday": [{"start": "08:30", "end": "12:00"}, {"start": "13:00", "end": "17:30"}],
392
+ "friday": [{"start": "08:30", "end": "12:00"}, {"start": "13:00", "end": "16:30"}],
393
+ "saturday": [],
394
+ "sunday": []
395
+ }
396
+ }
397
+ }'
398
+ ```
399
+
400
+ ### 14.5 Resmi tatil (`public-holiday`)
401
+
402
+ `key` deseni: `public-holiday-{tarih}` (örnek: `public-holiday-2026-04-23`). `absenceType` **`public-holiday`**. Tam veya yarım gün için `startDateTime` / `endDateTime` ihtiyaca göre set edilir.
403
+
404
+ ```bash
405
+ curl --location '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/start?sync=true' \
406
+ --header 'Content-Type: application/json' \
407
+ --header 'Accept-Language: tr-TR' \
408
+ --header 'X-Request-Id: <uuid>' \
409
+ --header 'Authorization: Bearer <access_token>' \
410
+ --data '{
411
+ "key": "public-holiday-2026-04-23",
412
+ "tags": ["public-holiday"],
413
+ "attributes": {
414
+ "absenceType": "public-holiday",
415
+ "startDateTime": "2026-04-23T00:00:00",
416
+ "endDateTime": "2026-04-23T23:59:59",
417
+ "title": "23 Nisan Ulusal Egemenlik ve Çocuk Bayramı"
418
+ }
419
+ }'
420
+ ```
421
+
422
+ ### 14.6 Kişisel izin (`personal-leave`)
423
+
424
+ `key` deseni: `personal-leave-{advisorId}-{startDateTime}-{endDateTime}`. `absenceType` **`personal-leave`**. `advisor` izin alan danışmanın benzersiz kimliği (çoğunlukla sicil). `advisorType` ortamda kısaltma (**`PM` / `IA`**) veya tam akış değerleri (**`portfolio-manager` / `investment-advisor`**) olarak kullanılabilir; üretim sözleşmenize göre seçin.
425
+
426
+ ```bash
427
+ curl --location '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/start?sync=true' \
428
+ --header 'Content-Type: application/json' \
429
+ --header 'Accept-Language: tr-TR' \
430
+ --header 'X-Request-Id: <uuid>' \
431
+ --header 'sub: <kullanici_sub>' \
432
+ --header 'Authorization: Bearer <access_token>' \
433
+ --data '{
434
+ "key": "personal-leave-<advisorId>-2026-04-07T00:00:00-2026-04-07T12:59:59",
435
+ "tags": ["personal-leave"],
436
+ "attributes": {
437
+ "advisor": "<advisorId>",
438
+ "advisorType": "PM",
439
+ "absenceType": "personal-leave",
440
+ "startDateTime": "2026-04-07T00:00:00",
441
+ "endDateTime": "2026-04-07T12:59:59",
442
+ "title": "Müşteri Toplantısı"
443
+ }
444
+ }'
445
+ ```
446
+
447
+ ### 14.7 Danışmana özel çalışma saatleri (`working-hours-change` + advisor)
448
+
449
+ `key` deseni: `working-hour-{advisorId}`. Tags: `working-hours-change`, `advisor`. `advisor` alanı zorunlu; `customWorkingHours` yapısı §14.3 ile aynıdır.
450
+
451
+ ```bash
452
+ curl --location '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/start?sync=true' \
453
+ --header 'Content-Type: application/json' \
454
+ --header 'Accept-Language: tr-TR' \
455
+ --header 'X-Request-Id: <uuid>' \
456
+ --header 'Authorization: Bearer <access_token>' \
457
+ --data '{
458
+ "key": "working-hour-<advisorId>",
459
+ "tags": ["working-hours-change", "advisor"],
460
+ "attributes": {
461
+ "advisor": "<advisorId>",
462
+ "absenceType": "working-hours-change",
463
+ "title": "Özel Çalışma Saatleri",
464
+ "customWorkingHours": {
465
+ "monday": [{"start": "10:00", "end": "12:00"}, {"start": "13:00", "end": "19:00"}],
466
+ "tuesday": [],
467
+ "wednesday": [],
468
+ "thursday": [],
469
+ "friday": [],
470
+ "saturday": [],
471
+ "sunday": []
472
+ }
473
+ }
474
+ }'
475
+ ```
476
+
477
+ ### 14.8 İptal — `cancel` geçişi
478
+
479
+ ```bash
480
+ curl --location --request PATCH '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/{{instanceIdOrKey}}/transitions/cancel?sync=true' \
481
+ --header 'Content-Type: application/json' \
482
+ --header 'Accept-Language: tr-TR' \
483
+ --header 'X-Request-Id: <uuid>' \
484
+ --header 'Authorization: Bearer <access_token>' \
485
+ --data '{"attributes": {}}'
486
+ ```
487
+
488
+ ### 14.9 Yokluk güncelleme — `update` (örnek: izin tarihleri)
489
+
490
+ ```bash
491
+ curl --location --request PATCH '{{BaseUrl}}/morph-touch/workflows/absence-entry/instances/{{instanceIdOrKey}}/transitions/update?sync=true' \
492
+ --header 'Content-Type: application/json' \
493
+ --header 'Accept-Language: tr-TR' \
494
+ --header 'X-Request-Id: <uuid>' \
495
+ --header 'Authorization: Bearer <access_token>' \
496
+ --data '{
497
+ "attributes": {
498
+ "startDateTime": "2026-01-28T15:00:00",
499
+ "endDateTime": "2026-01-28T17:00:00",
500
+ "title": "Müşteri Toplantısı (Güncellendi)"
501
+ }
502
+ }'
503
+ ```
504
+
505
+ ### 14.10 `get-absence-entry` fonksiyonu
506
+
507
+ `absenceType` zorunlu; şirket çalışma saatleri için yalnız `working-hours-change` gönderildiğinde şirket geneli kayıtlar döner. Tarih aralığı ile resmi tatiller; `advisor` ile danışman çalışma saatleri.
508
+
509
+ ```bash
510
+ # Şirket çalışma saatleri
511
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-absence-entry?absenceType=working-hours-change' \
512
+ --header 'Accept: application/json' \
513
+ --header 'Accept-Language: tr-TR' \
514
+ --header 'X-Request-Id: <uuid>' \
515
+ --header 'Authorization: Bearer <access_token>'
516
+
517
+ # Resmi tatiller (tarih aralığı)
518
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-absence-entry?absenceType=public-holiday&startDate=2026-04-01T00:00:00&endDate=2026-04-30T23:59:59' \
519
+ --header 'Accept: application/json' \
520
+ --header 'Accept-Language: tr-TR' \
521
+ --header 'X-Request-Id: <uuid>' \
522
+ --header 'Authorization: Bearer <access_token>'
523
+
524
+ # Danışman özel çalışma saatleri
525
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-absence-entry?absenceType=working-hours-change&advisor=<advisorId>' \
526
+ --header 'Accept: application/json' \
527
+ --header 'Accept-Language: tr-TR' \
528
+ --header 'X-Request-Id: <uuid>' \
529
+ --header 'Authorization: Bearer <access_token>'
530
+ ```
531
+
532
+ ### 14.11 `get-available-slots`
533
+
534
+ Belirtilen `advisorId` ve `date` için o günkü boş slotları döner; `duration` isteğe bağlıdır (dakika).
535
+
536
+ ```bash
537
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-available-slots?advisorId=<advisorId>&date=2026-03-17' \
538
+ --header 'Accept: application/json' \
539
+ --header 'Accept-Language: tr-TR' \
540
+ --header 'X-Request-Id: <uuid>' \
541
+ --header 'Authorization: Bearer <access_token>'
542
+ ```
543
+
544
+ Örnek gövde:
545
+
546
+ ```json
547
+ {
548
+ "getAvailableSlots": {
549
+ "availableSlots": [
550
+ "09:00-09:30",
551
+ "09:30-10:00",
552
+ "10:00-10:30"
553
+ ]
554
+ }
555
+ }
556
+ ```
557
+
558
+ ### 14.12 Rezervasyon akışı (`rezervation`)
559
+
560
+ 1. **`start`:** `key` her rezervasyon için benzersiz olmalıdır; sonraki adımlarda `randevuKey` olarak bu değer kullanılır. `user`, `advisor`, `startDateTime`, `endDateTime` — slotlarla uyumlu aralık seçin. **`sub`** header’ı token’dan veya açıkça gönderilir (müşteri kimliği).
561
+ 2. Geçmiş tarih veya aynı kullanıcı için kurallara aykırı ikinci aktif rezervasyon varsa oluşturma reddedilebilir (bkz. §4 / §12).
562
+ 3. State **`slot-unavailable`** ise **`appointment-form-retry`** ile yeni tarih/saat gönderilir.
563
+ 4. **`appointment-form`** sonrası **`confirm-selection`** ile kullanıcı girdisi onaylanır.
564
+ 5. **`create-appointment`** ile durum **`active`** olur; arka planda bildirim ve kullanıcı bilgisi (`get-user-info-for-rezervation`) çalışır, SMS kayıtlı telefona gider.
565
+
566
+ Aşağıdaki geçiş çağrılarında `instances/` sonrasına **platform instance id** veya `start` ile verdiğiniz rezervasyon **`key`** (ör. `rez-<unique-suffix>`) yazılabilir (`{{rezervationInstanceIdOrKey}}`).
567
+
568
+ ```bash
569
+ curl --location '{{BaseUrl}}/morph-touch/workflows/rezervation/instances/start?sync=true' \
570
+ --header 'Content-Type: application/json' \
571
+ --header 'Accept-Language: tr-TR' \
572
+ --header 'X-Request-Id: <uuid>' \
573
+ --header 'sub: <customer_sub>' \
574
+ --header 'Authorization: Bearer <access_token>' \
575
+ --data '{
576
+ "key": "rez-<unique-suffix>",
577
+ "tags": ["appointment", "randevu"],
578
+ "attributes": {
579
+ "user": "<userRef>",
580
+ "advisor": "<advisorRef>",
581
+ "startDateTime": "2026-04-17T10:30:00",
582
+ "endDateTime": "2026-04-17T11:00:00"
583
+ }
584
+ }'
585
+ ```
586
+
587
+ ```bash
588
+ curl --location --request PATCH '{{BaseUrl}}/morph-touch/workflows/rezervation/instances/{{rezervationInstanceIdOrKey}}/transitions/appointment-form-retry?sync=true' \
589
+ --header 'Content-Type: application/json' \
590
+ --header 'Accept-Language: tr-TR' \
591
+ --header 'X-Request-Id: <uuid>' \
592
+ --header 'Authorization: Bearer <access_token>' \
593
+ --data '{
594
+ "attributes": {
595
+ "startDateTime": "2026-04-17T11:00:00",
596
+ "endDateTime": "2026-04-17T11:30:00"
597
+ }
598
+ }'
599
+ ```
600
+
601
+ ```bash
602
+ curl --location --request PATCH '{{BaseUrl}}/morph-touch/workflows/rezervation/instances/{{rezervationInstanceIdOrKey}}/transitions/confirm-selection?sync=true' \
603
+ --header 'Content-Type: application/json' \
604
+ --header 'Accept-Language: tr-TR' \
605
+ --header 'X-Request-Id: <uuid>' \
606
+ --header 'Authorization: Bearer <access_token>' \
607
+ --data '{"attributes": {}}'
608
+ ```
609
+
610
+ ```bash
611
+ curl --location --request PATCH '{{BaseUrl}}/morph-touch/workflows/rezervation/instances/{{rezervationInstanceIdOrKey}}/transitions/create-appointment?sync=true' \
612
+ --header 'Content-Type: application/json' \
613
+ --header 'Accept-Language: tr-TR' \
614
+ --header 'X-Request-Id: <uuid>' \
615
+ --header 'Authorization: Bearer <access_token>' \
616
+ --data '{"attributes": {}}'
617
+ ```
618
+
619
+ ### 14.13 Görüşme başlatma (`rezervation-start`)
620
+
621
+ Randevu başlangıcına **en fazla 15 dakika** kala çağrılabilir; daha erken ise **`meet-not-started`** benzeri dala düşer. `randevuKey` ilgili rezervasyonun `key` değeridir. `participantType`: `customer`, `advisor` veya `invited`; **`invited`** ise **`invitedUserId`** zorunludur ve kullanıcı önce **add-participant-to-rezervation** akışı ile rezervasyona eklenmiş olmalıdır. İlk katılımcı Matrix odasını oluşturur ve rezervasyon **`in-meet`** olur; ikinci katılımcı **join** eder ve LiveKit URL’leri rezervasyon datasına yazılır.
622
+
623
+ ```bash
624
+ curl --location '{{BaseUrl}}/morph-touch/workflows/rezervation-start/instances/start?sync=true' \
625
+ --header 'Content-Type: application/json' \
626
+ --header 'Accept-Language: tr-TR' \
627
+ --header 'X-Request-Id: <uuid>' \
628
+ --header 'Authorization: Bearer <access_token>' \
629
+ --data '{
630
+ "key": "randevu-<unique-suffix>",
631
+ "tags": ["randevu", "meeting"],
632
+ "attributes": {
633
+ "randevuKey": "rez-<unique-suffix>",
634
+ "participantType": "advisor"
635
+ }
636
+ }'
637
+ ```
638
+
639
+ Davetli örneği: `participantType: "invited"` ve `invitedUserId: "<davetliId>"` ekleyin.
640
+
641
+ ### 14.14 Rezervasyona katılımcı ekleme (`add-participant-to-rezervation`)
642
+
643
+ ```bash
644
+ curl --location '{{BaseUrl}}/morph-touch/workflows/add-participant-to-rezervation/instances/start?sync=true' \
645
+ --header 'Content-Type: application/json' \
646
+ --header 'Accept-Language: tr-TR' \
647
+ --header 'X-Request-Id: <uuid>' \
648
+ --header 'Authorization: Bearer <access_token>' \
649
+ --data '{
650
+ "key": "add-participant-<unique-suffix>",
651
+ "tags": ["rezervation", "add-participant"],
652
+ "attributes": {
653
+ "randevuKey": "rez-<unique-suffix>",
654
+ "newUserId": "<davetEdilecekSicil>"
655
+ }
656
+ }'
657
+ ```
658
+
659
+ Önerilen `key` deseni: `add-participant-{advisorId}-{randevuKey}` (benzersizlik için).
660
+
661
+ ### 14.15 Aktif rezervasyon güncelleme (`rezervation-update`)
662
+
663
+ `randevuKey` güncellenecek rezervasyonun `key` değeridir. `startDateTime`, `endDateTime`, `advisor` ihtiyaca göre gönderilir. **`autoProcess: true`** ise akış doğrulamayı otomatik ilerletebilir; **`false`** ise `start` sonrası güncelleme değerleri **`PATCH .../transitions/to-validate`** ile gönderilir ([rezervation-update.json](../Workflows/rezervation-update.json)).
664
+
665
+ ```bash
666
+ curl --location '{{BaseUrl}}/morph-touch/workflows/rezervation-update/instances/start?sync=true' \
667
+ --header 'Content-Type: application/json' \
668
+ --header 'Accept-Language: tr-TR' \
669
+ --header 'X-Request-Id: <uuid>' \
670
+ --header 'Authorization: Bearer <access_token>' \
671
+ --data '{
672
+ "key": "rezervation-update-<unique-suffix>",
673
+ "tags": ["rezervation", "randevu", "update"],
674
+ "attributes": {
675
+ "randevuKey": "rez-<unique-suffix>",
676
+ "startDateTime": "2026-02-03T10:00:00",
677
+ "endDateTime": "2026-02-03T10:30:00",
678
+ "advisor": "<yeniAdvisorRef>",
679
+ "autoProcess": true
680
+ }
681
+ }'
682
+ ```
683
+
684
+ ### 14.16 Kalıcı sohbet — `start-chat`
685
+
686
+ Oda yoksa oluşturulur; varsa doğrudan **`in-chat`**. `user` sohbeti başlatan müşteri; `advisorType` **`PM`** veya **`IA`**; `advisorId` danışmanın benzersiz kimliği (sicil).
687
+
688
+ ```bash
689
+ curl --location '{{BaseUrl}}/morph-touch/workflows/start-chat/instances/start?sync=true' \
690
+ --header 'Content-Type: application/json' \
691
+ --header 'Accept-Language: tr-TR' \
692
+ --header 'X-Request-Id: <uuid>' \
693
+ --header 'Authorization: Bearer <access_token>' \
694
+ --data '{
695
+ "key": "start-chat-<unique-suffix>",
696
+ "tags": ["chat", "start-chat"],
697
+ "attributes": {
698
+ "user": "<userRef>",
699
+ "advisorType": "IA",
700
+ "advisorId": "<advisorId>"
701
+ }
702
+ }'
703
+ ```
704
+
705
+ ### 14.17 Sohbet odaları ve mesajlar (domain fonksiyonları)
706
+
707
+ Canonical yol: **`GET {{BaseUrl}}/morph-touch/functions/get-chat-rooms`** ve **`GET .../functions/get-room-messages`**. Bazı gateway kurulumlarında farklı önek olabilir.
708
+
709
+ **`get-chat-rooms`:** `user` **veya** `advisor` (ikisi birden değil). İsteğe bağlı `roomType`: `permanent` veya `rezervation`.
710
+
711
+ **Not:** [GetChatRoomsMapping](../Functions/src/GetChatRoomsMapping.csx) içinde instance sorgusu şu an sabit `pageSize=100` ile yapılabilir; query’de `pageSize` geçmek her zaman etkili olmayabilir.
712
+
713
+ ```bash
714
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-chat-rooms?user=<userRef>&roomType=permanent' \
715
+ --header 'Accept: application/json' \
716
+ --header 'Accept-Language: tr-TR' \
717
+ --header 'X-Request-Id: <uuid>' \
718
+ --header 'Authorization: Bearer <access_token>'
719
+ ```
720
+
721
+ **`get-room-messages`:** Zorunlu `roomId`, `user`. İsteğe bağlı **`limit`** (varsayılan mapping tarafında 50); sayfalama için `from` token’ı kullanılabilir.
722
+
723
+ ```bash
724
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-room-messages?roomId=<encodedRoomId>&user=<userRef>&limit=20' \
725
+ --header 'Accept: application/json' \
726
+ --header 'Accept-Language: tr-TR' \
727
+ --header 'X-Request-Id: <uuid>' \
728
+ --header 'Authorization: Bearer <access_token>'
729
+ ```
730
+
731
+ ### 14.18 Rezervasyon listesi — `get-rezervations`
732
+
733
+ Query: `advisorId`, `userId`, `startDate`, `endDate` — tarihler zorunlu değildir; aralık filtrelemek için kullanılır.
734
+
735
+ ```bash
736
+ curl --location '{{BaseUrl}}/morph-touch/functions/get-rezervations?advisorId=<advisorId>&startDate=2026-02-01&endDate=2026-02-28' \
737
+ --header 'Accept: application/json' \
738
+ --header 'Accept-Language: tr-TR' \
739
+ --header 'X-Request-Id: <uuid>' \
740
+ --header 'Authorization: Bearer <access_token>'
741
+ ```
742
+
743
+ ---
744
+
745
+ *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.*