Управління каналами зв’язку користувача

1. Загальний опис

Наразі користувач має можливість налаштовувати канали зв’язку для отримання повідомлень від системи:

  • email - Відправка поштових повідомлень

  • diia - Відправка push-нотифікацій у мобільний додаток Дія

Особливістю inbox каналу зв’язку є те, що він буде активований за замовчуванням, користувач не зможе редагувати, деактивувати або якимось іншим чином налаштовувати цей канал.

Іншими словами, робота з inbox каналом не є предметом даної статті

2. Функціональні сценарії

  • Пошук налаштувать користувача за ідентифікатором користувача

  • Пошук налаштувань користувача за ідентифікатором користувача, отриманим з токена доступу

  • Активація каналу зв’язку шляхом введення / оновлення даних атрибутів каналу (наприклад: поштова адреса)

  • Деактивація каналу зв’язку

  • Валідація введених налаштувань користувача (за патерном email, відсутністю в blacklist тощо)

3. Базові принципи

  • Користувач має право змінювати лише власні налаштування

  • Користувач може мати лише один канал кожного типу (email, diia)

  • Отримувати налаштування користувача може користувач, якому належать ці налаштування, або система (для змоги надсилати повідомлення користувачам на обрані ними канали зв’язку)

4. Технічний дизайн рішення

При імплементації роботи з каналами зв’язку було змінено дизайн Сервісу налаштувань. Основна зміна полягає в тому, що сервіси user-settings-service-api та user-settings-service-persistence об’єднані в один сервіс user-settings-service.
user settings service design

4.1. Компоненти системи та їх призначення в рамках дизайну рішення

У даному розділі наведено перелік компонент системи, які задіяні або потребують змін/створення в рамках реалізації функціональних вимог згідно технічного дизайну рішення.

Компонент Службова назва Призначення

Кабінет громадянина

citizen-portal

Управління налаштуваннями користувача через сторінку "Профіль" кабінету

Сервіс управління налаштуваннями користувачів

user-settings-service

Отримання та зміна налаштувань каналів зв’язку, обраних користувачем

Розподілена реляційна база даних Citus

citus-master

Довготривале збереження налаштувань каналів зв’язку користувачів на цільовому оточенні реєстру

Розподілений брокер повідомлень Kafka

kafka

Асинхронне відправлення аудит-повідомлень про зміни в каналах зв’язку

Сервіс управління Avro-схемами опису структур даних

kafka-schema-registry

Збереження Avro-схеми опису структури даних значущих подій аудиту

4.2. Налаштування політик міжсервісної взаємодії

Для коректної роботи сервісу налаштувань, мають бути налаштовані відповідні мережеві політики NetworkPolicy, які дозволяють взаємодію для наступних компонентів:

  • konguser-settings-service

  • user-settings-servicecitus-master

  • user-settings-servicekafka

  • user-settings-servicekafka-schema-registry

4.3. API управління налаштуваннями та каналами зв’язку

Отримання доступу до API можливе лише в рамках виконання запиту автентифікованого користувача в системі

4.3.1. Отримання користувачем налаштувань, що йому належать

Даний API-роут є публічним та має бути опублікованим для зовнішнього доступу через окремий Kong Route для Кабінету Громадянина.

GET /api/settings/me

Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

Приклад відповіді:
{
  "settingsId":  "uuid",
  "channels": [
    {
        "channel": "email",
        "activated": "true",
        "address": "user@domain.com",
        "deactivationReason": "some reason"
    }
  ]
}
Таблиця 1. Коди відповіді
Код Опис

200

OK

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

404

Дані не знайдено

500

Серверна помилка обробки запиту

4.3.2. Отримання налаштувань для користувача за ідентифікатором

GET /api/settings/{userId}

Даний API-роут не є службовим та не має бути опублікованим для зовнішнього доступу через Kong Route.
Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

userId

Текстовий

Параметр запиту

Унікальний ідентифікатор користувача в системі

Приклад відповіді:
{
  "settingsId":  "uuid",
  "channels": [
    {
        "channel": "email",
        "activated": "true",
        "address": "user@domain.com",
        "deactivationReason": "some reason"
    }
  ]
}
Таблиця 2. Коди відповіді
Код Опис

200

OK

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

404

Дані не знайдено

500

Серверна помилка обробки запиту

