---
# System prepended metadata

title: 'HOW TO : Notification'
tags: [Tahir Doğan, howto, notification]

---

# Notification
###### tags:`Tahir Doğan`,`notification`,`howto`

Uygulamalarin bildirimlerini iletmek için kullanacağı altyapı hizmete açılmıştır.
Bundan sonraki süreçte bu altyapı ile kullanıcılarla işlem temelinde iletişim sağlanacaktır. 

Bu belge altyapının sunduğu fonksiyonları ve bun fonksiyonların nasıl kullanılacağı ile ilgili temel bilgileri içerir.

## Fonksiyonlar
* Müşterilerin bildirim ayarlarını tutar.
    * Her bir bildirim tipi için farklı telefon numarası ve eposta adresi tanımlanabilir. *vNext*
    * Bildirimler için filtreler uygulanabilir. "X nolu hesaptan 300 TL ve üzerinde para çıkışında" gibi. *vNext*
* Veritabanı üzerinden CDC ile bildirime konu eylem gerçekleştiği anda bildirim çalışır.
* Bildirim metinleri dEngage şablonlar halinde üzerinde tasarlanabilir.
    *  Veri zenginleştirmesi ile şablonlarda kullanılmak üzere ek veriler sisteme dahil edilebilir.


## Notification Topolojisi


```plantuml
@startuml

database "Veritabanı" {
  folder "Temel Bankacılık" {
    [Gelen EFT] as dbEFT
  }
}

node "Qlik Replicate" {
    interface "Gelen EFT" as topic
    dbEFT ==> topic
}

package "Notification" {
  
  topic ==> [Worker]   
  [Worker] *-0)-- [Müşteri] : Zenginleştirici
  [Worker] *-0)-- [Hesap] : Zenginleştirici
  [Notification Yönetim Servisleri] as admin   
  [Worker] <--> admin
}


node "Messasing Gateway" {
    interface "SMS & Mail & Push " as sender 
    [Worker] ==> sender
}


node "dEngage" {
    interface "SMS" as sms 
    sender ==> sms
    interface "e-Mail" as email 
    sender ==> email
    interface "Push Notification" as push 
    sender ==> push
}

@enduml
```

## İşleyiş

### 1- Bildirim Kaynağının CDC ile Aktarımı.

:::info
**Sorumlu**: Bildirim Kaynağı Ürün Sorumlusu
**Operatör**: İş Zekası Birimi
:::

Sorumlu bildirim için kaynak olacak tabloyu belirler. Belirlediği tabloda bildirimde kullanılacak alanları ve filtleri belirleyerek operatör birimden CDC ile Kafka topiğine akmasını sağlar.

Özetle Sorumlu aşağıdaki gibi bir veri seti ile Operatörden talepte bulunur. 

| Parametre | Değeri | 
| -------- | -------- | 
| Veritabanı Adı    | AresWorkflow | 
| Tablo Adı    | Workflow Instance | 
| Alanlar    | * | 
| Filtre    | isCompleted == false | 


### 2- dEngage Templatelerinin Oluşturulması.

:::info
**Sorumlu**: Bildirim Kaynağı Ürün Sorumlusu
**Operatör**: Bildirim Kaynağı Ürün Sorumlusu
:::

Bildirimde kullanılacak sms, push ve eposta içeriklerinin tanımlanması dEngage üzerinde yapılır. Tanımlanan her bir içerik için dEngage tarafından bir id atanır. Bu Id'ler Notification sisteminde kaynak tanımlarında kullanılır.
:::danger
Bu sablonlarin on ve burgan ayrimi messaging gateway uzerinde otomatik yapilabiliyor mu?
:::

### 3- Source Kaydı

Bildirimlerde kullanılmak amacıyla bildirim sistemine kaynak kaydı 
yapılır.

Her bir kaynak kaydının içermesi gereken asgari veriler;
* **Adı** Hem ingilizce hem türkçe olmak üzere. 
* **Parametler** Müşteri bildirimi açtığında belirleyebileceği parametreleri tanımlamak için kullanılır. Opsiyonlar: *TextContains, TextMatch, Boolean, LessThan, GreaterThan, Equal*
* **Görünüm** İlgili bildirim bildirimler ekranında müşteriye gösterilecek mi?  Ayar değişikliğine izin verilecek mi? gibi görünüm durum bilgisidir.
* **Kaynak** Bildirim gönderiminin tetikleneceği Kafka Topic bilgisidir.
* **Client Id JsonPath** Müşteri bilgisinin bulunduğu veri içerisindeki pozisyon. Client Id zenginleştirme veri kümesinde de bulunabilir.
* **Enrichements** Zenginleştirme için çağrılacak servislerin listesini ve parametre bilgisidir.
* **References** Gönderim yapacak servis referansları


