# Workflow ve Subworkflow
## Giriş ve Genel Bakış:
### Workflow Servisinin Amacı ve Genel Yapısı
#### Workflow Servisinin Amacı
Workflow servisi, iş süreçlerini otomatize etmek, yönetmek ve izlemek için kullanılan bir araçtır. Bu servisin temel amacı, süreçleri daha verimli, hata oranı düşük ve kolay yönetilebilir hale getirmektir. Çeşitli iş akışlarını tek bir platform üzerinden tanımlayarak ve bu akışları otomatikleştirerek, organizasyonların zaman ve maliyet tasarrufu sağlamalarına yardımcı olur. Bu, iş akışlarının daha hızlı ve hatasız bir şekilde tamamlanmasını sağlayarak genel operasyonel verimliliği artırır.
#### Genel Yapı
Workflow servisinin genel yapısı, iş süreçlerini tanımlama, yönetme ve optimize etme yeteneği üzerine kurulmuştur. Servisin genel yapısı, aşağıdaki bileşenlere dayanmaktadır:
1. **Workflow ve Sub Workflow Tanımları:**
- Workflow Tanımı: Belirli iş süreçlerini ve bu süreçlerin nasıl işleyeceğini tanımlar. Her bir iş akışı, başlangıçtan sona kadar gerekli adımları ve karar noktalarını içerir.
- Sub Workflow Tanımı: Ana iş akışının bir parçası olarak çalışan ve belirli koşullarda devreye giren alt iş akışlarıdır. Bu yaklaşım, iş akışlarını daha modüler ve yönetilebilir hale getirir.
2. **Süreç Tasarımı ve Yönetimi:**
- İş akışları, standart süreç modelleme dilleri kullanılarak tasarlanır. Bu modelleme, iş akışlarının görsel olarak anlaşılabilir ve kolayca yönetilebilir olmasını sağlar.
- BPMN gibi araçlar, iş süreçlerinin tasarımında ve düzenlenmesinde kullanılır.
3. **Otomasyon ve Entegrasyon:**
- Workflow servisi, iş süreçlerini otomatize etmek için çeşitli araçlar ve entegrasyonlar sağlar. Bu, manuel iş yükünü azaltır ve süreçlerin daha hızlı ve hatasız tamamlanmasını sağlar.
- Entegrasyon, farklı sistemler ve uygulamalar arasında veri akışını ve iş birliğini kolaylaştırır.
4. **İzleme ve Raporlama:**
- Servis, iş süreçlerinin performansını izlemek ve analiz etmek için araçlar sunar. Bu, süreçlerin etkinliğinin ölçülmesini ve sürekli iyileştirme fırsatlarının belirlenmesini sağlar.
- Raporlama özellikleri, süreçlerin durumu ve performansı hakkında ayrıntılı bilgiler sağlar.
5. **Güvenlik ve Erişim Kontrolleri:**
- Güvenlik, workflow servisinin temel bir bileşenidir. Kullanıcıların yetkilendirilmesi, erişim kontrolü ve veri güvenliği, servisin güvenilir ve güvenli bir şekilde kullanılmasını sağlar.
Bu genel yapı, iş süreçlerinin etkili bir şekilde yönetilmesini, otomatize edilmesini ve iyileştirilmesini sağlar. Servis, iş süreçlerinin karmaşıklığını azaltarak organizasyonların daha verimli ve etkin çalışmasına imkan tanır.
### Camunda ve Zeebe’nin Roller ve Süreçteki Önemleri
#### Camunda'nın Rolü
Camunda, iş süreçlerinin modellemesi ve otomasyonu için gelişmiş bir platformdur. Workflow yönetimi ve süreç otomasyonu konusunda kritik bir rol oynar. İşte Camunda'nın ana rolleri ve önemi:
1. **Süreç Modelleme ve Tasarımı:**
- Camunda, BPMN (Business Process Model and Notation) standardını kullanarak iş süreçlerinin görsel modellemesini sağlar. Bu, iş akışlarının net, anlaşılır ve etkin bir şekilde tasarlanmasına olanak tanır.
2. **Otomasyon ve Yürütme:**
- Modelleme sonrasında Camunda, bu süreçlerin otomatik olarak yürütülmesine imkan verir. Bu, manuel işlemleri azaltarak zaman ve kaynak tasarrufu sağlar.
3. **İş Akışlarının İzlenmesi ve Yönetimi:**
- Camunda, iş akışlarının gerçek zamanlı izlenmesi ve yönetilmesi için araçlar sunar. Bu, süreçler üzerinde tam kontrol ve görünürlük sağlayarak, verimliliği artırır.
4. **Entegrasyon ve Esneklik:**
- Çeşitli sistemlerle entegre olabilen Camunda, esnek bir yapı sunar ve farklı iş ihtiyaçlarına uyum sağlar.
#### Zeebe'nin Rolü
Zeebe, yüksek performanslı bir workflow motorudur ve özellikle büyük ölçekli ve yüksek hacimli iş yüklerinde ön plana çıkar. İşte Zeebe'nin rolleri ve önemi:
1. **Ölçeklenebilir Workflow Motoru:**
- Zeebe, ölçeklenebilir ve yüksek performanslı iş akışları için tasarlanmıştır. Büyük veri setleri ve yoğun iş yükleri ile başa çıkabilir.
2. **Gerçek Zamanlı İş Akışı İzleme ve Yönetimi:**
- Süreçleri gerçek zamanlı olarak izleyebilir ve yönetebilir. Bu, iş akışlarının sürekli olarak optimize edilmesine ve hızlı yanıt verilmesine olanak tanır.
3. **Mikro Hizmetler ve Dağıtık Sistemlerle Entegrasyon:**
- Zeebe, mikro hizmet mimarileri ve dağıtık sistemlerle kolayca entegre olabilir. Bu, modern yazılım geliştirme yaklaşımlarıyla uyumluluğunu artırır.
4. **Yüksek Kullanılabilirlik ve Güvenilirlik:**
- Zeebe, yüksek kullanılabilirlik ve güvenilirlik sunar, bu da onu kritik iş süreçleri için ideal bir çözüm yapar.
Camunda ve Zeebe'nin birlikte kullanımı, iş süreçlerinin verimli bir şekilde modellemesini, otomasyonunu ve yönetimini sağlar. Bu ikili, iş süreçlerinin karmaşıklığını azaltırken, esneklik ve ölçeklenebilirlik sunar, böylece işletmelerin değişen ihtiyaçlarına hızlı bir şekilde uyum sağlar.
## Workflow ve Sub Workflow Tanımlama:
### Workflow Tanımı Ayrıntıları
#### cURL Komutu:
Bu komut, API üzerinden bir workflow tanımlamak için kullanılır.
```bash=
curl -X 'POST' \
'https://test-amorphie-workflow.burgan.com.tr/workflow/definition' \
-H 'accept: */*' \
-H 'Language: en-EN' \
-H 'Content-Type: application/json' \
-d '{
"name": "WorkflowIsmi",
"title": [
{
"language": "en-EN",
"label": "English Name"
},
{
"language": "tr-TR",
"label": "English Title"
}
],
"entities": [
{
"name": "render-online-sign-flow",
"isExclusive": true,
"isStateManager": true,
"availableInStatus": [
2
]
}
],
"tags": [
],
"status": 1,
"historyForms": [
{
"language": "tr-TR",
"label": "turkce-gecmis-sablon"
}
],
"recordId": "2374776b-df98-4de2-ab4b-5b51b33a64f8"
}'
```
* **name:** Workflow'un benzersiz adı.
* **title:** Farklı dillerde workflow başlıkları. Her dil için ayrı bir **label** içerir.
* **entities:** Workflow ile ilişkili varlıklar. Her varlık için **isExclusive**, **isStateManager**, **availableInStatus** gibi özellikler belirlenir.
* **isExclusive**: Bu entity'nin tek bir workflow'a özel olup olmadığını belirtir.
* **isStateManager**: Entity'nin durum yönetiminde etkili olup olmadığını gösterir.
* **availableInStatus**: Varlığın hangi durumlarda kullanılabileceğini gösteren sayısal değerler. Örneğin, 2 yeni kayıt için kullanılır.
* **tags**: Workflow'u etiketlemek için kullanılır. Etiketler, workflow'u kategorize etmeye yardımcı olur.
* **status**: Workflow'un aktif (1) veya pasif (0) durumunu gösterir.
* **historyForms**: Backoffice uygulamasında kullanılan geçmiş form şablonları. Her dil için ayrı bir label içerir.
* **recordId**: Workflow'un benzersiz kimlik bilgisi.
### State Tanımı Ayrıntıları
#### cURL Komutu:
Bu komut, belirli bir workflow içindeki bir state'i tanımlamak için kullanılır.
```bash=
curl -X POST \
'https://test-amorphie-workflow.burgan.com.tr/workflow/definition/test-workflow-name/state?Language=en-EN' \
--header 'Accept: */*' \
--header 'User-Agent: Thunder Client (https://www.thunderclient.com)' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "State-Name",
"title": {
"language": "en-EN",
"label": "State Title"
},
"baseStatus": 2,
"type": 500,
"mfaType":1,
"subWorkflowName" :"sub-flow-name"
"transitions": [
{
"name": "contract-start-StartContract",
"title": {
"language": "en-EN",
"label": "Contract-Start"
},
"toState": "contract-check-sub-state",
"typeofUi": 1,
"page": {
"operation": 1,
"type": 1,
"timeout": 3000
},
"message":"StartContract",
"gateway":"workflow-zeebe-command",
"fromState": "contract-check-start-state",
"buttonType": 1
}
],
"ispublicForm": true,
"publicForms": [
{
"typeofUi": 1,
"forms": [
{
"language": "en-EN",
"label": "StartContract-ui"
}
]
}
]
}'
```
* **name**: State'in benzersiz adı.
* **title**: Farklı dillerde state başlıkları. Her dil için ayrı bir **label** içerir.
* **baseStatus**: State'in başlangıç durumunu gösteren sayısal değerler. Örnek değerler:
* 2: Yeni (New)
* 4: Aktif (Active)
* 8: İşlemde (InProgress)
* 16: Pasif (Passive)
* 32: Tamamlanmış (Completed)
* 256: Akışta Kilitli (LockedInFlow)
* 30: Tümü (All)
* **type**: State türü. Örneğin 500 subworkflow türüne işaret eder.
* **mfaType**: Erişim türü (0 Public, 1 Private).
* **subWorkflowName**: State bir subworkflow başlatıyorsa, bu subworkflow'un adı.
* **transitions**: State içindeki geçişleri tanımlar. Her geçiş için hedef state (toState), UI türü (typeofUi), sayfa bilgileri (page), mesajlar (message) ve diğer özellikler tanımlanır.
* **ispublicForm ve publicForms**: State'in dışarıya açık form bilgileri.
### SubWorkflow Tanımı ve Önemi
Subworkflowlar, ana iş akışının bir parçası olarak çalışan, ancak belirli koşullar altında başlatılan bağımsız iş akışlarıdır. **subWorkflowName** alanı ile belirtilir ve ana workflow içerisinde belirli bir state tarafından başlatılır. Bu, iş akışlarının daha modüler ve yönetilebilir olmasını sağlar, ayrıca karmaşıklığı azaltır ve yeniden kullanılabilirliği artırır.
## Örnek Workflow tanımlama ve açıklamaları
Örnek Workflow Tanımı curl
```bash=
curl -X 'POST' \
'https://test-amorphie-workflow.burgan.com.tr/workflow/definition' \
-H 'accept: */*' \
-H 'Language: en-EN' \
-H 'Content-Type: application/json' \
-d '{
"name": "WorkflowIsmi",
"title": [
{
"language": "en-EN",
"label": "English Name"
},
{
"language": "tr-TR",
"label": "English Title"
}
],
"entities": [
{
"name": "render-online-sign-flow",
"isExclusive": true,
"isStateManager": true,
"availableInStatus": [
2
]
}
],
"tags": [
],
"status": 1,
"historyForms": [
{
"language": "tr-TR",
"label": "turkce-gecmis-sablon"
}
],
"recordId": "2374776b-df98-4de2-ab4b-5b51b33a64f8"
}'
```
* Name => Workflow ismini belirtir
* Title => Workflow un title bilgisini dile göre belirleyen alandır
* Language=> Workflowun title in dil bilgisini içerir
* Label=> Workflowun başlık bilgisini dile göre belirtir
* entities=> Workflow un entity bilgilerini içerir Örnek vermek gerekirse user entity sinin Hem user-register flowu hemde
user-reset-password flowu olabilir
availableInStatus değerinin alabileceği değerler
* New = 2,
* Active = 4,
* InProgress = 8,
* Passive = 16,
* Completed = 32,
* LockedInFlow = 256,
* All = 30
Örnek vermek gerekirse user-register flowunda user yeni tanımlacağı için 2 değerini alır
isStateManager=> Bu değer true olduğunda Kullanıcının durumuna bağlı bir şekilde flowun ilerleyeceği belli olur
Genellikle bu değeri true olarak vermenizi bekliyoruz
False olduğu durumlar Örnek => State durumu user-active deki veya user-update-approval aşamasındaki gibi tüm durumlarda
user-reset-password flowunu başlatmak istiyorsak kullanılır
Not: Bu durumda user-reset--password a user entitysinden bağımsız bir entity tanımlanması daha uygun olur
Tags=> amorphie-tag projesi içerisinde bulunan tag leri Workflowları taglemek amacıyla eklenebilir
status=>
* 1=> Active
* 0=>Deactive
Workflowun aktif deaktif durumunu belirtir Deactive bir Flowu tetikleyemezsiniz
HistoryForms
Backoffice uygulamasında bir flowun daha önceki aşamasını göstermek amacıyla TemplateEngine uygulamasına eklenmiş şablonu dile göre eklenmiş halidir
RecordId => Workflowun unic Guid olan bilgisini içerir. Bu Guid ye göre Tüm state bilgilerini alınan end point sorgulanabilir.
```bash=
curl -X POST \
'https://test-amorphie-workflow.burgan.com.tr/workflow/definition/test-workflow-name/state?Language=en-EN' \
--header 'Accept: */*' \
--header 'User-Agent: Thunder Client (https://www.thunderclient.com)' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "State-Name",
"title": {
"language": "en-EN",
"label": "State Title"
},
"baseStatus": 2,
"type": 500,
"mfaType":1,
"subWorkflowName" :"sub-flow-name"
"transitions": [
{
"name": "contract-start-StartContract",
"title": {
"language": "en-EN",
"label": "Contract-Start"
},
"toState": "contract-check-sub-state",
"typeofUi": 1,
"page": {
"operation": 1,
"type": 1,
"timeout": 3000
},
"message":"StartContract",
"gateway":"workflow-zeebe-command",
"fromState": "contract-check-start-state",
"buttonType": 1
}
],
"ispublicForm": true,
"publicForms": [
{
"typeofUi": 1,
"forms": [
{
"language": "en-EN",
"label": "StartContract-ui"
}
]
}
]
}'
```
Örnek Url de belirtilen test-workflow-name Workflowu kaydederken verilen Name alanı olmalıdır.
Name=> State in unic ismini belirtir
Title => State in title bilgisini dile göre belirleyen alandır
* Language=> State title in dil bilgisini içerir
* Label=> State başlık bilgisini dile göre belirtir
Örnek Kullanım Yeri Backoffice de Flow Başlatıldığında Açılan Pop up ın başlık kısımda State Title bilgisini içerir
baseStatus=> değerinin alabileceği değerler
* New = 2,
* Active = 4,
* InProgress = 8,
* Passive = 16,
* Completed = 32,
* LockedInFlow = 256,
* All = 30
Örnek vermek gerekirse User-register state in user hala kaydolmadığı için 2 durumundadır user-active state inde 4 durumundadır
type => değerinin alabileceği değerler
* Standart = 0,
* Start = 100,
* Finish = 200,
* Fail = 400,
* SubWorkflow = 500
Start type a ait state in transitionları ilk olarak başlatılır
Eğer flow daha önceden hiç başlatılmadı ise sadece start type ait state in transitionları başlatılabilir
Standart type ına ait stateler start la finish arasındaki tüm stateler için kullanılır
Finish type ise flowun bittiğini belirtmek amacıyla kullanılır end state ler için kullanılır
Fail type ı olan stateler eğer bir hata durumuna düşecek ise bu state ile belirtilir
Standart ve Start adımına ait statelerde; Instance hangi state de ise o state e ait transitionlar çalıştırılabilir ama fail state giden transition instance hangi state de olursa olsun çalışacaktır.
SubWorkflow state ise eğer o durumda bir subworkflow çalışacaksa kullanılır. Bu adımda subWorkflowName property sinin de doldurulması beklenir.
subWorkflowName =>o state de çalışacak workflow un name bilgisi girilmesi gerekmektedir.
Böylece bu state durumuna gelen instance ların available transitionlar listesinde subworkflowun start state ine ait
transitionlar listelenecektir.
mfaType=>alabileceği değerler
0 =>Public
1=> Private
Login veya register gibi token gerektirmeyen flowların statelerinde public mfaType kullanılmaktadır.
Diğer tüm stateler için private mfaType değeri kullanılmaktadır.
transitions=>
İlgili state de çalışacak tüm transitionlar bu arrayde listelenmelidir.
Not:> İlgili state güncellenirken sadece güncellenecek veya o state e eklenecek transitionlar verilebilir
Güncellenirken girilmeyen transitionlar silinmez.
transitions.name => ilgili transition ın ismidir.
Not:>İlgili flow tetiklenirken bu property ait değer transitionName olarak verilmelidir.
transitions.title => Transition ın title bilgisini dile göre belirleyen alandır
* Language=> Transition title ın dil bilgisini içerir
* Label=> Transition başlık bilgisini dile göre belirtir
Örnek Kullanım Yeri Backoffice de Flow Başlatıldığında İlgili Flowu tetikleyen buttonun Title bilgisini buradan alır
toState=> Transition tetiklediğinde ilgili stateden hangi state e gideceği bilgisi verilir.
Not:> Bu state daha önceden tanımlı olmalıdır. State tanımlamaları yapılırken bu yüzden end state inden başlayarak tanımla yapılması
tavsiye edilir. Aksi takdirde toState de tanımlama yapıldıktan sonra tekrar ilgili state güncellenmesi gerekir
transitions.typeofUi=>alabileceği değerler
* Formio = 1,
* PageUrl = 2,
* Html = 4,
* FlutterWidget = 8
Ui iki farklı şekilde verilebilir.
Transitionlara ui atama
State lere ui atama
İki farklı şekilde verilmesinin sebebi Örneğin Bir kayır sürecinde flow için User onay aşaması için tanımlanan user-approval state inde user-approve ve user-reject transitionları olsun. Bu durumda hem user-approve hem user-reject için ayrıca bir ui tanımlamasına gerek yok Bir farklı durum olarak user-active state indeki bir instance için çalıştırabileceği transitionlar user-update ve user-deactive Bu durumda state e ui eklemek mantıklı olmuyor transition a ui eklemek gerekiyor Update in ui ı farklı olmalı deactive in ui ı farklı olmalı transitions içerisinde tanımlanan typeofUi transitiona atanan ui ın hangi type da olduğunu belirtir
transitions.page => ilgili transition çalıştıktan sonra gideceği sayfanın bilgilerini içerir
page.operation => alabileceği değerler
* Open=> 1
* Close=>2
* Stay=>4
operation ilgili sayfayı açacağını kapatacağını yada o sayfada kalacağı bilgisini içerir
page.type=>alabileceği değerler
* PushReplacement = 1,
* PopUp = 2,
* PopUntil = 4,
* PushAsRoot = 8,
* Push = 16,
* BottomSheet = 32
pop-until: Belirli bir sayfaya gitmek için, mevcut sayfadan başlayarak belirtilen sayfaya kadar olan tüm geçişleri geri alır.
push: Belirtilen sayfayı açar ve eğer bu sayfa zaten geçmişte varsa, bu sayfayı tekrar açar.
push-replacement: Belirtilen sayfayı açar ve mevcut sayfayı bu yeni sayfa ile değiştirir.
push-as-root: Belirtilen sayfayı açar ve geçmişteki tüm sayfaları temizleyerek yeni sayfayı temel sayfa olarak ekler.
popup: Belirtilen sayfayı bir popup (açılır pencere) olarak görüntüler.
bottom-sheet: Belirtilen sayfayı bir alt tabaka modal penceresinde (bottom sheet) görüntüler.
page.pageRoute=> => Sayfanın isminin dile göre tutultuduğu alandır
* Language=> Sayfanın isminin dil bilgisini içerir
* Label=> Sayfanın ismini dile göre belirtir
typeofUi bilgisi 8 yani FlutterWidget ise bu alan tanımlanması beklenmektedir.
transitions.form=> İlgili transition ın ui bilgisininn tutulduğu template bilgisini içerir
Eğer ui transitionda değil state de tutulacaksa tanımlanmasına gerek yoktur.
transitions.form.typeofUi=> alabileceği değerler
* Formio = 1,
* PageUrl = 2,
* Html = 4,
* FlutterWidget = 8
Template in hangi tür ui içerdiği bilgisini tutmaktadır.
transitions.form.navigationType=>ui nasıl açılacağı bilgisini tutar
alabileceği değerler
* PushReplacement = 1,
* PopUp = 2,
* PopUntil = 4,
* PushAsRoot = 8,
* Push = 16,
* BottomSheet = 32
transitions.form.forms=>Template in isminin dile göre tutultuduğu alandır
* Language=> Template in isminin dil bilgisini içerir
* Label=> Template in ismini dile göre belirtir Not:> Buradaki bilgi Template Engine de tutulan json template in name alanı olmalıdır.
transitions.fromState => en üstte tanımlanan state in name alanı ile aynı olmalıdır.
transitions.gateway=> Zeebenin gateway adresini içerir
Hem Prod hem de test ortamı için aksi belirtilmediği sürece "workflow-zeebe-command" değeri girilmelidir.
transitions.message=>İlgili transition çalıştığında zeebede bu transitiona eşdeğer olan message event in message kısmı girilmelidir.
transitions.buttonType=> İlgili transition a ait butonun type bilgisini içerir alabileceği değerler =>
* Forward=>1
* Back=>2
* Cancel=>4
ispublicForm=> Eğer ui bilgisi state de tutulacaksa bu değer true olmalıdır.
publicForms=> State de tutulacak ui bilgisini içermektedir.
publicForms.typeofUi=> =>alabileceği değerler
* Formio = 1,
* PageUrl = 2,
* Html = 4,
* FlutterWidget = 8
Template in hangi tür ui içerdiği bilgisini tutmaktadır.
publicForms.navigationType=>ui nasıl açılacağı bilgisini tutar
alabileceği değerler
* PushReplacement = 1,
* PopUp = 2,
* PopUntil = 4,
* PushAsRoot = 8,
* Push = 16,
* BottomSheet = 32
publicForms.forms=>Template in isminin dile göre tutultuduğu alandır
* Language=> Template in isminin dil bilgisini içerir.
* Label=> Template in ismini dile göre belirtir
Not:> Buradaki bilgi Template Engine de tutulan json template in name alanı olmalıdır.
## Subworkflow Hata Yönetimi
Hata (ThrownError) : State Manager ve Http Worker bileşenlerinde beklenmedik durumlar için flow'da handle edilmek üzere ThrowError command ile hata fırlatılmaktadır.
Bu hatalar ilgili process'e yada elemente bağlanan "Error Boundary Event"lar ile yakalanabilmektedir.
Hata yakalandıktan sonra flow hatanın yakalandığı yerden akışına devam eder.
Flowlarda subprocess çağrılan senaryolarda hata yönetimi için dikkat edilmesi gereken bazı hususlar bulunmaktadır.
Subprocess'de oluşan bir hata, üst flowlara çıkarılmalıdır.
Bunun için 2 yöntem bulunmaktadır.
2 yöntemi de içeren örnek flow görseldeki gibidir.