4.3.3. Валідація адреси для каналу зв’язку

Серверна валідація даних, внесених у якості адреси для каналу зв’язку. Набір правил залежить від типу каналу, для channel = email:

  • Валідація поштової адреси за regexp

  • Валідація поштової адреси на унікальність

  • Валідація поштової адреси проти сконфігурованого blacklist-набору

Валідація для channel = diia не застосовується.
Данний API-роут є публічним та має бути опублікованим для зовнішнього доступу через окремий Kong Route для Кабінету Громадянина.

POST /api/settings/me/channels/{channel}/validate

Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

channel

Текстовий

Параметр запиту

Назва каналу [email, diia]

Приклад запита
{
    "address": "<email>"
}
Приклад відповіді з помилкою валідації
{
    "traceId": "string",
    "code": "string",
    "message": "string",
    "localizedMessage": "string"
}
Таблиця 3. Коди відповіді

Код

Опис

200

OK

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

422

Помилка валідації

500

Серверна помилка обробки запиту

4.3.4. Активація каналу зв’язку користувача

Активація каналу зв’язку для користувача, створення налаштувань для каналу, якщо вони ще не існують.

Данний API-роут є публічним та має бути опублікованим для зовнішнього доступу через окремий Kong Route для Кабінету Громадянина.

POST /api/settings/me/channels/{channel}/activate

Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

channel

Текстовий

Параметр запиту

Назва каналу [email, diia]

Приклад тіла запиту для channel = email
{
    "address": "user@domain.com"
}
Таблиця 4. Коди відповіді
Код Опис

200

OK

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

409

Порушення обмежень бази даних

500

Серверна помилка обробки запиту

4.3.5. Деактивація каналу зв’язку

POST /api/settings/me/channels/{channel}/deactivate

Данний API-роут є публічним та має бути опублікованим для зовнішнього доступу через окремий Kong Route для Кабінету Громадянина.
Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

channel

Текстовий

Параметр запиту

Назва каналу [email, diia]

Приклад тіла запиту
{
  "deactivationReason": "<deactivation reason enum: [USER_DEACTIVATED|SYSTEM_DEACTIVATED|BLACKLIST_DEACTIVATED]> + some message"
}
Таблиця 5. Коди відповіді

Код

Опис

200

OK

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

500

Серверна помилка обробки запиту

4.5. Фізична модель зберігання даних

В рамках реалізації функціональних вимог, необхідно створити окрему схему SETTINGS та розширити фізичну модель додатковими таблицями:

  • SETTINGS - зберігання налаштувань користувача

  • NOTIFICATION_CHANNEL - зберігання налаштувань каналів зв’язку користувача

У випадку необхідності введення статусу/ролі користувача таблиця "subject_settings" може бути розширена відповідними полями.
Diagram

4.5.1. Структура даних SETTINGS

Поле Тип Обмеження Значення за замовчуванням Опис

ID

UUID

Primary Key

uuid_generate_v4()

Унікальний автоматично згенерований ідентифікатор запису

KEYCLOAK_ID

UUID

Not Null

-

Зовнішній ідентифікатор користувача в keycloak

4.5.2. Структура даних NOTIFICATION_CHANNEL

Поле Тип Обмеження Значення за замовчуванням Опис

ID

UUID

Primary Key

uuid_generate_v4()

Унікальний автоматично згенерований ідентифікатор запису

SETTINGS_ID

UUID

Foreign Key, Not Null, Unique Constraint with CHANNEL

-

Ідентифікатор запису в settings

CHANNEL

ENUM

Not Null, Unique Constraint with SETTINGS_ID [email,diia]

-

Назва каналу зв’язку для використання шаблону повідомлення

ADDRESS

TEXT

Unique

-

Адреса для відправлення повідомлень (опційна, в залежності від типу каналу зв’язку)

DEACTIVATION_REASON

TEXT

-

-

Причина попередньої деактивації каналу

IS_ACTIVATED

BOOLEAN

Not Null

false

Чи активований даний канал

CREATED_AT

TIMESTAMP

Not Null

now()

Дата/Час створення запису

UPDATED_AT

TIMESTAMP

Not Null

now()

Дата/Час оновлення запису

Роботи з забезпечення унікальності поштових адрес заплановані на 2023 рік. До тих пір Unique обмеження для поля ADDRESS не є необхідним