:::danger
Zenginleştirme Servisleri modelde bulunmuyor?

Böyle bir alan olmalı sanki?


```csharp=
 public class Source
    {
        ...
        public List<Enrichment> Enrichments{ get; set; }
        
        public class Enrichment
        {
            public string Node { get; set; }
            public string? RequiredNode { get; set; }
            public Uri Url { get; set; }
        }
        ...
    }
```

Burada **Node** dönen değerin data içine attach edileceği root node ismi bilgisidir. 

**RequiredNode** ise Url içinde parametre olarak kullanılacak veri başka bir zenginleştirmeye ihtiyaç duyuyorsa o ihtiyaç duyulan zenginleştirme Node tanımlanır.

**Url** ise zenginleştirme için çağrılacak servisi tanımlar. Serviş her zaman GET Rest servisidir. Url içinde templating yada interpolation gibi yaklaşım kullanılarak json veriler kullanılabilir.

:::

### 4- Dağıtım
:::info
**Sorumlu**: Bildirim Kaynağı Ürün Sorumlusu
**Operatör**: Entegrasyon
:::

Kayıt tamamlandıktan sonra eğer iş varolan Reminder uygulamasından gönderim yapıyorsa disable edilmesi ve yeni iş podlarının ayağa kaldırılması yapılır.



# Notification izin aktarım süreci

Notification izin aktarım süreci, müşteri verilerinde meydana gelen değişiklikleri algılayan bir sistemdir. Bu süreçte, Qlik tarafından yapılan değişiklikler Kafka kuyruğuna yazılır ve NotificationWorker tarafından yakalanır. Müşteri numarası parse edildikten sonra NotificationServisine gönderilir ve müşteriye ait verilerin kayıtlarına bakılır. Eğer müşteri kaydı varsa, müşteri bilgileri izinleriyle birlikte Workerdan geri döndürülür ve Müşteri izinlerine göre, sms, mail veya push gönderimi Messaging Gateway aracılığıyla yapılır. Eğer müşteri kaydı yoksa, CustomerApi servisine müşteri numarası gönderilir ve kontrol sağlanır. Eğer müşteri kaydı varsa, müşteri bilgileri ile birlikte Workerdan geri döndürülür ve Müşteri izinlerine göre, sms, mail veya push gönderimi Messaging Gateway aracılığıyla yapılır. Eğer müşteri kaydı yoksa, süreç sonlanır. Bu süreç, müşteri bilgilerinin güncellenmesi ve izinlerinin yönetimi için bir mekanizma sağlar.

```plantuml
@startuml
start
:Değişiklikler Qlik tarafından algılanıp kafka topic’e yazılır;
:Kafka kuyruğunda bulunan kayıt NotificationWorker tarafından yakalanır;
:Kayıt içerisinde bulunan müşteri numarası parse edilir.;
:Alınan müşteri numarası NotificationServisine gönderilir;
:Notification servisinde gelen müşteri numarasına göre kayıtlara bakılır.;
if (Bu müşteriye ait bir kayıt var mı?) then (evet)
    :Müşteri bilgileri izinleri ile birlikte workera döner.;
else (hayır)
    :CustomerApi servisine müşteri numarası gönderilir ve kontrol sağlanır;
    if (Müşteri var mı?) then (evet)
        :Müşteri bilgileri ile dönüş yapılır.;
        if (Müşteriye ait izinler var mı?) then (evet)
            :Müşteri izinlerine bakılarak sms,mail,push gönderimi messaging gateway üzerinden yapılır;
        else (hayır)
            :Tüm izinleri aktif olacak şekilde oluşturulur. Müşteriye ait bilgiler yeni reminder veritabanına yazılır;
            :Müşteri izinlerine bakılarak sms,mail,push gönderimi messaging gateway üzerinden yapılır;
        endif
    else (hayır)
        stop
    endif
endif
stop
@enduml
```
| Adım | Açıklama |
|------|----------|
| 1    | Değişiklikler Qlik tarafından algılanıp kafka topic’e yazılır |
| 2    | Kafka kuyruğunda bulunan kayıt NotificationWorker tarafından yakalanır |
| 3    | Kayıt içerisinde bulunan müşteri numarası parse edilir |
| 4    | Alınan müşteri numarası NotificationServisine gönderilir |
| 5    | Notification servisinde gelen müşteri numarasına göre kayıtlara bakılır |
| 6    | İlk önce yeni veritabanına bakılır |
| 7    | Bu müşteriye ait bir kayıt varsa müşteri bilgileri izinleri ile birlikte workera döner |
| 8    | Eğer yok ise CustomerApi servisine müşteri numarası gönderilir ve kontrol sağlanır |
| 9    | O müşteri var ise müşteri bilgileri ile dönüş yapılır. Eğer müşteri yoksa süreç sonlanır |
| 10   | Müşteri var ise, Müşteriye ait izinler ise eski reminder veritabanındaki DG_REMINDER tablosundan sorgulanır |
| 11   | Eğer yeni bir müşteri ise izinleri yok ise (eski reminder da), tüm izinleri aktif olacak şekilde oluşturulur. Müşteriye ait bilgiler yeni reminder veritabanına  yazılır |
| 12   | Workerdan Notificationa müşteri numarası ile gelen istek müşteri bilgileri ile geri döner |
| 13   | Müşteri izinlerine bakılarak sms,mail,push gönderimi messaging gateway üzerinden yapılır |

