# API Gateway - Approval
###### tags: `ready`
Organizasyon tarafından geliştirilen, müşteriler ve çalışanlar tarafından kullanılan servislere gateway üzerinde onaylama (**Approval**) ve imzalama (**Transaction Signing - Dynamic Linking**) yetkiliğini getiren altyapıdır.
## Temel Hedefler
- Her bir servis için onay akışı tanımlanabilmesi
- Onay akışı içeirisinde insan etkileşimi (Kuyruk veye Kişi) olabilmesi
- Onay akışı içerisinde OTP mekanizmasının (SMS veya Push Notification) olabilmesi
- E-Posta ile onay akışının olması.
- Onay akışı içerisinde IVN mekanizmasının olabilmesi
- Kuyrukta bekleyen işlemler kullanıcı bazında takip edilebilmesi.
- Kurukta bekleyen işlemlere ait verileri gösterebilmek için HTML template tanımının yapılabilmesi
- Kuyruktaki işleri izleme için gerekli arayüzlerin tüm kullanıcılar sunulması
- Banka içi işlerin onayı için Mobil veya web bankacılık uygulamasının kullanılabilmesi
## Akış Tanımları
Akış tanımları temelde akışın hangi servise (*for*) uygulanacağını, ve uygulanacak olan akış adımlarını (*pipeline*) tanımlar.
:::warning
Onayı akışı sadece POST, PATCH, PUT ve DELETE komutlarına uygulanabilir. GET komutuna onay akışı tanımı yapılamaz.
:::
## Örnek Tanım ve Kayıt
### Para Transfer Onay Tanımı (Definition)
```json
{
"for": {
"type": "POST",
"service": "/eft/transfer",
"summary-data-template": "lt-eft-transaction",
"full-data-template": "pt-eft-transaction",
"time-out": 6000
},
"pipeline": [
```
Her akış **for** alanında temel onay akış bilgilerini içerir.
- **type** alanmı ile http komutu tanımlanır. Alabileceği değerler POST, PATCH, PUT ve DELETE dir.
- **service** alanı ile akışın uygulanacağı servis tanımlanır.
- **summary-data-template** alanı ile bekleyen işlemler ekranında kullanılmak üzere satır oluşturan template bilgisi tanımlanır. Satır içerisinde servis ile ilgili, akış ile ilgili ve servise gönderilen veri ile ilgili bilgiler bulunur.
- **full-data-template** alanı ile dımda kullanıcılara gösterilecek verinin render dileceği template tanımını içerir.
- **timeout** akışın ne kadar sürede olumsuz bir şekilde tamamlanacağını belirtmektedir. Timeout saniye birimindedir.
Örneğimnizde EFT transfer servisi **type** ve **service** alanlarına tanımlanmış durumdadır.
Para transfer süreci için tamamlanma süresi olarak 100 dakika tanımlanmış. Gerekli gösterim için HTML şeklinde ekran template tanımlarıda yapılmış.
```json
{
"order": 1,
"type": "SMS-OTP",
"name": "Müşteri OTP Onayı",
"rule": "! http://burganapi/customer-query/has-registered-mobile-device({{submitter.citizenship-number}})",
"time-out": 600,
"max-retry-count": 3,
"timeout-per-retry": 180,
"approver": "{{submitter.citizenship-number}}",
"approver-security-level": "2FA"
"phone-number": "{{submitter.phone-number}}",
"sms-distribution-list": "dl-sms-otp-validate"
},
```
Her akış adımı **pipeline** içinde tanımlar ve aşağıdaki ortak alanlar bulunur.
- **order** onay akışında sırayı belirler. Onay akış adımları order rakamını baz alarak seri olarak çalışır. Aynı order rakamına sahip adımlar paralel olarak çağrılabilir. Paralel akışlardan birinin tamamlanması ile onay sonlanır.
- **type** adımın tipini belirler. Olası adım tipleri *SMS-OTP, PUSH-OTP, MAIL-OTP, QUEUE, PERSON*
- **time-out** adımda onayın bekleneceği maksimum süreyi saniye cinsinde tanımlar. Eğer tanımlı süre içerisinden adım onay almaz ise otomatik olarak time-out adımına geçer.
- **rule** adımın çalıştırılıp çalıuştırılmaycağına karar vermek için kullanılan opsiyonel bir alandır. Rule içinde *condition service* kullanılır.
:::info
Tüm alanlar için templating engine kullanılabilir.
- Servisi çağırarak onaya veri gönderen kullanıcı : **submitter.***
- Servisi çağırarak onaya gönderilen veri : **data.***
- O an servisi çağıran kullanıcı :**user.***
Template rendering içerisinde submit edilecek veri ile ilişkili pipe geliştirmeleri yapılabilir.
```
{{security.submitter.user.tckn | full-customer-info}} -> Uğur Karataş (665566)
```
:::
SMS-OTP tipinde ek olarak bulunan alanlar;
- **max-retry-count** kullanıcı tarafından talep edilebiliecek otp sayısıdır. "Tekrar Gönder" diyerek kullancı yeni OTP gönderilmesini sağlayabilir.
- **timeout-per-retry** her bir OTP için tanımlı maksimim doğrulama süresi saniye cinsinden verilir.
- **approver** OTP yi kullanarak doğrulama yapabilecek kullanıcı bilgisini içerir.
- **approver-security-level** OTP yi kullanarak doğrulama yapabilecek kullanıcı güvenlik seviyesidir. *None, 1FA, 2FA* olarak seçilebilir.
- **phone-number** OTP mesajının iletileceği telefon numarasını içermektedir.
- **sms-distribution-list**: Sms gönderimi için kullanıcılak kampanya kanalının tanımıdır. İlgili kanala veri geçilerek mesaj iletimi talep edilir.
:::info
**Approver** sadece **approver-security-level** *1FA* veya *2FA* olduğu durumda dikkate alınır.
Approver üç farklı formatta verilebilir.
- **Vatansaşlık numarası:** Kullanıcıdan burada vatandaşlık numarası ile ilişkili token alarak onay vermesi beklenir.
- **e-posta** adresi sadece banka kullanıcıları için sağlanabilir. e-posta adresinden ilgili kulanıcı tarafından onay beklenir.
- **e-posta grubu** tanımı ile eposta grubuna dahil olan herhagi bir kullanıcı tarafından doğrulama beklenmektedir. e-posta grubu sadece Queue tipindeki adımda kullanılabilir.
:::
```json
{
"order": 1,
"type": "PUSH-OTP",
"name": "Müşteri OTP Onayı",
"time-out": 600,
"approver-security-level": "1FA",
"rule": "http://burganapi/customer-query/has-registered-mobile-device({{submitter.citizenship-number}})",
"approver": "{{submitter.citizenship-number}}",
"registered-device": "{{submitter.mobile-device}}",
"push-distribution-list": "dl-push-otp-validate"
},
```
PUSH-OTP tipinde ek olarak bulunan alanlar;
- **registered-device** kullanıcı tarafından mobil bankacılık uygulaması kurulmuş ve uygulama aktive edilmiş cihazının tanımlayıcı kodudur. Mesaj bu cihaz üzerindeki uygulamaya iletilir.
- **push-distribution-list**: Mesaj gönderimi için kullanıcılak kampanya kanalının tanımıdır.
```json
{
"order": 2,
"name": "İlk EFT, Müşteri IVN Onayı",
"type": "IVN",
"time-out": 600,
"max-retry-count": 2,
"timeout-per-retry": 180,
"approver": "{{submitter.citizenship-number}}",
"phone-number": "{{submitter.phone-number}}",
"ivn-message": "first-eft-call",
"rule": "http://burganapi/customer-query/is-first-transfer({{submitter.citizenship-number}}, {{data.target-iban}})"
},
```
IVN tipinde ek olarak bulunan alanlar;
- **ivn-message** Kullanıcıya okunacak mesajın referans kodunun içerir.
```json
{
"order": 3,
"type": "QUEUEQueue",
"name": "Operasyon Kontrol Onayı",
"minimum-approver": 1,
"minimum-rejecter": 1,
"time-out": 14400,
"approvers": [
"ukaratas@burgan.com.tr",
"dijital.operasyon@burgan.com.tr",
"{{ security.submitter.user.tckn }}"
]
}
]
}
```
IVN tipinde ek olarak bulunan alanlar;
- **ivn-message** Kullanıcıya okunacak mesajın referans kodunun içerir.
### Para Transfer Onay Kaydı (Instance)
```json
{
"type": "POST",
"service": "/eft/transfer",
"summary-data-template": "lt-eft-transaction",
"full-data-template": "pt-eft-transaction",
"time-out": 600,
"created-at": "2020-06-14T15:23:00.000Z",
"completed-at": "2020-06-14T15:23:00.000Z",
"status": "approved",
"validation-code": "abbcd5f2-7af7-47ed-a9b2-312dac2a1919",
"data": {
"sourceIban": "TR660010009999901234567890",
"targetIban": "TR320010009999901234567890",
"amount": "5000",
"description": "Alisveris icin odeme"
},
"submitter": {
"citizenship-number": "38552069008",
"phone-number": "00905302896073",
"e-mail": "ukaratas@rocketmail.com",
"mobile-device": "b77a45f2-7af7-47ed-a9b2-312dac2a1919",
"type": "customer"
},
"pipeline": [
{
"order": 1,
"type": "SMS-OTP",
"name": "Müşteri OTP Onayı",
"rule": "!isMobileRegistered()",
"time-out": 600,
"max-retry-count": 3,
"retry-count": 2,
"timeout-per-retry": 180,
"approver": "38552069008",
"phone-number": "00905302896073",
"sms-distribution-list": "dl-sms-otp-validate",
"status": "approved",
"history": [
{
"at": "2020-06-14T15:22:00.000Z",
"action": "rule-in",
"actor": "@system",
"description": " (isMobileRegistered()) is true"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "send-otp",
"actor": "@system",
"description": "OTP 67***7 has been sent to user."
},
{
"at": "2020-06-14T15:25:00.000Z",
"action": "otp-time-out",
"actor": "@system",
"description": "OTP 67***7 has been time out"
},
{
"at": "2020-06-14T15:26:00.000Z",
"action": "resend-otp",
"actor": "38552069008",
"description": "OTP 68***6 has been sent to user."
},
{
"at": "2020-06-14T15:27:00.000Z",
"action": "resend-otp",
"actor": "38552069008",
"description": "OTP 68***6 has been validated."
}
]
},
{
"order": 1,
"type": "PUSH-OTP",
"name": "Müşteri OTP Onayı",
"time-out": 600,
"2FA-required": false,
"rule": "isMobileRegistered()",
"approver": "38552069008",
"registered-device": "b77a45f2-7af7-47ed-a9b2-312dac2a1919",
"push-distribution-list": "dl-push-otp-validate",
"status": "rule-out",
"history": [
{
"at": "2020-06-14T15:25:00.000Z",
"action": "rule-out",
"actor": "@system",
"description": " (isMobileRegistered()) is false"
}
]
},
{
"order": 2,
"name": "İlk EFT, Müşteri IVN Onayı",
"type": "IVN",
"time-out": 600,
"max-retry-count": 2,
"retry-count": 1,
"timeout-per-retry": 180,
"status": "approved",
"approver": "38552069008",
"phone-number": "00905302896073",
"ivn-message": "first-eft-call",
"rule": "isFirstTransfer(data.targetIban)",
"history": [
{
"at": "2020-06-14T15:23:00.000Z",
"action": "rule-in",
"actor": "@system",
"description": " (isFirstTransfer(data.targetIban)) is true"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "call",
"actor": "@system",
"description": "Call started to 00905302896073"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "pick-up",
"actor": "@system",
"description": "IVN started speech"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "approved",
"actor": "38552069008",
"description": "Approved by press 1"
}
]
},
{
"order": 3,
"type": "Queue",
"name": "Operasyon Kontrol Onayı",
"minimum-approver": 1,
"minimum-rejecter": 1,
"assigned-to": "",
"time-out": 14400,
"status": "waiting-order | processing-assigned | processing-not-assigned | approved | rejected | time-out",
"approvers": [
"ukaratas@burgan.com.tr",
"dijital.operasyon@burgan.com.tr",
"38552069007"
],
"history": [
{
"at": "2020-06-14T15:23:00.000Z",
"action": "created",
"actor": "@system",
"description": "Task create to queue"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "assigned",
"actor": "ukaratas@burgan.com.tr(dijital.operasyon@burgan.com.tr)",
"description": "Task assigned to Ugur KARATAS"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "return-queue",
"actor": "ukaratas@burgan.com.tr(dijital.operasyon@burgan.com.tr)",
"description": "Task returned to queue"
},
{
"at": "2020-06-14T15:23:00.000Z",
"action": "assigned",
"actor": "nuca@burgan.com.tr(dijital.operasyon@burgan.com.tr)",
"description": "Task approved by Nurhat UCA"
}
]
}
]
}
```json
## Adım Tipleri
## SMS-OTP
### Tanım Modeli
```json
{
"order": 1,
"type": "SMS-OTP",
"time-out": 600,
"page-template": "sms-otp-validate-template-definition-update-page"
"max-retry-count": 3,
"timeout-per-retry": 180,
"actor": "{{ security.submitter.user.tckn }}",
"phone": "{{ security.submitter.user.phone }}",
"sms-distribution-list": "smsdl-sms-otp-validate",
}
```
Sms Otp adımında temel alanlara ek olarak
**max-retry-count** alanı kullanıcının kaç defa otp tetikleyebileceği bilgisi tanımlanır.
**timeout-per-retry** ile her bir tetiklenen otp için ne kadar süre doğrulama kabul edebileceği tanımlanır.
**actor** onay verecek kullanıcıyı tanımlar. Sadece actor olarak tanımlanmış kişi onay servisini çağrırarak kodu submit edebilir.
:::info
Actor olarak kullanıcı **vatandaşlık numarası**, **domain eposta adresi** ve **domain eposta grubu** tanımlanabilir.
Domain gateway tarafından erişilebilir ve sorgulanabilir olmalıdır.
:::
**phone** o kayıt için mesaj gönderilecek telefon numarası bilgisidir.
**sms-distribution-list** sms kaydının gönderilmesi için kayıt atılacak sms dağıtım listesinin adıdır.
### Yanıt Modeli
Eğer Onay akışında sırası gelen bir adımdaysa yanıt;
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "SMS-OTP",
"retry-count": 1,
"page-template-render":"<p><b>530 2896073</b> nolu telefonunuza kodunuz gonderilmistir</p>"
}
```
Eğer Onay akışında sırası geçmiş ve onaylanmış bir adım ise yanıt;
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "SMS-OTP",
"retry-count": 1,
"page-template-render":"<p><b>530 2896073</b> nolu telefonunuza kodunuz gonderilmistir</p>",
"validated-at":"2020-04-22T05:21:26.557Z"
}
```
Eğer Onay akışında sırası geçmiş ve onaylan**ma**mış bir adım ise yanıt;
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "SMS-OTP",
"retry-count": 1,
"page-template-render":"<p><b>530 2896073</b> nolu telefonunuza kodunuz gonderilmistir</p>",
"timeout-at":"2020-04-22T05:21:26.557Z"
}
```
### Destek Servisleri
#### POST /gateway/approval/sms-otp/validate/{id}
Otp doğrulamak için. Id işlemin tekil anahtarıdır.
```json
Body:
{
"code":"456896"
}
```
Validasyonun başarılı olması sonucunda eğer varsa bir sonraki onay adımı ile ilgili bilgi yoksa işlemi gerçekleştirip işlem ile ilgili bilgi döner.
#### POST /gateway/approval/sms-otp/resend/{id}
Yeni bir OTP talep etmek için kullaılacak servis.
## Adım : E-mail
### Tanım Modeli
```json
{
"order": 0,
"type": "EMAIL",
"time-out": 432000,
"page-template": "mail-validate-template-definition-update-page"
"actor": "{{ security.submitter.user.tckn }}",
"e-mail": "{{ security.submitter.user.mail }}",
"e-mail-distribution-list": "mdl-sms-otp-validate",
}
```
E-mail adımında temel alanlara ek olarak
**actor** onay verecek kullanıcıyı tanımlar. Sadece actor olarak tanımlanmış kişi onay servisini çağrırarak kodu submit edebilir.
**e-mail** o kayıt için mesaj gönderilecek e-posta adres bilgisidir.
**mail-distribution-list** e-posta kaydının gönderilmesi için kayıt atılacak dağıtım listesinin adıdır.
### Yanıt Modeli
Eğer Onay akışında sırası gelen bir adımdaysa yanıt;
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "EMAIL",
"page-template-render":"<p><b>530 2896073</b> nolu onay e-postanız gonderilmistir</p>",
}
```
Eğer Onay akışında sırası geçmiş ve onaylanmış bir adım ise yanıt;
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "EMAIL",
"page-template-render":"<p><b>530 2896073</b> nolu onay e-postanız gonderilmistir</p>",
"validated-at":"2020-04-22T05:21:26.557Z"
}
```
Eğer Onay akışında sırası geçmiş ve onaylan**ma**mış bir adım ise yanıt;
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "EMAIL",
"page-template-render":"<p><b>530 2896073</b> nolu onay e-postanız gonderilmistir</p>",
"timeout-at":"2020-04-22T05:21:26.557Z"
}
```
### Destek Servisleri
#### POST /gateway/approval/sms-otp/validate/{id}
Otp doğrulamak için. Id işlemin tekil anahtarıdır.
```json
Body:
{
"code":"456896"
}
```
Validasyonun başarılı olması sonucunda eğer varsa bir sonraki onay adımı ile ilgili bilgi yoksa işlemi gerçekleştirip işlem ile ilgili bilgi döner.
#### POST /gateway/approval/sms-otp/resend/{id}
Yeni bir OTP talep etmek için kullaılacak servis.
## Adım : IVN
```json
{
"order": 2,
"type": "IVN",
"time-out": 600,
"page-template": "validate-template-definition-update-page"
"max-retry-count": 2,
"auto-close": 30,
"suspend-duration-between-retries": 300,
"phone": "{{ security.submitter.user.phone }}",
"ivn-voice-record": "validate-template-definition",
}
```
### Servisler
#### GET /gateway/approval/ivn/status/{id}
IVN validasyonu sorgulamak için kullanılır. Id işlemin tekil anahtarıdır.
Validasyonun başarılı olması sonucunda eğer varsa bir sonraki onay adımı ile ilgili bilgi yoksa gerçekleştirdiği işlem ile ilgili bilgi döner.
## Adım : QUEUE
```json
{
"order": 3,
"type": "QUEUE",
"time-out": 4320,
"page-template": "generic-template-definition-update-page",
"minimum-approver": 2,
"minimum-rejecter": 1,
"actors": [
"ukaratas@burgan.com.tr",
"adk@burgan.com.tr",
"{{ security.submitter.user.tckn }}"
]
}
```
### Servisler
#### POST /gateway/approval/queue/approve/{id}
Kuyrukta bekleyen işlemi onaylamak için kullanılır.
```json
Body:
{
"comment":"benim açımdan ok."
}
```
Aksiyonun başarılı olması sonucunda eğer varsa bulunulan adımda veya bir sonraki onay adımı ile ilgili bilgi yoksa gerçekleştirdiği işlem ile ilgili bilgi döner.
#### POST /gateway/approval/queue/reject/{id}
Kuyrukta bekleyen işlemi ret etmek için kullanılır.
```json
Body:
{
"comment":"benim açımdan NOT ok."
}
```
#### POST /gateway/approval/queue/take/{id}
Kuyrukta bekleyen işlemi kullanıcının üzerine alması.
#### POST /gateway/approval/queue/release/{id}
Kuyrukta bekleyen işlemi iade etmesi
## İşlem Kayıtları
Kullanıcı onay akışı bağlı bir servis çağırdığında bir işlem kaydı oluşur.
İşlem kaydına istinaden çağırdığı servis HTTP statü olarak **200** yerine **202** döner. Dönüş mesajı olarak ise işlemin (ilk) onay adım bilgini döner.
```json
{
"id": "6ce0ad60-0d93-434b-ae0e-75f24608ae5d",
"type": "SMS-OTP",
"retry-count": 1,
"page-template-render":"<p><b>530 2896073</b> nolu telefonunuza kodunuz gonderilmistir</p>"
}
```
### POST: /gateway/approval/transactions/list/{type}/{page-index}/{page-size}
Servisi ile akış bekleyen/beklemiş kayıtlar listelenir.
**type** ile sağlanabilecek parametreler *RequestedByMe*, *WaitingMyApproval*, *EvaluatedByMe*
### POST: /gateway/approval/transactions/history/{id}
Servisi ile akış geçmişine erişilir.