4.6. Ролі/системні користувачі БД

Для обслуговування операцій взаємодії з БД, необхідно створити ролі/користувачів з визначеними правами доступу для використання відповідними компонентами системи:

Компонент системи Роль/Користувач Привілегії

user-settings-service

settings_role

GRANT SELECT, INSERT, UPDATE, DELETE ON SETTINGS

GRANT SELECT, INSERT, UPDATE, DELETE ON CHANNELS

4.7. Аудит та журналювання подій

Події активації/деактивації каналів зв’язку фіксуються у журналі аудиту з повним контекстом. Для реалізації вимоги необхідно розширити підсистему аудиту наступними службовими операціями:

  • USER_NOTIFICATION_CHANNEL_ACTIVATION

  • USER_NOTIFICATION_CHANNEL_DEACTIVATION

Детальніше з дизайном підсистеми "Журнал аудиту" можна ознайомитися за посиланням

4.7.1. Структура події аудиту

Нижче наведено структуру події аудиту та її відповідність структурі та значенням отриманого через Kafka-топік повідомлення про необхідність відправки нотифікації користувачу.

4.7.1.1. Структура контексту події аудиту
Подія активації каналу зв’язку користувача
{
  "channel": "email",
  "address": "email@email.com"
}
Подія деактивації каналу зв’язку користувача
{
  "channel": "email",
  "address": "email@email.com",
  "deactivationReason": "deactivationReason"
}

4.8. Налаштування публікації подій аудиту

Приклад налаштувань сервісу для публікації подій аудиту через Kafka-топік (на прикладі використання ddm-starter-audit бібліотеки)
audit:
  kafka:
    topic: audit-events
    schemaRegistryUrl: http://kafka-schema-registry:8081

5. Редизайн системи

В рамках редизайну системи, необхідно виконати наступні кроки:

  • Змінити ім’я сервіса налаштувань на user-settings-service

  • В усіх місцях, де використовується стара адреса сервіса налаштувань, змінити її на нову (виклики з Кабінету користувача, bpms, Сервісу відправки повідомлень)

  • Виправити назву сервіса налаштувань всюди, де вона використовується (для усіх мережевих політик, деплойментів, конфігурацій, секретів тощо)

  • Декомісувати сервіс user-settings-service-persistence, усі пов’язані з ним деплойменти, секрети, конфігмапи тощо

  • Видалити наступні kafka-топіки:

    • read-settings-inbound

    • read-settings-outbound

    • update-settings-inbound

    • update-settings-outbound

    • read-settings-by-keycloak-id-inbound

    • read-settings-by-keycloak-id-outbound

    • .DLT топіки для усіх перерахованих *-inbound

6. Міграція даних

Для збереження вже наявних поштових адрес користувачів, при оновленні фізичної моделі даних, необхідно виконати процедуру міграції

В рамках процедури міграції необхідно виконати наступні кроки:

  • Створити таблицю NOTIFICATION_CHANNEL

  • В рамках liquibase міграції БД для кожного наявного запису в таблиці SETTINGS створити у таблиці NOTIFICATION_CHANNEL відповідний запис з заповненими значеннями

Поле Значення

SETTINGS_ID

Ідентифікатор запису з таблиці SETTINGS

CHANNEL

email

ADDRESS

Значення з колонки email

IS_ACTIVATED

true

  • Оновити структуру таблиці SETTINGS

7. Міграція бізнес-процесів

В рамках переходу до реалізації концепції каналів зв’язку, необхідно забезпечити можливість їх управління виключно через профіль користувача.

Задля цього необхідно мігрувати бізнес-процеси он-бордингу користувачів існуючих реєстрів на нову версію, в якій відсутні кроки внесення поштової адреси.

Існують 2 делегати, що використовувались для роботи з налаштуваннями користувача:

  • userSettingsConnectorReadDelegate

  • userSettingsConnectorUpdateDelegate

Після змін у сервісі роботи з налаштуваннями користувача, для коректного продовження роботи userSettingsConnectorReadDelegate необхідно:

  • Перейти до використання нового ендпоінту отримання налаштувань

  • Перетворити дані, отримані з сервіса, до старої структури, та не змінювати формат відповіді делегата

Делегат userSettingsConnectorUpdateDelegate стає deprecated і підлягає подальшому видаленню у наступних оновленнях платформи