1) Subprocess olarak tasarlanan flowlara hata yakalama mekanizması eklenmemelidir. Böylece akışta herhangi bir yerde fırlatılan hata
ana processdeki "Error Boundary Event" ile yakalanır.
Görselde ki **subworkflow**'da herhangi bir adımda hata fırlatılması durumunda,
bu hata mainflow'daki "Error Boundary Event" tarafından yakalanacaktır.

2) Subprocess'te "Error Boundary Event" bulunması gerekiyorsa
(Bu subporcess başka bir senaryonun mainprocess'i olabileceği için akışı tasarlayan buraya "Error Boundary Event" eklemiş olabilir)
Subprocessin çağrıldığı "Call Activity" den hemen sonra bu akışın tamamlanma durumunu kontrol etmek için görseldeki gibi "Exclusive Gateway"
eklenmelidir.
Bu gatewayde Subworkflow'da hata oluştuysa **mainworkflow**'un da hataya düşürülmesi için kontrole "Error End Event" elementi eklenir.
Böylece **subworkflow**'da handle edilmiş olan hata, main processde de "Error Boundary Event"a düşürülmesi sağlanır.

Burda **mainworkflow**'u yakından inceleyecek olursak, "**Call Activity**"den hemen sonra
eklenen gatewaye eklediğimiz "**Control Flow**"lardan ilki yani default olan akışımızı devam ettirmek istediğimiz noktaya; ikincisi ise ThrownError variable'ın oluşmuş olması durumuna göre "Error End Event"a dallanmaktadır.

## Flow Not Eklenmesi
Flow tanımlarının içerisine ilgili flowa özgü, "buttonType":8 olan,
toState ve fromState validasyon kuralları gereği dolu olması gereken ancak ne olduğu önemsiz olan aşağıdakine benzer bir transition eklenir.
- **Örnek Transition:**
```json
{
"name": "wf-add-note-tx",
"title": {
"language": "en-EN",
"label": ""
},
"toState": "wf-dummy-approval",
"page": {
"operation": 1,
"type": 2,
"timeout": 3000
},
"fromState": "wf-dummy-start",
"message": "wf-add-note-tx",
"gateway": "workflow-zeebe-command",
"buttonType": 8
}
```
İlgili flowa görseldeki gibi
(Message Boundar Event(Non Interrupting)) elementi processe iliştilir.

Böylece flowda herhangi bir adımda note ekleme transitionı tetiklenebilir.
Request body aşağıdaki istekte belirtildiği gibi olmalıdır.
```
curl --location 'https://test-amorphie-workflow.burgan.com.tr/workflow/instance/a1000000-5717-4562-b3fc-2d963f66c000/transition/wf-add-note-tx' \
--header 'User: 3fa85f64-5717-4562-b3fc-2c963f66afa6' \
--header 'Behalf-Of-User: 3fa85f64-5717-4562-b3fc-2c963f66afa6' \
--header 'X-Device-Id: a0000f64-5717-0000-b3fc-2d963f660001' \
--header 'X-Token-Id: a0000f64-5717-0000-b3fc-2d963f660001' \
--header 'Content-Type: application/json' \
--header 'Cookie: a58e47c06cc3b2a29f02461f20391d49=b523be6f3cdb5bc3fde395fb4e3a4eaa' \
--data '{
"note": "test note 7"
}'
```
Başarılı istek sonucunda ilgili not o anki aktif transitionun TRX ile başlayan variable'ın **additionalData** kısmına note keyi ile array formatında UserId ve tarih bilgisi ile beraber eklenir.
## BPMN ile Süreç Tasarımı:
....