...
- Додати до базової моделі award необовʼязкову до заповнення поле beneficiaries моделю даних beneficiariesGeneralInfo (модель даних наведено нижче)
- Налаштувати інтеграцію з ЄДР де після відпраки запиту заповнюється модель beneficiariesGeneralInfo
- При внесенні інформації змінюємо award.dateModified, dateModified (procedure) та systemDateModified
- Майданчики відображають дану інформацію організатору в його кабінеті. Відображення в інших місцях не є обовʼязковою (портал, кабінети учасників)
- Модель даних beneficiariesGeneralInfo
Технічна назва Бізнес назва (x-legalName) Тип Read only Обовʼязковість (потребує уточнень) Коментар uk_UA en_US beneficiaries Інформація про кінцевого бенефеціарного влсника Information about the ultimate beneficial owner list of objects true false reason
string (multilang) true false beneficiariesGeneralInfo
object true false beneficialName ПІБ кінцевого бенефеціарного власника Full name of the ultimate beneficial owner string (multilang) true true В запиті Прізвище це відповідь на один запит, Імʼя та По батькові - відповідь на інший запит address Адреса Address model true true beneficiariesType
Тип бенефіціарного володіння Type of beneficiaries
string (multilang) true true role Роль КБВ по відношенню до пов’язаного суб’єкта string true true Відповідь на запит текстове відображення ролі (roleText) interest
Відсоток частки статутного капіталу або відсоток права голосу float true true indirectInterest
Відсоток частки статутного капіталу або відсоток права голосу у разі непрямого впливу float true true otherImpact
Інший характер та міру впливу beneficiaryFalse
Ознака можливої недостовірності інформації про КБВ excluded
Ознака виключення відомостей про КБВ за вказівкою Міністерства юстиції України isMissing
Ознака відсутності КБВ юридичної особи reason
Причина відсутності КБВ юридичної особи informationDate Дата отримання даних Date of information string ($dateTime) true true
...
- Інтеграція тригериться тільки при створенні award
- Запит асинхронний
- Дані записуються тільки якщо валідні
- Запис — атомарний (все або нічого)
- Можливі декілька КБВ
- Retry (3 рази) тільки для:
- 500
- 502
- Slack alert тільки для:
- 4xx + 429
- Fallback текст при недоступності ЄДР
- У разі отримання першої відповіді від ЄДР з HTTP статусом 402 або 429 ЦБД має призупинити направлення всіх наступних запитів до сервісу ЄДР до моменту ручного або автоматичного відновлення інтеграції після внесення коштів / відновлення ліміту.
- Система повинна диференційовано обробляти помилки ЄДР:
- технічні помилки (500, 502) → retry (Якщо не вдається отримати відповідь виводимо в поле reason текст "Не вдалось отримати інформацію з сервісу")
Статуси інтеграції (В разі якщо будемо виносити в Адмінку та або будемо в принципі зупиняти запити в разі отримання помилок)
- авторизаційні (401) → refresh token
- бізнес/доступ (402, 403, 406, 429) → зупинка або alert
- помилки даних (400, 404) → без retry, з логуванням
Система не повинна виконувати безкінечні повторні запити.
Статуси інтеграції (В разі якщо будемо виносити в Адмінку та або будемо в принципі зупиняти запити в разі отримання помилок)
| Статус | Опис |
|---|
active | Запити до ЄДР виконуються |
payment_required | Отримано 402, запити зупинено |
rate_limit_exceeded | Отримано 429, запити зупинено |
suspended | Загальний статус призупинення |
restored | Інтеграцію відновлено |
Як працює сервіс ЄДР
Сервіс ЄДР реалізований як API для автоматичного отримання даних для внесення інформації про КБВ учасника торгів що кваліфікується. Взаємодія працює по протоколу HTTP з використанням авторизації через JWT. Загальна логіка процесу: спочатку через метод авторизації отримуємо access та refresh токени, а потім використовуємо їх для виклику ендпоінту отримання даних для заповнення інформації про КБВ за кодом ЄДРПОУ юридичною особи. - Детальніше буде додано після отримання тестового ключа
...
USE CASE 8 — Зупинка запитів після отримання 429
Назва | Автоматичне призупинення інтеграції з ЄДР при помилці 429 Many Requests |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | ЦБД отримала відповідь 429 |
When | Система обробляє відповідь | |
Then | Направлення нових запитів до ЄДР зупиняється. | |
2 | Given | Інтеграція призупинена через |
When | Створюється новий award | |
Then | ЦБД не направляє запит до ЄДР | |
3 | Given | Отримано 429 |
| When | Система обробляє помилку | |
Then | Повідомлення надсилається в Slack канал. |
...
USE CASE 9 — Відновлення запитів після внесення коштів
Назва | Ручне або автоматичне відновлення інтеграції з ЄДР після внесення коштів |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | Інтеграція призупинена через 402 |
| And | Кошти внесено | |
When | Адміністратор активує інтеграцію | |
Then | Статус інтеграції змінюється на active. | |
2 | Given | Інтеграція активна після відновлення |
When | Створюється новий award | |
Then | ЦБД направляє запит до ЄДР | |
3 | Given | ЄДР після відновлення повертає 200 |
| When | ЦБД отримує валідні дані | |
Then | Дані записуються в |
...
USE CASE 10 — Відновлення після вичерпання ліміту запитів
Назва | Відновлення інтеграції після помилки 429 |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | Інтеграція призупинена через 429 |
When | Ліміт запитів відновлено | |
And | Адміністратор активує інтеграцію | |
Then | ЦБД знову направляє запити до ЄДР | |
2 | Given | Інтеграція активована після |
When | Створюється award | |
Then | Запит до ЄДР виконується |
User Story 3. Обробка помилок інтеграції з ЄДР та забезпечення стабільності системи
| Як | ЦБД Prozorro.Sale |
| я хочу | коректно обробляти всі типи помилок від ЄДР (400, 401, 403, 404, 406, 500, 502) |
| щоб | забезпечити стабільну роботу системи, не втрачати дані та мати можливість відновлення інтеграції |
USE CASE
...
11 — Обробка 401 (Unauthorized)
Назва | Автоматичне оновлення токена при помилці 401 |
Назва
| Актори |
|
|
|
| Передумови |
- Процедура входить в перелік дозволених (LLE, LLD, …, SUD)
- В процедурі використовується документ
x_ultimateBeneficiaryInfo - Учасник є юридичною особою
award.bidders.identifier.scheme = UA-EDRaward.status ∈ {pending_waiting, pending_admission, pending}
- Учасник подає заявку
- Майданчик активує заявку
- Заявка переходить у кваліфікацію
- ЦБД створює
award - ЦБД перевіряє умови запуску інтеграції
- ЦБД виконує авторизацію в ЄДР (отримує JWT токен)
- ЦБД відправляє запит до ЄДР з
code = ЄДРПОУ - ЄДР повертає дані КБВ (може бути список)
- ЦБД валідовує відповідь
- Дані відповідають моделі
beneficiariesGeneralInfo - ЦБД записує дані в
award.beneficiaries - Оновлює:
award.dateModifiedprocedure.dateModifiedsystemDateModified
award містить список КБВ (може бути декілька)
Acceptance Criteria
...
1
...
When
...
Then
...
2
...
ЄДР повернув валідні дані
...
When
...
Then
...
3
...
Then
...
оновлюються всі dateModified:
award.dateModifieddateModified (procedure)systemDateModified
🧩 USER STORY (для обробки помилок ЄДР)
...
User Story:
Як ЦБД
я хочу
щоб
🔐 USE CASE 1 — Обробка 401 (Unauthorized)
Назва
Автоматичне оновлення токена при помилці 401
Актори
- ЦБД
- ЄДР
- Slack
Передумови
- Запит до ЄДР виконано
- Отримано
401 Unauthorized
Основний сценарій
...
| |
| Основний сценарій |
|
|
...
| |
| Альтернативний сценарій | Refresh token невалідний → перейти до помилки критичного рівня |
| Результат | Інтеграція відновлюється без втручання людини |
Acceptance Criteria
1 | Given | Отримано 401 |
When | Токен протермінований | |
Then | Система виконує refresh token | |
2 | Given | Токен оновлено |
Then | Запит повторюється 1 раз | |
3 | Given | повторний запит успішний |
Then | дані записуються в award |
...
USE CASE 12 — Помилка 400 (Bad Request)
Назва | Обробка некоректного запиту до ЄДР |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Рішення | Виправлення формату запиту (dev fix) |
| Результат |
|
Acceptance Criteria
1 | Given | Отримано 400 |
When | Обробляється помилка | |
Then | Retry не виконується | |
And | Slack отримує повідомлення |
...
USE CASE 13 — Помилка 403 (Forbidden)
Назва | Обробка відсутності прав доступу |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Рішення |
|
| Результат | Інтеграція не працює до виправлення |
Acceptance Criteria
1 | Given | Отримано 403 |
Then | Retry не виконується | |
And | Slack отримує повідомлення |
...
USE CASE 14 — Помилка 404 (Not Found)
Назва | Обробка відсутності суб’єкта в ЄДР |
| Актори |
|
| Передумови | ЄДРПОУ не знайдено |
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | Отримано 404 |
Then | Retry не виконується | |
And | Записує beneficiaries тільки поле reason:
|
...
USE CASE 15 — Помилка 406 (Not Acceptable)
Назва | Обробка помилки формату даних |
| Актори |
|
| Передумови | Некоректний формат request/response |
| Основний сценарій |
|
| Рішення |
|
| Результат |
|
Acceptance Criteria
1 | Given | Отримано 406 |
Then | Retry не виконується | |
And | Slack отримує повідомлення |
ЗВЕДЕНА ТАБЛИЦЯ
Альтернативи
- Refresh token невалідний → перейти до помилки критичного рівня
Результат
- Інтеграція відновлюється без втручання людини
Acceptance Criteria
- Given отримано 401
When токен протермінований
Then система виконує refresh token - Given токен оновлено
Then запит повторюється 1 раз - Given повторний запит успішний
Then дані записуються в award
❗ USE CASE 2 — Помилка 400 (Bad Request)
Назва
Обробка некоректного запиту до ЄДР
Причина
- неправильний формат параметрів
- неправильний code
Основний сценарій
- ЦБД отримує
400 - Аналізує помилку
- Визначає:
- помилка у формуванні запиту
- НЕ виконує retry
- Логує помилку
- Надсилає повідомлення в Slack
Рішення
- виправлення формату запиту (dev fix)
Результат
- запит не повторюється
- потрібне втручання розробника
Acceptance Criteria
- Given отримано 400
When обробляється помилка
Then retry не виконується
And Slack отримує повідомлення
🚫 USE CASE 3 — Помилка 403 (Forbidden)
Назва
Обробка відсутності прав доступу
Причина
- змінились права доступу до API
- акаунт не має доступу
Основний сценарій
- ЦБД отримує
403 - Фіксує помилку
- НЕ виконує retry
- Відправляє alert в Slack
- (опційно) переводить інтеграцію в статус
restricted
Рішення
- перевірка прав доступу
- перевидача ключів / ролей
Результат
- інтеграція не працює до виправлення
Acceptance Criteria
- Given отримано 403
Then retry не виконується
And Slack повідомляється
🔍 USE CASE 4 — Помилка 404 (Not Found)
Назва
Обробка відсутності суб’єкта в ЄДР
Причина
- ЄДРПОУ не знайдено
Основний сценарій
- ЦБД отримує
404 - Визначає, що суб'єкт відсутній
- НЕ виконує retry
- НЕ записує beneficiaries
- (опційно) записує reason:
- "Суб'єкт не знайдено в ЄДР"
Результат
- award без КБВ
Acceptance Criteria
- Given отримано 404
Then retry не виконується
And дані не записуються
⚠️ USE CASE 5 — Помилка 406 (Not Acceptable)
Назва
Обробка помилки формату даних
Причина
- некоректний формат request/response
Основний сценарій
- ЦБД отримує
406 - Фіксує помилку
- НЕ виконує retry
- Відправляє alert в Slack
Рішення
- перевірка контракту API
- виправлення формату
Результат
- інтеграція потребує доопрацювання
Acceptance Criteria
- Given отримано 406
Then retry не виконується
And Slack повідомляється
🔄 USE CASE 6 — Помилки 500 / 502 (Server errors)
(у тебе вже частково є, але тут — повна версія)
Назва
Retry при серверних помилках ЄДР
Основний сценарій
- ЦБД отримує
500або502 - Виконує retry (до 3 разів)
- Якщо успіх → стандартний сценарій
- Якщо всі retry fail:
- записує fallback текст
- НЕ падає
Рішення
- автоматичне повторення
- graceful fallback
Результат
- система стабільна навіть при падінні ЄДР
Acceptance Criteria
- Given 500/502
Then retry до 3 разів - Given retry fail
Then записується fallback повідомлення
...
| Код | Retry | Зупинка інтеграції | Slack | Дія |
|---|---|---|---|---|
| 400 |
| Ні |
| Ні |
| Так | баг у запиті |
| 401 |
| Так (1 раз) |
| НІ |
| Ні | refresh token |
| 402 |
| Ні |
| Так |
| Так | чекати оплату |
| 403 |
| Ні | Можливо | Так |
| перевірити доступ | |
| 404 |
| Ні |
| Можливо |
| Ні | немає суб'єкта |
| 406 |
| Ні |
| Можливо |
| Так | формат |
| 429 |
| НІ |
| Так |
🧩 ГЛОБАЛЬНЕ БІЗНЕС-ПРАВИЛО
...
| Так | ліміт | |||
| 500 | 🔁 (3 рази) | Ні | Ні | тимчасова помилка |
| 502 | 🔁 (3 рази) | Ні | Ні | сервіс недоступний |