## Notification izin güncelleme süreci

Bu süreç, eski (`reminder`) veritabanındaki değişiklikleri (`qlik`) ile izlemeyi ve değişikliklerin bir `kafka` topiğine yazılmasını içerir. Ardından, bir `worker` uygulaması bu topiği dinleyerek, yeni (`reminder`) verileri varsa veritabanında günceller. Bu süreç, reminderın güncel tutulmasını ve kullanıcılara daha doğru bildirimler gönderilmesini sağlamak için tasarlanmıştır.



```plantuml

@startuml
start
:DG_Reminder tablosunda değişiklik gerçekleşir;
if (Değişiklik Algılandı mı? (Qlik)) then (evet)
  :İlgili Kafka topiğine yazılır;
  :Worker topic dinlemesi yapılır;
  if (Kayıt var mı?) then (evet)
    :Yeni reminderdaki bilgiler güncellenir;
  endif
else (hayır)
  stop
endif
stop
@enduml


```

| Adım | Açıklama |
|------|----------|
| 1 | Eski reminder `DG_Reminder` tablosunda herhangi bir değişiklik olduğunda değişiklik `qlik` tarafından algılanır. |
| 2 | İlgili `kafka` topiğine yazılır. |
| 3 | `Worker` topic dinlemesi yapılır. |
| 4 | Kayıt var ise yeni `reminder`daki bilgileri günceller. |


## İzin Sunma ve Güncelleme (Revamp)

### İzinlerin gösterimi

#### Eski reminder izinleri gösterme


**Örnek Response**
```json=
{
    "showWithoutLogin": false,
    "reminders": [
        {
            "reminderType": "accountMoneyEntry",
            "reminderDescription": "Hesabıma para geldiğinde",
            "sms": true,
            "email": false,
            "mobileNotification": true,
            "amount": 0,
            "hasAmountRestriction": false
        },
        {
            "reminderType": "accountMoneyExit",
            "reminderDescription": "Hesabımdan para çıkışı olduğunda",
            "sms": true,
            "email": false,
            "mobileNotification": true,
            "amount": 0,
            "hasAmountRestriction": false
        },
        {
            "reminderType": "checkingAccountUpperLimitExceeded",
            "reminderDescription": "Vadesiz hesap bakiyesi üst limite çıktığında",
            "sms": true,
            "email": false,
            "mobileNotification": true,
            "amount": 100,
            "hasAmountRestriction": true
        },
        {
            "reminderType": "checkingAccountLowerLimitExceeded",
            "reminderDescription": "Vadesiz hesap bakiyesi alt limite düştüğünde",
            "sms": true,
            "email": false,
            "mobileNotification": true,
            "amount": 100,
            "hasAmountRestriction": true
        },
        {
            "reminderType": "riskyFutureTransfersAndPayments",
            "reminderDescription": "Bakiye yetersizliği nedeniyle ödenmeme riski taşıyan ileri tarihli para transferleri ve ödemelerde",
            "sms": false,
            "email": true,
            "mobileNotification": true,
            "amount": 0,
            "hasAmountRestriction": false
        },
        {
            "reminderType": "savingAccountDueDateReturn",
            "reminderDescription": "Vadeli mevduat hesap dönüşü",
            "sms": false,
            "email": true,
            "mobileNotification": true,
            "amount": 0,
            "hasAmountRestriction": false
        },
        {
            "reminderType": "cardRefund",
            "reminderDescription": "Banka Kartı İade Bildirimi",
            "sms": true,
            "email": false,
            "mobileNotification": true,
            "amount": 0,
            "hasAmountRestriction": false
        },
        {
            "reminderType": "cardReccurring",
            "reminderDescription": "Banka Kartı Talimatlı Ödeme",
            "sms": true,
            "email": false,
            "mobileNotification": true,
            "amount": 0,
            "hasAmountRestriction": false
        }
    ]
}
```

#### Notification üzerinden izin gösterimi

Revamp gösterimi için mock data veririz diye konuşuldu. Netleştirmek lazım.

**Not :** Source üzerinde parent oluşturup, gerekirse alt kırılımları gösteriliyor olacak

### İzin güncelleme

#### Eski reminder üzerinde izin güncelleme

Servis veri tabanında ilgili **SP([REM].[DG_REMINDER_INSERT])** ile izim güncellemesi gerçekleştiriyor. SP ile İzin güncellemesi gerçekleştiğinde tüm izinler silinip yeniden ekleniyor.

#### Notification izin güncelleme

??? Burada ilk etapta source parent'a göre alt kırılım izinler güncellenebilir. (İzin kontrolü olmayan gönderimler dışında)

Notification'da tanımlı senaryolar güncellenebilir. Ancak eski reminder da devam eden senaryolar için güncelleme nasıl olmalı ? 


### Ek geliştirmeler

* Müşteri hesapları özelinde bildirim için farklı iletişim kanalı tanımlayabilecek
    * Senaryo özelinde bu özellik aktif edilebilecek
        * Gosterme kullaniciya
        * Goster ama degisitirmesine izin verme
        * goster ve izini degisitirmesine izin ver
        * parametresi varsa parametreleride degisti9rmesine izin ver
        * eposta ve telefon belirleyebilsin ve degistirebilsin
    
```csharp=
public enum SourceDisplayType
    {
        NotDisplay(always send notification) = 1, //Kullanıcıya gösterilmez. Source UI da parantez içindeki gibi gözükmelidir.
        Display(always send notification )= 2, // Gösterilir ama değiştirilemez.Source UI da parantez içindeki gibi gözükmelidir.
        DisplaySetSwitch = 3, //Göster ve değiştirmesine izin ver
        DisplayAndSetSwitchParameters = 4, //Göster ve Parametresi varsa değiştirmesine izin ver
        DisplayAndSetSwitchParametersChannelsInfo = 5, //eposta ve telefon belirleyebilsin ve değiştirebilsin.Parametre de değiştirebilsin.
    }
```

* İzinsiz gönderimler için **Inheritance** kavrami kullanılabilir diye konuşuldu, netleştirmek lazım

```csharp=
public enum InheritanceType
    {
        NotInherit = 0, // Durumu sadece kendinde guncellenir.
        Inherit = 1, // Durumu parent kayittan alarak guncellenir.
       
    }
    
```


```csharp=
[Flags]
public enum AlwaysSendType 
    {
        None = 0,
        Sms = 1, 
        Mail = 2,  
        Push = 4,  .
    }
```
* Source ekranında displaytype altına sms, mail ve push checkboxlar olacak. İşaretlenme durumuna göre toplamları source tablosundaki AlwaysSend alanında tutulacak.

* Source'da retention alanı saniye tutulup, **rententionDeltaJsonPath** ile kafkadan alınacak time alanı dinamik tutulabilecek.
* SMS gönderilmeyecek zaman aralığı şu an Qlick ile task durdurup başlatarak çözülecek
    * Future Backlog Item: Cron job ile yönetilmesi konuşuldu.
* ProcessItemIdPath olarak belirtilen alan **ProcessItemIdJsonPath** olarak gösterilmeli
* **Future Backlog Item:** TokenId kaydı consumer içerisinde tanımlanmalı.
* Grouplayacak source tanımları Source olarak tanımlanacak ve tum gercek sourcelar parentId ile gruba bağlanacak. Bu kavrama eski reminder gonderimleri dahil.
* POST Amoprhie Workflow ile geliştirilecek.


