Please use this identifier to cite or link to this item:
https://er.chdtu.edu.ua/handle/ChSTU/8941Full metadata record
| DC Field | Value | Language |
|---|---|---|
| dc.contributor.advisor | Півень, Олександр Борисович | - |
| dc.contributor.author | Куценко, Олег Сергійович | - |
| dc.date.accessioned | 2026-03-22T16:20:39Z | - |
| dc.date.available | 2026-03-22T16:20:39Z | - |
| dc.date.issued | 2024-06-04 | - |
| dc.identifier.uri | https://er.chdtu.edu.ua/handle/ChSTU/8941 | - |
| dc.language.iso | uk | uk_UA |
| dc.title | Розробка Telegram-боту сімейного лікаря | uk_UA |
| dc.type | Bachelor Thesis | uk_UA |
| Appears in Collections: | 121 Інженерія програмного забезпечення (Інженерія програмного забезпечення) | |
Files in This Item:
| File | Description | Size | Format | |
|---|---|---|---|---|
| Кваліфікаційев робота бакалавра Куценко Олег Сергійович.pdf Restricted Access | 5.92 MB | Adobe PDF | View/Open Request a copy |
Items in DSpace are protected by copyright, with all rights reserved, unless otherwise indicated.
Extracted text
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ЧЕРКАСЬКИЙ ДЕРЖАВНИЙ ТЕХНОЛОГІЧНИЙ УНІВЕРСИТЕТ
Факультет інформаційних технологій і систем
Кафедра програмного забезпечення автоматизованих систем
ПОЯСНЮВАЛЬНА ЗАПИСКА
до кваліфікаційної роботи
бакалавра
на тему: Розробка Telegram-боту сімейного лікаря»
Виконав: студент 4 курсу, групи ПЗ-2004
спеціальності
121 «Інженерія програмного забезпечення»
(шифр і назва напряму підготовки)
Студент Куценко О.С.
(прізвище та ініціали)
Керівник Півень О.Б.
(прізвище та ініціали)
Рецензент
(прізвище та ініціали)
Черкаси 2024
Черкаський державний технологічний університет
повне найменування вищого навчального закладу
Факультет інформаційних технологій і систем
Кафедра програмного забезпечення автоматизованих систем
Освітній рівень бакалавр
Спеціальність 121 «Інженерія програмного забезпечення»
Освітня програма Інженерія програмного забезпечення
ЗАТВЕРДЖУЮ
Зав. кафедри ПЗАС, професор
__________________ Голуб_С.В
«___» _____________ 2024 року
З А В Д А Н Н Я
НА КВАЛІФІКАЦІЙНУ РОБОТУ СТУДЕНТУ
Куценко Олег Сергійович
(прізвище, ім’я, по батькові)
1. Тему проекту (роботи) «Розробка Telegram-боту сімейного лікаря
Керівник проекту (роботи) Півень Олександр Борисович к.ф.-м.н. доцент
(прізвище, ім’я , по батькові, науковий ступінь, вчене звання)
Затверджені наказом Черкаського державного технологічного університету від « 26 » лютого 2024
року №60/04
2. Строк подання студентом проекту (роботи) 03.06.2024
3. Вхідні дані до проекту (роботи) стандарти програмного забезпечення; процеси управління;
вимоги до проекту; календарне планування проекту; управління ризиками проекту; управління
ресурсами
4. Зміст розрахунково-пояснювальної записки (перелік питань, які потрібно розробити) Вступ;
Існуючі методи та засоби вирішення поставлених завдань;
Впровадження результатів досліджень у практику;
Проектування програмного забезпечення інформаційних систем;
Розробка та тестування програмного забезпечення;
Висновки;
Список використаних джерел;
Додатки.
5. Перелік графічного матеріалу (з точним зазначенням обов’язкових робіт проекту)
Слайд 1, Слайд 2, Слайд 4, Слайд 5, Слайд 6, Слайд 7, Слайд 8, Слайд 9, Слайд 10, Слайд
11. Слайд 12
6. Консультанти розділів роботи
Розділ Прізвище, ініціали та Підпис, дата
посади консультанта Завдання видав Завдання прийняв
1
2
7. Дата видачі завдання 02 грудня 2023 р
КАЛЕНДАРНИЙ ПЛАН
Строк виконання
№ етапів
Назва етапів випускної роботи Примітки
п/п кваліфікаційної
роботи
1 Постановка задачі 02.12.2023 виконано
2 Підготовка завдання 10.12.2023 виконано
3 Погодження завдання 25.12.2023 виконано
4 Затвердження завдання 12.01.2024 виконано
Основна стадія
1 Підбір матеріалів 28.01.2024 виконано
2 Аналіз шляхів вирішення поставлених задач 15.02.2024 виконано
3 Розрахунок основних параметрів роботи 02.03.2024 виконано
4 Вибір кінцевого варіанту проектного рішення 21.03.2024 виконано
5 Оформлення первісної редакції роботи 20.04.2024 виконано
Заключна стадія
1 Узгодження прийнятих проектних рішень з керівником 03.05.2024 виконано
2 Оформлення пояснювальної записки роботи в кінцевій 10.05.2024 виконано
редакції
3 Попередній захист роботи 15.05.2024 виконано
4 Затвердження роботи 16.05.2024 виконано
5 Рецензування роботи 24.05.2024 виконано
6 Захист роботи 03.06.2024 виконано
Студент _____________________ Куценко О.С.
(підпис) (прізвище та ініціали)
Керівник роботи _____________________ Півень О.Б.
(підпис) (прізвище та ініціали)
ЗМІСТ
ЗМІСТ ..................................................................................................................... 4
ВСТУП ................................................................................................................... 6
РОЗДІЛ 1 ІСНУЮЧІ МЕТОДИ ТА ЗАСОБИ РОЗВ’ЯЗАННЯ
ПОСТАВЛЕНИХ ЗАВДАНЬ ......................................................................................... 8
1.1 Опис існуючих методів на засобів використаних при розробці ............ 8
1.2 Аналіз існуючих аналогів програми ......................................................... 9
1.3 Постановка задачі ..................................................................................... 12
ВИСНОВОК ДО ПЕРШОГО РОЗДІЛУ ....................................................... 14
РОЗДІЛ 2. ВПРОВАДЖЕННЯ РЕЗУЛЬТАТІВ ДОСЛІДЖЕНЬ У
ПРАКТИКУ ПРОЕКТУВАННЯ .................................................................................. 15
2.1 Моделювання предметної області ........................................................... 15
2.1.1 Предметна область моделювання. Модель предметної області.
Словник предметної області ................................................................................ 17
2.1.2 Елементи моделювання предметної області ................................... 18
2.1.3 Робоча область моделювання ........................................................... 20
2.2 Формування та аналіз вимог .................................................................... 22
2.2.1 Формування вимог до програмного забезпечення. Первинні і
детальні вимоги. Вимоги замовника і розробника. Функціональні та
нефункціональні вимоги ....................................................................................... 22
2.2.2 Формування вимог за допомогою діаграми прецедентів .............. 25
2.3 Проектування логічної структури програмного комплексу ................. 27
2.3.1 Діаграми класів .................................................................................. 27
2.3.2 Діаграми пакетів ................................................................................ 29
2.4 Архітектура проектування ....................................................................... 29
2.4.1 Діаграма компонентів ........................................................................ 29
2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма
розгортання ............................................................................................................ 30
ЧДТУ 242054.007 ПЗ
Змн. Арк. № докум. Підпис Дата
Розроб. Басюк К.С. «Телег рам-бот кафедри програмного Літ. Лист Листів
Перевір. Півень О.Б. забезпечення автоматизованих систем 3
Черкаського державного технологічного
університету»
Н. Контр. Півень О.Б. ФІТІС, кафедра ПЗАС, ПЗС-2244
Пояснювальна записка.
Затверд. Голуб С.В.
2.5 Моделювання поведінки системи ........................................................... 31
2.5.1 Діаграма діяльності ............................................................................ 32
2.5.2 Діаграма послідовності ...................................................................... 35
2.5.3 Діаграма комунікації ......................................................................... 36
2.5.4 Діаграма скінченного автомату ........................................................ 38
ВИСНОВОК ДО ДРУГОГО РОЗДІЛУ ......................................................... 39
РОЗДІЛ 3 РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО
ЗАБЕЗПЕЧЕННЯ........................................................................................................... 40
3.1 Розробка програмного комплексу ........................................................... 40
3.1.1 Обґрунтування вибору засобів реалізації ....................................... 40
3.1.2 Опис структурної (функціональної) схеми ..................................... 42
3.1.3 Опис логічної схеми .......................................................................... 44
3.1.4 Розробка бази даних .......................................................................... 46
3.1.5 Розробка інтерфейсу користувача .................................................... 48
3.1.6 Опис розробки програмних компонентів ........................................ 53
3.2 Тестування системи .................................................................................. 54
3.2.1 Модульне тестування ........................................................................ 55
3.2.2 Інтеграційне тестування .................................................................... 58
3.2.3 Системне тестування ......................................................................... 59
3.2.4 Приймальне тестування ..................................................................... 60
3.3 Приклади впровадженого програмного комплексу .............................. 60
ВИСНОВОК ДО ТРЕТЬОГО РОЗДІЛУ ....................................................... 62
ВИСНОВКИ ......................................................................................................... 63
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ ........................................................... 64
Додаток А ............................................................................................................. 66
Додаток Б ............................................................................................................. 68
Додаток В ........................................................................................................... 122
Додаток Г ........................................................................................................... 132
ЧДТУ 242054.007 ПЗ
Змн. Арк. № докум. Підпис Дата
ЧДТУ 242054.007 ПЗ
ВСТУП
Актуальність теми. Актуальність визначається потребою у програмній
реалізації інформаційної технології мережевої комунікації у формі телеграм боту
. Він забезпечує швидке та зручне отримання медичної консультації.
Розробка Telegram-боту сімейного лікаря є актуальним та доцільним
завданням, оскільки надає можливість швидкого та зручного отримання медичної
інформації та консультацій, необхідних для підтримки пацієнтів. Порівняно з
традиційними методами звернення до лікаря, використання телеграм-бота
дозволяє ефективно вирішувати питання у сфері охорони здоров'я в будь-який час
та в будь-якому місці, не обтяжуючи пацієннтів проведенням часу чергах або
обмеженим робочим графіком закладів медичного обслуговування.
Мета роботи полягає у розробці програмного забезпечення Telegram-боту
сімейного лікаря з метою забезпечення зручної та ефективної взаємодії між
лікарем та пацієнтами, що дозволить покращити їхню комунікацію.
Для досягнення цієї мети необхідно вирішити наступні завдання:
визначення сучасних методів та засобів розвязання задач;
реалізувати функціонал прикріплення пацієнтів до конкретного лікаря;
розробити систему запису на прийом, яка забезпечить зручний вибір дати
та часу прийому;
забезпечити можливість лікарям виписувати рецепти пацієнтам та
генерувати направлення до інших медичних закладів;
протестувати бота на відповідність функціональним вимогам та безпеці,
виявити та виправити можливі помилки;
впровадити бота у виробниче середовище та забезпечити користувачів
необхідною підтримкою та інструкціями щодо використання;
Об'єктом розробки є процес створення програмного забезпечення для
медичного обслуговування в сфері сімейної медицини за допомогою Telegram-
боту сімейного лікаря. Цей процес включає в себе всі етапи взаємодії між лікарем
та пацієнтами, починаючи від реєстрації лікарів та пацієнтів, прикріплення
5
ЧДТУ 242054.007 ПЗ
пацієнтів до конкретного лікаря, запису на прийом, виписання рецептів та
направлень до інших медичних закладів. Об'єкт розробки також охоплює
взаємодію користувачів з Telegram-ботом, його функціональні можливості та
інтерфейс, спрямований на забезпечення зручного та ефективного використання
медичних послуг у сфері сімейної медицини.
Предмет розробки програмне забезпечення медичного обслуговування в
сфері сімейної медицини за допомогою Telegram-боту сімейного лікаря.
Методи розробки включають аналіз вимог користувачів для розуміння
потреб у зручній та ефективній взаємодії з Telegram-ботом сімейного лікаря.
Проектування системи полягало у розробленні архітектури та інтерфейсу,
спрямованого на максимальне задоволення цих потреб. Імплементація
програмного забезпечення включає розроблення та реалізацію функціональності
боту, такої як модулі реєстрації, прикріплення пацієнтів, запису на прийом,
можливість виписування рецептів та направлень. Тестування та валідація
використовуються для перевірки відповідності функціональним вимогам та
виявлення можливих помилок. Впровадження та підтримка передбачають
впровадження боту у виробниче середовище та надання користувачам необхідної
підтримки.
Опис отриманих реузльтатів. В завершеній кваліфікаційній роботі
бакалавра було успішно реалізовано програмне забезпечення Telegram-бот
сімейного лікаря
Практичне значення отриманих результатів. Отримані результати
досліджень мають велике практичне значення для впровадження в медичні заклади
та поліпшення доступу до сімейної медичної допомоги. Зокрема, розроблений
Telegram-бот сімейного лікаря може бути використаний реальних медичних
закладах, для забезпечення спрощеної комунікаціїї лікаря з пацієнтами.
6
ЧДТУ 242054.007 ПЗ
Особистий внесок автора. У результаті написання кваліфікаційної роботи
особистий внесок полягав у всебічному аналізі потреб користувачів та
функціональних вимог до Telegram-боту сімейного лікаря. Було виконано
проектування архітектури боту, звертаючи увагу на максимальну зручність та
інтуїтивність користування. Крім того, була виконана розробка та імплементація
програмного коду для реалізації функціональності боту, його тестування та
впровадження.
7
ЧДТУ 242054.007 ПЗ
РОЗДІЛ 1 ІСНУЮЧІ МЕТОДИ ТА ЗАСОБИ РОЗВ’ЯЗАННЯ
ПОСТАВЛЕНИХ ЗАВДАНЬ
1.1 Опис існуючих методів на засобів використаних при розробці
Під час розробки Telegram-боту сімейного лікаря було проведено аналіз
наукової та технічної інформації, доступної у відкритому доступі, зокрема статей
та інтернет-ресурсів. За результатами цього аналізу було визначено кілька
ключових методів та засобів, які використовуються для розв’язання подібних
завдань у галузі сімейної медицини та розробки програмного забезпечення.
Один з основних методів, використаних при розробці, — це аналіз сучасних
практик у сфері медичних інформаційних технологій та популярних мобільних
додатків для медичних послуг. Цей аналіз дозволив ідентифікувати ключові
функціональні вимоги до боту, а також кращі практики щодо його дизайну та
інтерфейсу.
Крім того, були досліджені методи та інструменти розробки чат-ботів для
платформи Telegram, зокрема використання мов програмування TypeScript та
різних бібліотек для роботи з TelegramAPI задля успішної реалізації
функціональності боту.
Проведений аналіз наукової та технічної літератури дав змогу
конкретизувати завдання роботи, ідентифікувати актуальні проблеми у галузі та
визначити оптимальні методи та засоби для їх розв’язання. Результати цього
аналізу стали в нагоді для подальшої розробки Telegram-боту сімейного лікаря.
Під час аналізу наукової та технічної літератури також було виявлено
існуючі рішення для автоматизації процесів управління пацієнтами та медичної
документації. Деякі з цих рішень базуються на використанні інших платформ чат-
ботів або спеціалізованих медичних інформаційних систем. Аналіз цих рішень
дозволив визначити переваги та недоліки вже існуючих продуктів, що були
враховані при розробці власного боту.
Цей аналіз допоміг визначити найкращі підходи до захисту персональної
інформації пацієнтів та забезпечення відповідності вимогам законодавства про
8
ЧДТУ 242054.007 ПЗ
захист даних у сфері охорони здоров'я.
Крім того, було вивчено сучасні підходи до реалізації функціональності у
чат-ботах, зокрема використання штучного інтелекту та обробки природної мови
для автоматичного розпізнавання та обробки повідомлень від користувачів. Ці
підходи були використані для покращення взаємодії користувачів з Telegram-
ботом сімейного лікаря та забезпечення більш ефективної роботи боту.
Після вивчення сучасних підходів було розглянуто найбільш валідний стек
технологій для реалізаціїї подібних продуктів. Він містить використання таких
технологій як TypeScript, Node.js, Grammy, Prisma.
TypeScript є мовою програмування, яка розширює можливості JavaScript
шляхом додавання статичної типізації. Вона дозволяє виявляти та виправляти
помилки на етапі розробки, що полегшує написання більш надійного та
структурованого коду [1].
Node.js — це середовище виконання JavaScript, яке дозволяє виконувати
JavaScript на серверній стороні. Воно забезпечує можливість розробки серверних
додатків за допомогою JavaScript, що дозволяє створювати веб-сервери та робити
операції з файлами та базами даних [2].
Prisma — це ORM (Object-Relational Mapping), яка дозволяє зручно
взаємодіяти з базою даних за допомогою звичайних об'єктів та моделей. Воно
автоматизує створення SQL-запитів та забезпечує безпечний доступ до даних [3].
Grammy є фреймворком для розробки чат-ботів для платформи Telegram. Він
надає зручний та простий спосіб створення функціональності ботів та взаємодії з
Telegram API, що спрощує процес розробки та впровадження Telegram-ботів [4].
На сьогодні, перераховані технології є максимально ефективними та
забезпечують високу якість розробки та функціонування Telegram-боту сімейного
лікаря.
1.2 Аналіз існуючих аналогів програми
Аналіз існуючих аналогів програми відіграє ключову роль у розробці та
проєктуванні програмного продукту. Тому було проведено огляд і порівняння
існуючих аналогів Telegram-боту сімейного лікаря з метою з’ясуванння їхніх
9
ЧДТУ 242054.007 ПЗ
переваг і недоліків. Аналізування аналогів допомагло зрозуміти, які можливості
вже існують на ринку, і які можна покращити або вдосконалити у новому
програмному продукті.
Для проведення аналізу існуючих аналогів Telegram-боту сімейного лікаря
були обрані кілька ключових критеріїв для порівняння. Серед них - функціональні
можливості ботів, інтерфейс користувача, безпека даних, швидкодія та підтримка.
Застосування цих критеріїв дозволило отримати об'єктивну оцінку кожного
аналогу та порівняти їхні переваги та недоліки.
Основними етапами аналізу існуючих аналогів програми було обрано:
вибір аналогів: обрання найбільш популярних та релевантних аналогів
програми, які вже існують на ринку медичних чат-ботів та телемедицини.
огляд функціональності: детальний огляд функціональних можливостей
кожного аналога, зокрема реєстрація користувачів, запис на прийом,
виписка рецептів та направлень, можливості взаємодії з лікарем та інші.
аналіз інтерфейсу користувача: оцінка зручності та естетичного вигляду
інтерфейсу користувача кожного аналога, включаючи навігацію,
розміщення елементів та загальний дизайн.
оцінка безпеки та конфіденційності: перевірка заходів, які вжиті для
захисту персональних даних користувачів та конфіденційності медичної
інформації.
швидкодія та продуктивність: оцінка швидкодії роботи кожного аналога,
часу відповіді на запити користувачів та загальної продуктивності.
підтримка та оновлення: аналіз доступності підтримки користувачів та
регулярність оновлень та вдосконалень.
У якості аналога для аналізу обрано чат-бот "Ada Health", який відомий
своєю широкою функціональністю та популярністю серед користувачів. "Ada
Health" — це чат-бот , який надає медичні консультації та діагностику.
Бот надає користувачам можливість описати свої симптоми та отримати
рекомендації щодо подальшої дії, включаючи консультацію з лікарем, якщо
потрібно [4].
10
ЧДТУ 242054.007 ПЗ
Аналог "Ada Health" обраний через його широкий спектр функціональності,
включаючи реєстрацію користувачів, опис симптомів, видачу рекомендацій щодо
медичних питань та можливість взаємодії з лікарем. Також важливою перевагою
"Ada Health" є його популярність серед користувачів та високий рівень довіри до
бренду.
Однією з ключових переваг "Ada Health" є широкий спектр медичних
послуг, які він надає. Це включає в себе самодіагностику за допомогою штучного
інтелекту, консультації з лікарем та рекомендації щодо лікування. Такий
різноманітний функціонал робить "Ada Health" привабливим вибором для
користувачів, які шукають доступні та зручні медичні послуги в онлайн-форматі.
Інший важливий аспект — це зручний інтерфейс користувача. Інтерфейс
"Ada Health" є інтуїтивно зрозумілим та зручним для користувачів будь-якого
рівня обізнаності. Це дозволяє користувачам легко взаємодіяти з сервісом і
отримувати необхідну медичну допомогу без зайвих труднощів [4].
Крім того, "Ada Health" є одним з найпопулярніших медичних чат-ботів, що
користується великою кількістю користувачів по всьому світу. Він відомий своєю
надійністю та високим рівнем довіри, що стимулює багатьох людей до
використання цього сервісу для медичних консультацій та діагностики.
Незважаючи на ці переваги, "Ada Health" має деякі недоліки. Наприклад,
обмеженість алгоритмів діагностики може призвести до неточних результатів
діагностики та невірних рекомендацій щодо лікування. Також відсутність
можливості прямої взаємодії з реальним лікарем може ускладнити ситуації, коли
потрібна індивідуалізована медична консультація. Також важливо враховувати
питання конфіденційності даних користувачів, оскільки при використанні
медичних чат-ботів може виникнути ризик порушення конфіденційності медичних
даних [4].
Аналіз переваг та недоліків "Ada Health" надав важливі висновки щодо
того, які аспекти повині бути використані для проєктування та реалізації Telegram-
боту сімейного лікаря.
11
ЧДТУ 242054.007 ПЗ
Рисунок 1.1 – Досліджений аналог «Ada Health» [4]
1.3 Постановка задач
В процесі розгляду аналогів було виявлено ряд недоліків в існуючих
рішеннях, які можна виправити в даній програмній системі. Система буде
орієнтована на зручне використання для користувача. Також після аналізу було
виявлено мало функціональних можливостей, що будуть допрацьовані та
покращені.
Система повинна бути доступна для використання на різних типах
пристроїв, а також різних браузерах. Це все зумовлено для охоплення великої
кількості користувачів.
Отже, що вимагається від системи:
1 Реалізувати клієнтську частину, яка забезпечить інтуїтивно зрозумілий
інтерфейс користувача;
2 Розробити серверну частину, що забезпечить надійну та швидку обробку
12
ЧДТУ 242054.007 ПЗ
запитів;
3 Забезпечити зручний інтерфейс, орієнтований на користувача та його
потреби;
4 Впровадити функціональні можливості для виписки рецептів,
направлень та запису на прийом;
5 Забезпечити підтримку на різних типах дисплеїв пристроїв;
6 Підтримка роботи у різних браузерах.
13
ЧДТУ 242054.007 ПЗ
Висновки до розділу 1
Було проведено аналіз існуючих методів та засобів для розв’язання
поставлених завдань щодо розробки Telegram-боту сімейного лікаря. Аналіз
наукової та технічної інформації дозволив визначити основні підходи та
технології, які використовуються у сфері медичних чат-ботів, зокрема методи
обробки природної мови та інструменти для роботи з Telegram API.
Були розглянуті сучасні практики використання медичних інформаційних
технологій та мобільних додатків, що дало змогу ідентифікувати ключові
функціональні вимоги до боту, а також найкращі практики щодо його дизайну та
інтерфейсу. Аналіз існуючих рішень для автоматизації процесів управління
пацієнтами та медичної документації дозволив визначити переваги та недоліки вже
існуючих продуктів, що були враховані при розробці власного боту.
Було обрано стек технологій, що включає TypeScript, Node.js, Prisma та
Grammy, які забезпечили високу якість розробки та функціонування Telegram-боту
сімейного лікаря.
14
ЧДТУ 242054.007 ПЗ
2 ПРОЕКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЕЧННЯ СИСТЕМИ
2.1 Моделювання предметної області
2.1.1 Предметна область моделювання. Модель предметної області. Словник
предметної області
Предметна область моделювання
Розглядаючи тему бакалаврської роботи "Розробка Telegram-боту сімейного
лікаря", предметною областю моделювання є сфера медичної допомоги та
обслуговування пацієнтів. Модель предметної області включає в себе класи
об'єктів та їх взаємозв'язки, що є ключовими для реалізації функціоналу Telegram-
боту сімейного лікаря.
Першочерговою задачею при моделюванні предметної області є визначення
класів об'єктів, які присутні у системі. У випадку боту сімейного лікаря ці об'єкти
включають пацієнтів, лікарів, медичні записи, рецепти, направлення та інші
елементи, необхідні для надання медичної допомоги через месенджер Telegram.
Предметна область моделювання
У моделі предметної області ідентифікуються різноманітні класи об'єктів,
які відображають основні аспекти медичного обслуговування та взаємодії між
пацієнтами та лікарями через Telegram-бот. До них відносяться:
Пацієнт, який представляє особу, що шукає медичну допомогу через бот. До
атрибутів пацієнта можуть входити особисті дані, історія медичних записів та інші
параметри, необхідні для забезпечення медичної допомоги.
Лікар, який представляє медичного працівника, який надає консультації та
призначає рецепти та направлення через бот. До атрибутів лікаря можуть входити
дані про спеціалізацію, контактну інформацію та інші важливі деталі.
Медичні записи відображають інформацію про проведені консультації,
процедури та призначені рецепти для кожного пацієнта. Ці записи забезпечують
зберігання історії лікування та дозволяють лікарям моніторити медичний стан
пацієнтів.
Рецепти та направлення містять інформацію про призначені лікарем рецепти
15
ЧДТУ 242054.007 ПЗ
та направлення для пацієнтів через бот. Ці дані є важливими для надання
подальшої медичної допомоги та лікування.
Запис на прийом дозволяє пацієнтам записатися на прийом до лікаря через
бот. Ця функція забезпечує можливість вибору зручного часу та дати прийому та
спрощує процес організації медичних зустрічей.
Архів медичних записів забезпечує зберігання історії медичних записів
пацієнтів для подальшого доступу та аналізу. Цей архів допомагає лікарям
моніторити хід лікування та забезпечує належну документацію щодо медичного
стану пацієнтів.
Конфіденційність даних забезпечує захист особистих та медичних даних
пацієнтів від несанкціонованого доступу. Система має високий рівень захисту
даних та відповідає вимогам законодавства про конфіденційність медичної
інформації.
Рисунок 2.1 - Діаграма класів спроектованого ПЗ
Словник предметної області.
На основі моделювання предметної області було розроблено словник
предметної області.
16
ЧДТУ 242054.007 ПЗ
Пацієнт - ця сутність включає інформацію про особу, яка шукає медичну
допомогу через бота. Вона може мати такі атрибути, як ім'я, прізвище, контактні
дані, а також історію медичних записів та рецептів.
Лікар - володіє основною медичною інформацією та має можливість давати
консультації, призначати рецепти та направлення.
Реєстрація - цей процес передбачає можливість пацієнтів та лікарів
створювати облікові записи у системі бота. Вона має забезпечувати безпеку та
конфіденційність даних.
Призначення - лікар має можливість видавати рецепти та направлення
пацієнтам через бота. Ця функція передбачає генерацію відповідних документів та
їхню відправку користувачам.
Запис на прийом - пацієнти можуть записуватися на прийом до лікаря через
бота. Цей процес передбачає вибір доступного часу та дати прийому.
Медичний запис – інформація про медичні консультації, процедури та
рецепти, надані пацієнтам, зберігається у вигляді медичних записів. Кожен запис
має вказувати дату, час та зміст консультації.
Архів медичних записів - це сховище, де зберігається історія медичних
записів пацієнтів для подальшого доступу та аналізу.
Конфіденційність - Забезпечення захисту особистих та медичних даних
пацієнтів від несанкціонованого доступу. Система повинна мати високий рівень
захисту даних та відповідати вимогам законодавства про конфіденційність
медичної інформації.
2.1.2 Елементи моделювання предметної області
У моделюванні предметної області "Розробка Telegram-боту сімейного
лікаря" ключовим етапом є визначення елементів, які складають систему та їхніх
взаємозв'язків. Для цього використовуються класи, які є узагальненими об'єктами,
групованими залежно від їхньої структури даних та поведінки.
Класифікація класів у моделі предметної області дозволяє логічно
організувати роботу з кодом програми та уникнути дублювання понять. На перший
17
ЧДТУ 242054.007 ПЗ
етап створюються діаграми класів, що представляють систему в цілому. У процесі
роботи над варіантами використання діаграми поступово уточнюються.
У моделі предметної області слід враховувати, що іменники та іменні групи
перетворюються на об'єкти та атрибути, а дієслова та дієслівні групи - на операції
та асоціації. Цей процес сприяє створенню чіткої та зрозумілої моделі, що
відображає всі аспекти системи.
Основні елементи моделі предметної області включають:
Пацієнт - клас, що відображає особу, яка шукає медичну допомогу через бот.
Він містить атрибути, такі як особисті дані, історія медичних записів тощо.
Лікар - клас, що представляє медичного працівника, який надає консультації
та призначає рецепти та направлення через бот. Містить дані про спеціалізацію,
контактну інформацію тощо.
Медичні записи - клас, що містить інформацію про проведені консультації,
процедури та призначені рецепти для кожного пацієнта.
Рецепти та направлення - клас, що містить інформацію про призначені
лікарем рецепти та направлення для пацієнтів через бот.
Запис на прийом - клас, що дозволяє пацієнтам записатися на прийом до
лікаря через бот.
Архів медичних записів - клас, що забезпечує зберігання історії медичних
записів пацієнтів для подальшого доступу та аналізу.
У моделі предметної області необхідно також врахувати елементи
конфіденційності даних та їхній захист від несанкціонованого доступу.
Для моделювання предметної області та проектування системи
використовується мова UML (Unified Modeling Language), яка надає
стандартизовані засоби для візуалізації та аналізу програмних систем [5].
18
ЧДТУ 242054.007 ПЗ
Рисунок 2.2 - Основні графічні символи UML[6]
19
ЧДТУ 242054.007 ПЗ
Рисунок 2.3 – Єднальні елементи UML [6]
При проєктуванні програмної реалізації було розроблено основні діаграми з
використанням основних графічних символів UML.
Рисунок 2.4 - Основні діаграми UML [6]
2.1.3 Робоча область моделювання
20
ЧДТУ 242054.007 ПЗ
Робоча область моделювання є ключовим етапом проектування програмного
забезпечення системи "Розробка Telegram-боту сімейного лікаря". Цей етап
передбачає розгортання середовища та інструментів, які будуть
використовуватися для створення моделі предметної області, а також для розробки
та впровадження програмного продукту. До робочої області моделювання входять
наступні складові:
Розгортання середовища розробки - для ефективного моделювання та
програмування системи необхідно встановлено та налаштовано середовище
розробки, яке підтримує мови програмування та забезпечує розширені можливості
для роботи з кодом [7].
Використання інструментів моделювання – для створення моделі предметної
області використовуються спеціалізовані інструменти моделювання, такі як UML-
редактори.
Застосування методів та прийомів моделювання - під час роботи над моделлю
предметної області використовуються різноманітні методи та прийоми
моделювання, такі як аналіз вимог, ідентифікація класів та їхніх взаємозв'язків,
розробка діаграм класів та інших артефактів моделі.
Створення прототипів та тестування рішень - під час моделювання були
розроблені прототипи окремих компонентів системи для перевірки їхньої
працездатності та відповідності вимогам.
Нижче наведено деталізацію процесу моделювання.
Початковий етап моделювання передбачав аналіз вимог до системи. Це
включало вивчення функціональних та нефункціональних вимог, вимог щодо
інтерфейсу користувача, вимог до безпеки та забезпечення конфіденційності, а
також вимог до швидкодії та масштабованості системи.
Одним з основних інструментів моделювання було створення діаграм класів за
допомогою мови UML. На цій діаграмі відображалися класи об'єктів у системі, їх
атрибути та методи, а також взаємозв'язки між ними.
Під час моделювання визначалися основні класи об'єктів, які представляли
собою ключові сутності в системі.
21
ЧДТУ 242054.007 ПЗ
Були визначені взаємозв'язки між класами, які відображали зв'язки та
взаємодію між об'єктами у системі. Наприклад, у класі "Лікар" може бути
асоційований з класом "Пацієнт" через відношення "прикріплення".
Окрім діаграм класів, також створювалися інші види діаграм, такі як діаграми
послідовності для відображення послідовності операцій у системі, діаграми
активності для моделювання процесів роботи системи тощо.
Моделювання проводилося за ітеративним методом, що дозволяло поступово
уточнювати та розширювати модель на основі отриманих результатів та зміни
вимог.
Для створення діаграм використовувалися різноманітні засоби та програми, які
підтримують стандарт UML. Це дозволило зручно та ефективно створювати та
підтримувати модель.
Для кращого розуміння предметної області було розророблено відповідну
діаграму (рис 2.5).
Рисунок 2.5 Модель робочої області телеграм-боту сімейного лікаря
2.2 Формування та аналіз вимог
В цьому розділі будуть розглянуті первинні та детальні вимоги.
2.2.1 1 Формування вимог до програмного забезпечення. Первинні і детальні
вимоги. Вимоги замовника і розробника. Функціональні та нефункціональні
вимоги
22
ЧДТУ 242054.007 ПЗ
Формування вимог до програмного забезпечення
Первинні і детальні вимоги
В процесі визначення вимог до системи "Telegram-бот сімейного лікаря"
були враховані як первинні, так і детальні вимоги, які визначають
функціональність та характеристики системи
ПЕРВИННІ ВИМОГИ:
система повинна надавати можливість реєстрації як лікарів, так і пацієнтів
з введенням основних даних, таких як ім'я, прізвище, адреса електронної
пошти тощо.
функціонал системи повинен дозволяти лікарям прикріплювати пацієнтів
до свого акаунту для подальшого обслуговування.
пацієнти повинні мати можливість записатися на прийом до лікаря через
telegram-бот, вказавши зручну дату та час.
лікарі повинні мати можливість виписувати рецепти для пацієнтів,
вказуючи необхідні медикаменти та їх дозування.
функціонал системи повинен дозволяти лікарям виписувати направлення
до інших спеціалістів або медичних закладів для додаткового обстеження
чи лікування.
ДЕТАЛЬНІ ВИМОГИ:
система повинна забезпечувати безпечну аутентифікацію та авторизацію
користувачів, використовуючи захищені механізми аутентифікації.
система повинна дотримуватися вимог щодо захисту персональних даних
пацієнтів, включаючи використання шифрування та інших методів
захисту інформації.
telegram-бот повинен мати зручний та інтуїтивно зрозумілий інтерфейс
користувача для легкого використання як лікарями, так і пацієнтами.
система повинна бути масштабованою та надійною, забезпечуючи
стабільну роботу навіть при великій кількості користувачів та трафіку.
Вимоги замовника і розробника.
23
ЧДТУ 242054.007 ПЗ
Функціональні та нефункціональні вимоги
Вимоги замовника та розробника до системи "Розробка Telegram-боту
сімейного лікаря" можна розділити на функціональні та нефункціональні
вимоги.
Функціональні вимоги:
Реєстрація користувачів:
замовник: можливість реєстрації лікарів та пацієнтів з введенням
основних персональних даних.
розробник: реалізація функціоналу для реєстрації користувачів з
обов'язковим заповненням певних полів та перевіркою введених даних.
Прикріплення пацієнтів до лікаря:
замовник: можливість лікарів прикріплювати пацієнтів до свого акаунту
для подальшого обслуговування.
розробник: реалізація функції, яка дозволяє лікарям прикріплювати
пацієнтів до свого акаунту за допомогою ідентифікатора користувача.
Запис на прийом:
Замовник: Можливість пацієнтів записуватися на прийом до лікаря через
Telegram-бот.
Розробник: Реалізація функції запису на прийом, включаючи можливість
вибору дати та часу прийому.
Виписання рецептів та направлень:
Замовник: Можливість лікарів виписувати рецепти на ліки та направлення
до інших лікарів чи медичних закладів.
Розробник: Реалізація функціоналу для виписування рецептів та
направлень, включаючи можливість введення необхідних даних та
генерацію відповідних документів.
Нефункціональні вимоги:
Безпека:
Замовник: Забезпечення високого рівня безпеки персональних даних
24
ЧДТУ 242054.007 ПЗ
пацієнтів та конфіденційності медичної інформації.
Розробник: Використання шифрування для захисту передачі даних між
користувачами та сервером бота.
Інтерфейс:
Замовник: Розробка зручного та інтуїтивно зрозумілого інтерфейсу
користувача для легкого використання бота.
Розробник: Побудова інтерфейсу з урахуванням вимог до доступності та
ергономіки, що дозволить користувачам з легкістю взаємодіяти з
системою.
Масштабованість та надійність:
Замовник: Забезпечення стабільної та надійної роботи системи навіть при
великій кількості користувачів та трафіку.
Розробник: Використання оптимізованих архітектурних рішень та
тестування системи на масштабованість для запобігання можливих
проблем з продуктивністю та надійністю.
2.2.2 Формування вимог за допомогою діаграми прецедентів
Формування вимог за допомогою діаграм прецедентів є важливим етапом у
процесі аналізу та визначення функціональних вимог до системи "Розробка
Telegram-боту сімейного лікаря". Діаграми прецедентів допомагають
ідентифікувати основні функції та функціональні можливості системи, а також
визначити взаємодію між користувачами та самою системою [12]. На рисунку 2.6
наведено варіанти графічного позначення акторів на діаграмах прецендентів.
Рисунок 2.6 – Варіанти графічного позначення актора:
а – у вигляді «чоловічка»; б — у вигляді фігури;
25
ЧДТУ 242054.007 ПЗ
В проєктованій системи визначено 2 актора:
Сімейний лікар - медичний працівник, який має кваліфікацію та дозвіл на
надання медичної допомоги. У контексті розробки Telegram-боту сімейного
лікаря, лікар виступає як актор, який надає медичні послуги пацієнтам через цю
систему. Він може приймати пацієнтів, виписувати рецепти, виписувати
направлення до інших лікарів або медичних закладів, а також вести медичну
документацію. Лікар має доступ до певного функціоналу боту, що дозволяє йому
здійснювати ці дії.
Пацієнт - це особа, яка потребує медичної допомоги та обслуговування. У
контексті розробки Telegram-боту сімейного лікаря, пацієнт виступає як актор,
який користується системою для отримання медичних послуг та керування своїм
здоров'ям. Він може записуватися на прийом до лікаря, отримувати рецепти,
отримувати направлення до інших лікарів або медичних закладів, а також
отримувати консультації з питань здоров'я.
Нижче наведено формування вимог за допомогою діаграми прецендентів
(рис. 2.7).
Рис 2.7 - Діаграма прецендентів телеграм-боту сімейного лікаря
26
ЧДТУ 242054.007 ПЗ
2.3 Проектування логічної структури програмного комплексу
2.3.1 Діаграми класів
Діаграма класів є однією з ключових візуальних моделей у мові UML,
призначеною для відображення структури системи та взаємозв'язків між класами
[8]. Кожен клас у діаграмі класів представляє концепцію або об'єкт у системі, який
має свої атрибути та методи. Зв'язки між класами на діаграмі класів відображають
асоціації, агрегації, композиції та спадкування. Асоціація вказує на зв'язок між
об'єктами двох класів, який може бути однозв'язним або багатозв'язним. Агрегація
та композиція вказують на відношення ціле-частина між класами, де агрегація є
слабшим зв'язком, ніж композиція. Спадкування використовується для визначення
класу, який успадковує властивості та методи іншого класу, що є батьківським [8].
Нижче на рисунку представлена діаграма класів програмного забезпечення
telegram-боту.
Написати діаграму класів без атрибутів. Розписати логіку атрибутів які
входять в кожний клас
Рисунок 2.8 – Діаграмма класів ПЗ телеграм-боту
27
ЧДТУ 242054.007 ПЗ
Рисунок 2.9 – Діаграмма класів ПЗ телеграм-боту без атрибутів
AuthService відповідає за авторизацію користувачів, перевірку існування
лікарів та пацієнтів. AuthMenu обробляє повідомлення та відкриває контекст бота
для авторизації. Menu керує основним меню, обробляє повідомлення, створює
кнопки та клавіатури. PatientMenu відкриває підменю медичної картки, направлень
та рецептів пацієнтів. PatientRecipesMenu відкриває контекст бота для роботи з
рецептами пацієнтів. PatientMecardMenu відкриває контекст бота для медичної
картки пацієнтів. PatientReferralsMenu відкриває контекст бота для направлень
пацієнтів. PatientReceptionMenu обробляє повідомлення та відкриває контекст бота
для прийомів пацієнтів.
DoctorMenu відкриває підменю пацієнтів та створення пацієнта для лікарів.
DoctorMenuPatients відкриває контекст бота для роботи з пацієнтами лікаря.
DoctorCreatePatient обробляє повідомлення та відкриває контекст бота для
створення нового пацієнта. DoctorReceptionMenu обробляє повідомлення та
відкриває контекст бота для прийомів лікаря. DoctorService керує рецептами,
направленнями, пацієнтами та користувачами для лікарів.
28
ЧДТУ 242054.007 ПЗ
2.3.2 Діаграми пакетів
Діаграма пакетів у розробці Telegram-боту "Сімейний лікар" допомагає
систематизувати функціональність за окремими модулями, зменшує складність
системи та полегшує її розуміння для розробників [10]. Вона також сприяє
модульності та розширюваності системи, визначає інтерфейси для взаємодії з
зовнішніми сервісами та допомагає у плануванні розробки.
Нижче висвітлено розроблену діаграму пакетів спроектованої системи.
Рисунок 2.10 – Діаграма пакетів
2.4 Архітектурне проектування
2.4.1 Діаграма компонентів
Було розроблено діаграму компонентів, яка слугує для візуалізації окремих
функціональних блоків та залежностей між ними. Вона допомагає ідентифікувати
та організувати компоненти програмної системи, такі як контролери, сервіси,
моделі даних тощо. Ця діаграма полегшує розуміння структури системи та
29
ЧДТУ 242054.007 ПЗ
розподілу функціональності між різними компонентами. Крім того, вона сприяє
модульності та підтримує гнучкість системи, дозволяючи легко вносити зміни або
розширювати її функціональність.
Рис 2.13 - Діаграма компонентів для телеграм боту сімейного лікаря
2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма
розгортання
Розгортання телеграм-бота - це процес встановлення та налаштування всіх
компонентів системи, необхідних для того, щоб бот міг працювати та взаємодіяти
з користувачами через платформу Telegram. Цей процес включає в себе підготовку
програмного забезпечення, налаштування середовища виконання, підготовку та
конфігурацію бази даних, розгортання коду та його інтеграцію з платформою
Telegram.
Першим кроком у розгортанні телеграм-бота стала підготовка середовища
розробки. Це включило встановлення необхідного програмного забезпечення,
такого як Node.js, npm (менеджер пакетів для TypeScript), інструментів для роботи
30
ЧДТУ 242054.007 ПЗ
з базою даних, а також редактора коду для розробки програм.
Наступним кроком стало створення бота. Для створення бота в Telegram
необхідно використовувати їх API та отримати API-ключ бота. Цей ключ
слугуватиме ідентифікатором вашого бота в Telegram. Після отримання ключа,
створюється новий бот через Telegram BotFather, який надасть унікальний токен
для кожного бота .
Рисунок 2.14 – Діаграма розгортання програмної системи для телеграм боту
сімейного лікаря
2.5 Моделювання поведінки системи
Нижче розглягуто процес моделювання поведінки проєктованого
програмного комплексу.
31
ЧДТУ 242054.007 ПЗ
2.5.1 Діаграма діяльності
При модолюванні поведінки системи було створено діаграми діяльності.
Діаграма діяльності у розробці Telegram-боту "Сімейний лікар" використовується
для моделювання послідовності дій або процесів, які відбуваються під час
взаємодії з користувачем чи системою [9]. Вона дозволяє уявити кожен крок у
виконанні конкретної операції та ілюструє поток контролю між різними діями. Ця
діаграма допомагає уточнити вимоги до системи, визначити послідовність
взаємодії між користувачем та системою, а також ідентифікувати можливі
проблеми або неоднозначності у процесах взаємодії.
Рисунок 2.15 – Діаграма діяльності для обрання лікаря
32
ЧДТУ 242054.007 ПЗ
Рисунок 2.16 – Діаграма діяльності для перегляду записів на прийом
33
ЧДТУ 242054.007 ПЗ
Рисунок 2.17 – Діаграма діяльності для створення рецепту
34
ЧДТУ 242054.007 ПЗ
2.5.2 Діаграма послідовності
При проектуванні було створено діаграми послідовностей. Діаграма
послідовності при проектуванні програмного продукту використовується для
візуалізації послідовності взаємодії між об'єктами в системі під час виконання
конкретного сценарію використання. Вона дозволяє проаналізувати взаємодію між
різними частинами системи та ілюструє порядок виконання різних дій та операцій.
Ця діаграма допомагає уточнити вимоги до системи, виявити потрібні комунікації
між об'єктами та ідентифікувати можливі проблеми або невідповідності у логіці
системи. Крім того, вона є ефективним інструментом для комунікації між
розробниками та стейкхолдерами, оскільки дозволяє швидко зрозуміти логіку
взаємодії між різними частинами системи без детального технічного опису.
Рисунок 2.18 – Діаграма послідовності реєстрація пацієнта
35
ЧДТУ 242054.007 ПЗ
Рисунок 2.19 – Діаграма послідовності для виписання рецептів
2.5.3 Діаграма комунікації
Наступним кроком при проєктуванні системи стала розробка діаграми
комунікації, яка використовується для візуалізації взаємодії між об'єктами системи
під час виконання певного сценарію використання. Ця діаграма фокусується на
обміні повідомленнями між об'єктами та ілюструє порядок цього обміну під час
виконання конкретної операції чи функції. Вона дозволяє зрозуміти, як об'єкти
взаємодіють між собою для досягнення певної мети та які саме повідомлення вони
обмінюються. Ця діаграма також допомагає ідентифікувати можливі проблеми або
невідповідності у взаємодії між об'єктами та з'ясувати потреби у подальшій
деталізації вимог до системи. Крім того, вона є ефективним інструментом для
комунікації між розробниками та стейкхолдерами, оскільки дозволяє зрозуміти, як
36
ЧДТУ 242054.007 ПЗ
саме об'єкти спілкуються між собою в системі та як це впливає на її
функціонування.
Нижче наведені діаграми комунікації для сімейного лікаря та пацієнта.
Рисунок 2.19 – Діаграма комунікації пацієнта з сімейним лікарем
Рисунок 2.21 – Діаграма комунікації пацієнта з сімейним лікарем
37
ЧДТУ 242054.007 ПЗ
2.5.4 Діаграма скінченного автомату
Розроблена діаграма скінченного автомату використовується для
моделювання різних станів системи та переходів між ними. Вона дозволяє
визначити можливі стани системи, умови переходу між ними та дії, які
відбуваються під час кожного переходу [11]. При розробці цієї діаграми стало
зрозуміло логіку поведінки системи та визначено правила її функціонування.
Нижче представлена діаграма скінченного автомату для можливих станів та
переходів під час роботи телеграм боту.
Рисунок 2.22 – Діаграмма скінченного автомату для станів та переходів при
роботі Telegram-боту сімейного лікаря
38
ЧДТУ 242054.007 ПЗ
Висновки до розділу 2
Було проведено моделювання предметної області, яке включало в себе
визначення ключових класів об'єктів та їх взаємозв'язків. Це дало змогу створити
чітку та зрозумілу модель, що відображає всі аспекти системи.
Проектування логічної структури програмного комплексу базувалося на
архітектурному шаблоні MVC (Model-View-Controller). Було розроблено діаграми
класів, діаграми пакетів, діаграми компонентів, діаграми розгортання та діаграми
поведінки системи.
Формування вимог за допомогою діаграм прецедентів дозволило визначити
основні функції та функціональні можливості системи, а також взаємодію між
користувачами та системою. Ці вимоги були враховані при розробці архітектури
та інтерфейсу системи.
39
ЧДТУ 242054.007 ПЗ
3 РОЗРОБКА ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ
3.1 Розробка програмного комплексу
3.1.1 Обґрунтування вибору засобів реалізації
Обґрунтування вибору засобів реалізації полягає в аналізі доступних
інструментів та технологій з урахуванням їхніх переваг і недоліків у контексті
конкретної розробки. При виборі засобів реалізації Telegram-боту сімейного лікаря
враховувалися такі фактори, як підтримка необхідного функціоналу, зручність у
використанні, швидкодія та розширюваність платформи. Крім того, враховувалися
можливості інтеграції з іншими сервісами, безпека та можливість масштабування
системи.
Для розробки Telegram-боту сімейного лікаря був обраний опитамальний
стек технологій, в нього входять : TypeScript, node.js, Grammy, Prisma.
При Telegram-боту сімейного лікаря мова TypeScript виявилась вкрай
корисним інструментом. Одна з головних переваг TypeScript полягає в його
статичній типізації, яка допомагала виявляти потенційні помилки ще на етапі
розробки, що забезпечило високу надійність та стабільність роботи боту [1].
Використання типів дозволило збільшити чіткість та зрозумілість коду, а також
полегшило роботу над проектом.
Ще однією важливою перевагою TypeScript стала можливість використання
сучасних функцій JavaScript, які були корисними в контексті розробки Telegram-
боту, таких як асинхронні функції або розширені методи масивів. Це дозволило
використовувати найновіші можливості JavaScript для ефективної реалізації
функціональності боту.
Також, TypeScript забезпечив велику сумісність з існуючим JavaScript-
кодом, що може бути особливо корисним у випадках, коли вже існують певні
частини програми, реалізовані на JavaScript [1]. Це дозволило поступово
переходити до TypeScript, додавати типізацію до існуючих модулів та
покращувати їх зручність та надійність. Загалом, використання TypeScript у
розробці Telegram-боту сімейного лікаря допомогло забезпечити стабільну та
40
ЧДТУ 242054.007 ПЗ
ефективну роботу програми, зменшити кількість помилок.
Node.js став важливим компонентом у розробці Telegram-боту сімейного
лікаря з кількох причин. По-перше, Node.js є платформою, яка дозволяє
виконувати TypeScript на сервері, що зробило його ідеальним інструментом для
створення веб-сервера для бота [2]. Використання однієї мови програмування як
на фронтенді, так і на бекенді, спростило розробку та підтримку коду.
По-друге, Node.js забезпечив асинхронність та події зворотного виклику, що
дозволило обробляти багато запитів одночасно без блокування виконання
програми
По-третє, Node.js має велику кількість модулів у відкритому доступі, що
дозволило швидко та ефективно додавати різноманітні функції до свого боту.
Наявність різноманітних модулів для роботи з мережею, базами даних,
шифруванням та іншими аспектами розробки полегшило створення Telegram-бота
та забезпечило його функціональність.
Фреймворк має велику кількість допоміжних модулів і middleware, які
полегшили розробку та забезпечили різноманітні можливості. Завдяки middleware
стало можливо легко додавати функціональність, таку як обробка запитів,
аутентифікація, обробка помилок тощо.
Крім того, Node.js є добре документованим та має велику спільноту
користувачів, що дозволяє легко знаходити відповіді на питання та отримувати
допомогу в разі необхідності. Його широке використання в галузі веб-розробки
свідчить про його надійність та ефективність.
Prisma ORM відіграла ключову роль у забезпеченні ефективності та
надійності обробки даних. Завдяки простому та зрозумілому синтаксису Prisma,
швидко визначено схему даних та взаємозв'язки між ними без необхідності
написання складних SQL-запитів [3]. Це дозволило прискорити процес розробки
та зменшити кількість можливих помилок.
Prisma підтримує різні системи управління базами даних, що дозволило
вибрати найбільш придатний варіант для конкретного проекту. Для розробки
Telegram-боту сімейного лікаря використовується SQLite для зберігання медичних
41
ЧДТУ 242054.007 ПЗ
даних.
Підтримка типів даних TypeScript у Prisma дозволила забезпечити перевірку
типів та валідацію даних під час компіляції. Це допомогло уникнути потенційних
помилок та забезпечити високу надійність обробки даних.
Також було використано бібліотеку Grammy для створення Telegram-боту.
Grammy надає зручний та простий інтерфейс для створення ботів в Telegram. Її
функціональні можливості легко освоюються навіть для початківців у розробці
чат-ботів.
Grammy надає широкий набір можливостей для розробки Telegram-ботів,
включаючи обробку повідомлень, реєстрацію команд та взаємодію з API Telegram.
Бібліотека підтримує асинхронне програмування, що дозволило ефективно
обробляти багато запитів в одному потоці виконання.
Grammy підтримує TypeScript, що дозволило використовувати перевірку
типів та інші переваги цієї мови програмування у процесі розробки Telegram-ботів.
Grammy має активну спільноту розробників, а також докладну та зрозумілу
документацію, що допомогло швидко засвоїти її функціонал та ефективно
використовувати при розробці.
3.1.2 Опис структурної (функціональної) схеми
Структурна схема розробленого Telegram-боту сімейного лікаря включає в
себе взаємодію між основними компонентами системи.
Бекенд - це основний робочий двигун системи, який відповідає за логіку
обробки запитів користувачів, обробку даних та взаємодію з базою даних. Бекенд
включає в себе різні модулі.
Telegram API Integration- компонент який відповідає за взаємодію з API
Telegram для отримання та відправлення повідомлень. Він отримує вхідні
повідомлення від користувачів через Telegram та передає їх до бекенду для
подальшої обробки. Також він відповідає за відправку вихідних повідомлень
користувачам через Telegram. В базі даних зберігається вся інформація про
користувачів, їх медичні записи, призначені рецепти, нагадування та інші дані,
42
ЧДТУ 242054.007 ПЗ
необхідні для роботи системи. Бекенд взаємодіє з базою даних для зберігання та
отримання інформації.
Взаємодія між цими компонентами відбувається наступним чином: після
отримання повідомлення від користувача через Telegram, Telegram API Integration
передає це повідомлення до бекенду. Бекенд обробляє запит, взаємодіючи з базою
даних для отримання або збереження необхідної інформації, та генерує відповідь.
Після цього відповідь передається в Telegram API Integration, який відправляє її
користувачеві через Telegram. Така взаємодія забезпечує повноцінну роботу
Telegram-боту сімейного лікаря з урахуванням всіх функціональних можливостей.
Рисунок 3.1 – Структурна схема основних компонентів
43
ЧДТУ 242054.007 ПЗ
Рисунок 3.2 – Функціональна схема роботи Telegram-боту
3.1.3 Опис логічної схеми системи
Логічна схема системи Telegram-боту сімейного лікаря базується на
архітектурному шаблоні MVC (Model-View-Controller), що дозволяє розділити
логіку додатку на три основні компоненти: модель (Model), представлення (View)
та контролер (Controller).В архітектурі MVC система розділяється на три основних
компоненти: Модель - це компонент, який відповідає за обробку даних і бізнес-
логіку додатку [13]. При розробці Telegram-боту сімейного лікаря модель включає
в себе об'єкти та методи, які взаємодіють з базою даних для отримання, збереження
та обробки медичних записів, рецептів, інформації про користувачів та інше.
Модель не залежить від інтерфейсу користувача та відображення даних, що
дозволяє зберігати логіку додатку незалежною від його інтерфейсу.
Представлення - компонент, який відповідає за відображення даних
користувачу та інтерфейс взаємодії з користувачем. У випадку Telegram-боту
44
ЧДТУ 242054.007 ПЗ
сімейного лікаря представлення включає в себе текстові повідомлення, кнопки,
вікна введення даних та інші елементи, які користувач може бачити та взаємодіяти
з ними через інтерфейс Telegram. Представлення не містить бізнес-логіки та не
знає, як саме обробляються дані, а лише відображає їх користувачеві.
Контролер - Це компонент, який відповідає за обробку запитів користувачів
та взаємодію між моделлю та представленням. В розробці Telegram-боту сімейного
лікаря контролер включає в себе обробники подій, які реагують на вхідні
повідомлення від користувачів та ініціюють відповідні дії. Контролер отримує дані
від моделі, обробляє їх та передає відповідні дані для відображення у
представленні.
Рисунок 3.3 – Логічна схема проекту на основі архітектурної парадигми MVC
[13].
45
ЧДТУ 242054.007 ПЗ
3.1.4 Розробка бази даних
Під час розробки бази даних для Telegram-боту сімейного лікаря було
використано SQLite та Prisma для забезпечення ефективного та надійного
зберігання та керування даними. Вибір цих технологій був обґрунтований їхньою
простотою використання, широкою підтримкою та високою продуктивністю.
SQLite використовується для локального зберігання даних користувачів та іншої
статичної інформації, тоді як Prisma використовується для роботи з
централізованою базою даних, що забезпечує збереження та доступ до важливої
інформації про пацієнтів та медичні дані.
Розробка бази даних почалася з аналізу вимог до системи та розробки
структури даних, яка відображає основні сутності та їх взаємозв'язки. Далі було
розроблено схеми бази даних з використанням SQLite та Prisma, визначено типи
даних, обмеження цілісності та інші параметри для кожної таблиці та поля.
Після цього було проведено реалізацію схеми бази даних з використанням
відповідних мов програмування та інструментів розробки. Було створено
необхідні таблиці, включено зв'язки між ними та реалізовано необхідні операції
збереження, оновлення та видалення даних.
Ця модель даних розроблена з використанням мови Prisma Schema та описує
структуру бази даних для Telegram-боту сімейного лікаря. Нижче наведено опис
кожної з таблиць та їх взаємозв'язки:
Таблиця Session відображає сесії користувачів та містить наступні поля:
id: унікальний ідентифікатор сесії
key: унікальний ключ сесії
value: значення сесії
Таблиця Patient представляє дані про пацієнтів і включає такі поля:
id: унікальний ідентифікатор пацієнта
chatid: ідентифікатор чату пацієнта в Telegram
telegramId: ідентифікатор користувача в Telegram
fullName: повне ім'я пацієнта
46
ЧДТУ 242054.007 ПЗ
birth: дата народження пацієнта
bloodGroup: група крові пацієнта
phoneNumber: номер телефону пацієнта
doctorId: ідентифікатор лікаря, до якого прикріплений пацієнт
receptions: список прийомів пацієнта
recipe: список рецептів пацієнта
referrals: список направлень пацієнта
Таблиця Doctor містить дані про лікарів та включає наступні поля:
id: унікальний ідентифікатор лікаря
phoneNumber: номер телефону лікаря
username: ім'я користувача лікаря в Telegram
fullname: повне ім'я лікаря
patients: список пацієнтів, яким призначено цей лікар
receptions: список прийомів, проведених цим лікарем
recipes: список рецептів, виписаних цим лікарем
referrals: список направлень, виданих цим лікарем
Таблиця Recipe відображає дані про рецепти та включає наступні поля:
id: унікальний ідентифікатор рецепту
doctorId: ідентифікатор лікаря, який виписав рецепт
patientId: ідентифікатор пацієнта, для якого призначено рецепт
text: текст рецепту
Таблиця Referral містить дані про направлення та має наступні поля:
id: унікальний ідентифікатор направлення
text: текст направлення
date: дата видання направлення
doctorId: ідентифікатор лікаря, який видав направлення
patientId: ідентифікатор пацієнта, для якого призначено направлення
Таблиця Reception відображає дані про прийоми пацієнтів та включає такі
поля:
47
ЧДТУ 242054.007 ПЗ
id: унікальний ідентифікатор прийому
date: дата та час прийому
doctorId: ідентифікатор лікаря, який проводить прийом
patientId: ідентифікатор пацієнта, який зареєстрований на прийом
finished: ознака завершення прийому
Ця модель бази даних дозволяє зберігати та управляти інформацією про
пацієнтів, лікарів, рецепти, направлення та прийоми, що дозволяє Telegram-боту
сімейного лікаря ефективно взаємодіяти з користувачами та забезпечує
збереження медичних даних відповідно до вимог системи.
Рисунок 3.4 – Діаграма - модель «сутність-зв'язок»
3.1.5 Розробка інтерфейсу користувача
48
ЧДТУ 242054.007 ПЗ
Для розробки інтерфейсу користувача Telegram-боту сімейного лікаря
використовувалися стандартні технології TelegramAPI, які дозволили створити
зручний та ефективний інтерфейс для взаємодії з ботом. Інтерфейс був
спроектований з урахуванням потреб користувачів та особливостей функціоналу
боту, забезпечуючи зручний та інтуїтивно зрозумілий спосіб взаємодії.
Основною метою розробки інтерфейсу було створення зручного середовища
для користувачів, де вони могли б надсилати запити до боту, отримувати від нього
відповіді та користуватися різноманітними функціями, доступними через бота.
Для досягнення цієї мети використовувалися різноманітні елементи інтерфейсу,
такі як кнопки, текстові поля, форми тощо, які дозволяли користувачам легко та
зручно взаємодіяти з ботом.
Розроблений інтерфейс був оформлений у відповідності з сучасними
тенденціями дизайну та враховував вимоги щодо зручності та привабливості для
користувачів. Для цього використовувалися стилі та різноманітні бібліотеки та
фреймворки, що дозволили створити стильний та ефективний інтерфейс.
У процесі розробки було приділено увагу не лише дизайну та зовнішньому
вигляду, але й функціональності та зручності використання. Інтерфейс був
розроблений з урахуванням потреб користувачів та вимог щодо простоти та
легкості використання, щоб забезпечити їм максимальний комфорт при взаємодії
з ботом.
Також були використані стандартні засоби Telegram API для розробки
дизайну, за допомогою яких було створено текстові та медіа-елементіи, а також
елементи для керування їх відображенням у чатах та групах.
Telegram API підтримує відправку різноманітних медіа-елементів, таких як
зображення, відео, аудіо та документи. Це було використано для створення
різноманітного контенту в боті.
За допомогою Telegram API можна було створено кнопки, які
використовуються для взаємодії з ботом. Це стало в нагоді для створення
інтерактивних діалогів та меню для користувачів.
Telegram API забезпечив можливість розробки дизайну, який став
49
ЧДТУ 242054.007 ПЗ
оптимізованим для різних типів пристроїв та платформ, включаючи мобільні
пристрої, планшети та настільні комп'ютери.
Загалом, розроблений інтерфейс користувача став важливою складовою
Telegram-боту сімейного лікаря, забезпечуючи користувачам зручну та ефективну
платформу для взаємодії з ботом та отримання необхідної медичної інформації та
послуг.
На рисунках нижче наведено розроблений інтерфейс користувача
Telegram боту:
Рисунок 3.5 – Меню реєстарції
50
ЧДТУ 242054.007 ПЗ
Рисунок 3.6 – Медична картка пацієнта
Рисунок 3.7 – Головне меню сімейного лікаря
51
ЧДТУ 242054.007 ПЗ
Рисунок 3.8 – Список пацієнтів сімейного лікаря
Рисунок 3.9 – Список рецептів пацієнта
52
ЧДТУ 242054.007 ПЗ
Рисунок 3.10 – Список направлень пацієнта
3.1.6 Опис розробки програмних компонентів
Розроблений програмний продукт включає в себе такі модулі – Telegram-бот,
бекенд та базу даних.
Telegram-бот відповідає за взаємодію з користувачами через месенджер
Telegram. Він отримує запити від користувачів, передає їх до бекенду для обробки
та повертає відповіді назад користувачам. Telegram-бот використовує API
Telegram для отримання та надсилання повідомлень.
БД відповідає за збереження та управління даними, необхідними для роботи
Telegram-бота та бекенду. Вона включає в себе дані про користувачів, їх медичні
записи, рецепти, направлення та інші дані. База даних забезпечує постійний доступ
до даних для всіх компонентів системи.
Бекенд відповідає за обробку запитів від Telegram-бота, виконання бізнес-
логіки та взаємодію з базою даних. Він приймає запити від Telegram-бота,
обробляє їх, виконує потрібні операції з базою даних та повертає відповіді
53
ЧДТУ 242054.007 ПЗ
Telegram-боту для відображення користувачам. Бекенд також включає в себе
модулі автентифікації та авторизації користувачів.
Нижче наведено детальний опис взаємодії модулів програмного продукту.
Telegram-бот та користувачі:
Користувачі надсилають запити до Telegram-бота через інтерфейс
Telegram Messenger.
Telegram-бот отримує ці запити та обробляє їх, розпізнаваючи команди
або повідомлення від користувачів.
Після обробки запиту Telegram-бот визначає, який функціонал потрібно
виконати та яку інформацію необхідно отримати з бекенду.
Бекенд та Telegram-бот:
Після отримання запиту від Telegram-бота бекенд проводить перевірку
на валідність та безпеку запиту.
Потім бекенд виконує необхідні операції відповідно до отриманого
запиту. Це може включати пошук інформації в базі даних, обробку запиту
лікаря, формування відповідей тощо.
Після завершення обробки бекенд генерує відповідь та надсилає її
Telegram-боту.
Бекенд та база даних:
Під час обробки запиту від Telegram-бота бекенд може виконувати різні
операції з базою даних.
Це включає пошук, оновлення, видалення або додавання записів в базі
даних в залежності від характеру запиту.
Результати операцій з базою даних обробляються бекендом та
використовуються для формування відповіді, яку бекенд надсилає
Telegram-боту.
3.2 Тестування системи
У розділі тестування програмного забезпечення розгляyто перевірку
правильності та надійності роботи системи, яка включає модульне тестування, де
54
ЧДТУ 242054.007 ПЗ
окремі компоненти перевіряються на відповідність функціональним вимогам.
Інтеграційне тестування перевіряє взаємодію між компонентами. Системне
тестування охоплює перевірку повної інтегрованої системи на відповідність
специфікаціям. Приймальне тестування оцінює систему з точки зору кінцевого
користувача, підтверджуючи відповідність очікуванням.
3.2.1 Модульне тестування
Після розробки модулів Telegram-боту сімейного лікаря та його інтеграції з
бекендом та базою даних, було проведено широкий спектр модульних тестів з
метою перевірки функціональності та стабільності роботи програмного продукту.
Під час проведення тестування модулів Telegram-боту було розроблено
тестові сценарії для кожного функціонального модулю Telegram-боту, включаючи
реєстрацію лікарів та пацієнтів, запис на прийом, виписку рецептів та направлень,
а також управління призначеннями. Тестування здійснювалося з використанням
фреймворка для тестування Node.js, що дозволило автоматизувати процес та
забезпечити повноту та точність перевірки кожного функціонального модулю.
При проведенні тестування інтеграції між модулями було успішно пройдено
модульні тести Telegram-боту та окрему перевірки роботи бекенду та бази даних,
було проведено тестування інтеграції між цими компонентами. В рамках
тестування перевірялася правильність передачі даних між Telegram-ботом та
бекендом, а також коректність зберігання та оновлення даних в базі даних під час
взаємодії з Telegram-ботом.
Також було проведено тестування виняткових ситуацій, для забезпечення
стабільності та надійності роботи програмного продукту були проведені модульні
тести на виявлення виняткових ситуацій, таких як помилкові запити від
користувачів, втрата зв'язку з сервером Telegram або недоступність бази даних. Ці
тести дозволили виявити та виправити потенційні проблеми, що можуть
виникнути у реальних умовах експлуатації програмного продукту.
Завершальним етапо модульного тестування стало тестування
продуктивності та завантаження. Для перевірки продуктивності та стабільності
55
ЧДТУ 242054.007 ПЗ
роботи програмного продукту під час максимального навантаження були
проведені тести, що моделювали одночасну роботу великої кількості користувачів.
Результати цих тестів дозволили виявити слабкі місця системи та прийняти
відповідні заходи для їх виправлення та оптимізації.
У результаті проведення модульного тестування було підтверджено
стабільність та надійність роботи програмного продукту "Telegram-бот сімейного
лікаря" та його відповідність вимогам та очікуванням замовника.
Нижче наведено приклад розробленого модульного тесту :
import { FamilyDoctorBot } from './FamilyDoctorBot'; FamilyDoctorBot -
describe('FamilyDoctorBot', () => {
let bot: FamilyDoctorBot;
beforeEach(() => {
bot = new FamilyDoctorBot();
});
it('should greet new users', () => {
const greeting = bot.greet();
expect(greeting).toContain('Welcome to Family Doctor!');
});
it('should return a list of available services', () => {
const services = bot.listServices();
expect(services).toContain('1. Schedule an appointment');
expect(services).toContain('2. Ask a medical question');
expect(services).toContain('3. View medical records');
});
it('should schedule an appointment', () => {
56
ЧДТУ 242054.007 ПЗ
const appointmentDate = '2024-05-10';
const appointmentTime = '10:00';
const patientName = 'John Doe';
const confirmation = bot.scheduleAppointment(patientName,
appointmentDate, appointmentTime);
expect(confirmation).toContain('Your appointment is scheduled');
});
it('should provide medical advice', () => {
const medicalQuestion = 'What should I do if I have a fever?';
const advice = bot.provideAdvice(medicalQuestion);
expect(advice).toContain('Please consult your doctor');
});
it('should access medical records', () => {
const patientName = 'John Doe';
const records = bot.accessMedicalRecords(patientName);
expect(records).toBeDefined();
});
});
Рисунок 3.11 – Результат виконання модульного тесту
57
ЧДТУ 242054.007 ПЗ
Таблиця 3.1
Результати модульного тестування
Компонент Результат
index.js Успішний запуск
Application.js Успішне завантаження залежностей
Config.js Успішне завантаження залежностей
config.json Успішне завантаження залежностей
databaseManager.js Успішне завантаження залежностей
userModel.js Успішне завантаження залежностей
3.2.2 Інтеграційне тестування
Після успішного завершення модульного тестування та перевірки роботи
окремих компонентів програмного продукту, було проведено інтеграційне
тестування з метою перевірки спільної роботи цих компонентів як одного цілого.
Цей етап тестування був спрямований на виявлення можливих проблем та
конфліктів у взаємодії між окремими модулями програми [14].
Під час інтеграційного тестування перевірялася правильність зберігання та
оновлення даних в базі даних під час взаємодії з бекендом. Було перевірено, чи
коректно виконується обробка запитів до бази даних та чи відбувається передача
даних між цими компонентами без помилок.
Під час цього етапу тестування перевірялася правильність передачі даних
між Telegram-ботом та бекендом. Було впевнено, що бот коректно обробляє запити
від користувачів та передає їх до бекенду для подальшої обробки.
Для перевірки взаємодії з сервісом Telegram були виконані тести, що
моделювали відправку та отримання повідомлень через API Telegram. Було
перевірено коректність обробки вхідних та вихідних повідомлень, а також
взаємодію бота з користувачами.
Під час інтеграційного тестування також було перевірено коректність
синхронізації та взаємодії асинхронних операцій між різними компонентами
програмного продукту. Було впевнено, що всі операції виконуються правильно та
без збоїв у будь-якому порядку їх виконання.
58
ЧДТУ 242054.007 ПЗ
У результаті інтеграційного тестування було виявлено та виправлено деякі
проблеми у взаємодії між компонентами програмного продукту, що забезпечило
стабільну та надійну роботу системи в цілому.
Таблиця 3.2
Результати інтеграційного тестування
Компонент Результат
Інтеграція Bot та Web Успішна взаємодія
Інтеграція Web та Prisma Успішне підключення до бази даних
Інтеграція Bot та Prisma Успішна взаємодія з базою даних
Інтеграція API з Bot Успішне оброблення запитів через API
Інтеграція Views та Bot Успішне відображення інтерфейсу
3.2.3 Системне тестування
Системне тестування стало важливим етапом в процесі розробки
програмного продукту "Telegram-бот сімейного лікаря". Цей етап тестування
спрямований на перевірку функціональності та поведінки системи як цілого,
включаючи всі її компоненти та їх взаємодію [15].
Під час системного тестування було перевірено коректність реалізації
основного функціоналу бота, такого як реєстрація лікарів та пацієнтів, запис на
прийом, виписка рецептів та направлень. Забезпечено, що всі ці функції працюють
безперебійно та відповідають вимогам користувачів.
Системне тестування також включало перевірку взаємодії з базою даних,
зокрема, правильність збереження та оновлення інформації про лікарів, пацієнтів
та їх призначень. Було перевірено, що дані коректно зберігаються та можуть бути
отримані за потреби.
На цьому етапі було перевірено рівень безпеки системи, зокрема,
захищеність від несанкціонованого доступу до конфіденційної інформації. Також
була перевірена доступність системи та її стабільність при великому навантаженні
та під час виникнення різних ситуацій.
Проводилося тестування на виявлення та обробку помилок, які можуть
виникати під час використання бота. Було перевірено, що система коректно
59
ЧДТУ 242054.007 ПЗ
виявляє помилки та надає користувачам зрозумілі повідомлення про проблеми.
У результаті системного тестування було виявлено та виправлено ряд
проблем, що забезпечило високу якість та надійність програмного продукту.
3.2.4 Приймальне тестування
Приймальне тестування для Telegram-боту сімейного лікаря включало
оцінку його відповідності функціональним і нефункціональним вимогам а також
оцінку його зручності використання та безпеки.
Було перевірено функціональність та чи правильно програмний продукт
реагує на всі команди та запити користувачів. Перевірено роботу основних
функцій, таких як реєстрація користувачів, запис на прийом, виписка рецептів і
направлень тощо.
Протестовано зручність використання. Оцінено зручність взаємодії
користувача з ботом через інтерфейс Telegram. Перевірено зрозумілість та легкість
використання основних функцій боту.
Наступним кроком проведено аналіз стійкості боту до різних видів атак,
таких як SQL-ін'єкції, перехоплення сесій та інші. Перевірено заходи безпеки,
таких як шифрування даних та валідація введених даних.
Також було проведено перевірку відповідності документації. Перевірено
актуальністі та повноти документації до боту, включаючи інструкції користувача
та технічну документацію. З’явилась впевненість, що документація відображає
поточний функціонал та можливості боту.
Завершальним етапом приймального тестування стало тестування
реалістичних сценаріїв використання. Виконано тестові сценаріїі, які
відображають реальне використання боту користувачами. Також перевірено
відповідності реакції боту на навантаження та обробку запитів у реальному часі.
Приймальне тестування допомагло переконатися, що Telegram-бот
відповідає усім вимогам замовника, працює стабільно та забезпечує зручну та
безпечну взаємодію з користувачами.
3.3 Приклади впровадженого програмного комплексу
60
ЧДТУ 242054.007 ПЗ
Упровадження програмного комплексу Telegram-боту сімейного лікаря має
значний вплив на медичну галузь, поліпшуючи доступність медичної допомоги та
оптимізуючи процеси обслуговування пацієнтів. Нижче наведено результати
впровадження програмного комплексу у практиці:
Пацієнти можуть легко звертатися до лікаря через Telegram-бот, що спрощує
процес запису на прийом та надання медичних консультацій.
Зменшення часу очікування на прийом та можливість отримати
консультацію в будь-який час доби полегшує доступність медичної допомоги для
пацієнтів.
Лікарі можуть швидко та зручно взаємодіяти з пацієнтами через Telegram,
що дозволяє їм оптимізувати час та ефективно виконувати свої обов'язки.
Автоматизована система запису на прийом та обробки рецептів та
направлень допомагає лікарям краще керувати своїм часом та ресурсами.
Забезпечення доступу до медичних консультацій та інформації про стан
здоров'я через Telegram дозволяє пацієнтам отримувати швидку та якісну медичну
допомогу навіть у віддалених регіонах.
Моніторинг здоров'я пацієнтів за допомогою Telegram-боту дозволяє
лікарям швидко реагувати на зміни в стані здоров'я та надавати необхідну
допомогу вчасно.
Через можливість консультацій та отримання медичної допомоги в онлайн-
режимі пацієнти можуть уникнути зайвих візитів до лікарні та лікарів загалом,
зменшуючи навантаження на медичні установи.
Оптимізація процесів обслуговування пацієнтів через Telegram-бот дозволяє
лікарням та клінікам ефективніше використовувати свої ресурси та зменшити час
очікування для пацієнтів.
Забезпечення зручного та швидкого доступу до медичної допомоги через
Telegram-бот підвищує задоволення користувачів та їхню відданість медичній
установі.
Можливість взаємодії з лікарем в зручний для них час та місце сприяє
покращенню досвіду використання медичних послуг та збільшує лояльність
пацієнтів.
61
ЧДТУ 242054.007 ПЗ
Висновки до розділу 3
Було обґрунтовано вибір засобів реалізації, таких як TypeScript, Node.js,
Prisma та Grammy, які забезпечили високу надійність та ефективність роботи боту.
Було розроблено структурну (функціональну) схему, що включає взаємодію між
основними компонентами системи: бекендом, Telegram API та базою даних.
Розробка бази даних включала створення таблиць та визначення зв'язків між
ними з використанням SQLite та Prisma. Це забезпечило ефективне зберігання та
керування даними користувачів та медичної інформації.
Також було розроблено інтерфейс користувача, який забезпечує зручний та
інтуїтивно зрозумілий спосіб взаємодії з ботом для користувачів. Інтерфейс
включає різноманітні елементи, такі як кнопки, текстові поля та форми.
Тестування програмного забезпечення включало модульне, інтеграційне,
системне та приймальне тестування, що дозволило забезпечити відповідність
функціональним вимогам та виявити можливі помилки. Завершальним етапом
було впровадження бота у виробниче середовище та надання користувачам
необхідної підтримки.
62
ЧДТУ 242054.007 ПЗ
ВИСНОВКИ
В рамках кваліфікаційної роботи бакалавра "Розробка Telegram-боту
сімейного лікаря", було проведено дослідження актуальних аспектів використання
чат-ботів у медичній сфері з метою поліпшення доступності та якості медичних
послуг для населення. Аналізуючи існуючі практики та технологічні можливості,
було виявлено значний потенціал використання Telegram-ботів для забезпечення
зручного та ефективного спілкування між пацієнтами та медичним персоналом.
У процесі проєктування було приділено особливу увагу визначенню потреб
користувачів та розробці зручного та інтуїтивно зрозумілого інтерфейсу.
Розроблені функціональні та нефункціональні вимоги були враховані при
створенні архітектури системи та виборі технологій. Важливим етапом було
моделювання предметної області, що дозволило чітко визначити об'єкти та
взаємозв'язки між ними.
Крім того, важливим аспектом проєктування було забезпечення надійності
та безпеки системи. Були використані сучасні методи та практики розробки
програмного забезпечення для мінімізації можливості виникнення помилок та
захисту від потенційних загроз безпеки.
Було розроблено архітектуру системи, визначено основні компоненти та їх
взаємозв'язки. Вибір технологій був здійснений з урахуванням вимог проєкту,
зокрема бібліотеки TelegramAPI для розробки інтерфейсу користувача, Prisma для
роботи з базою даних. Після вибору технологій розпочалася фаза активної
розробки та імплементації функціональності. Кожен компонент системи був
розроблений окремо, а потім інтегрований у єдину систему. Процес розробки
супроводжувався тестуванням на кожному етапі для забезпечення якості та
надійності продукту.
У підсумку, спроектований та розроблений Telegram-бот, має потенціал у
сфері сімейної медицини. Дослідження підтверджує важливість розвитку та
впровадження подібних інноваційних інструментів для поліпшення якості та
доступності медичних послуг для населення.
63
ЧДТУ 242054.007 ПЗ
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ
1 TypeScript Documentation - [Електронний ресурс] - Режим доступу:
https://www.typescriptlang.org/docs/
2 Node.js Documentation - [Електронний ресурс] - Режим доступу:
https://nodejs.org/en/docs/
3 Prisma Documentation - [Електронний ресурс] - Режим доступу:
https://www.prisma.io/docs/
4 Ada Health - [Електронний ресурс] - Режим доступу: https://ada.com
5 UML - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Unified_Modeling_Language
6 Методичні рекомендації до підготовки кваліфікаційної роботи бакалавра для
здобувачів вищої освіти зі спеціальності 121 «Інженерія програмного
забезпечення» усіх форм навчання [Текст] /Укл.: Голуб С.В., Заспа Г.О.,
Півень О.Б. Катаєва Є.Ю., Салапатов В.І., Метелап В.В., Олексюк В.В.; М-
во освіти і науки України.
7 Розгортання програмного забезпечення - [Електронний ресурс] - Режим
доступу:
https://uk.wikipedia.org/wiki/Розгортання_програмного_забезпечення
8 Діаграма Класів - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Діаграма_класів
9 Діаграма діяльності - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Діаграма_діяльності
10 Діаграма Пакетів – [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Діаграма_пакетів
11 Діаграма станів (UML) - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Діаграма_станів_(UML)
12 Діаграма прецендентів - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Діаграма_прецедентів
13 Model-View-Controller - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Model-View-Controller
64
ЧДТУ 242054.007 ПЗ
14 Інтеграційне тестування - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Інтеграційне_тестування
15 Системне тестування - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Системне_тестування
16 Cannaday B. Developing Bots with Node.js. Apress, 2017.
17 Casciaro M. Node.js Design Patterns. Packt Publishing, 2016.
18 Fenton S. Pro TypeScript: Application-Scale JavaScript Development. Apress,
2014.
19 Crockford D. JavaScript: The Good Parts. O'Reilly Media, 2008.
20 World Health Organization (WHO) - [Електронний ресурс] - Режим доступу:
https://www.who.int
21 American Medical Association (AMA) - [Електронний ресурс] - Режим
доступу: https://www.ama-assn.org
22 Centers for Disease Control and Prevention (CDC) - [Електронний ресурс] -
Режим доступу: https://www.cdc.gov
23 Mayo Clinic - [Електронний ресурс] - Режим доступу:
https://www.mayoclinic.org
24 O'Hanlon P. Advanced TypeScript Programming Projects. Packt Publishing, 2019.
25 Jansen R. Learning TypeScript 2.x: Develop and maintain captivating web
applications with ease. Packt Publishing, 2017.
26 Griffiths D. Full Stack Development with Angular and Node.js. Packt Publishing,
2020.
27 Johns Hopkins Medicine - [Електронний ресурс] - Режим доступу:
https://www.hopkinsmedicine.org
28 Stanford Health Care - [Електронний ресурс] - Режим доступу:
https://stanfordhealthcare.org
29 Cleveland Clinic - [Електронний ресурс] - Режим доступу:
https://my.clevelandclinic.org
65
ДОДАТОК А
ЗАТВЕРДЖЕНО:
Зав. кафедри ПЗАС
проф. Голуб С. В.
___________________________
РОЗРОБКА TELEGRAM-БОТУ СІМЕЙНОГО ЛІКАРЯ
Специфікація
482.ЧДТУ.242054-007
Листів 1
Розробник ________________ Куценко О.С.
Керівник ________________ Півень О.Б.
Черкаси 2024
482.ЧДТУ.242054-007
Позначення Найменування Примітка
482.ЧДТУ.242054-007 12-01 Лістинг програми
482.ЧДТУ.242054-007 34-01 Інструкція користувача
482.ЧДТУ.242054-007 90-01 Графічні матеріали
67
ДОДАТОК Б
РОЗРОБКА TELEGRAM-БОТУ СІМЕЙНОГО ЛІКАРЯ
Лістинг програми
482.ЧДТУ.242054 12-01
Листів 54
Розробник ________________ Куценко О. С.
Черкаси 2024
482. ЧДТУ.242054 12-01
AuthMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext, Role } from "../../../bot";
import { AuthService } from "../services/AuthService";
import { Keyboard } from "grammy";
import { Globals } from "../../../Globals";
import { DoctorMenu } from "./DoctorMenu";
import { Prisma, PrismaClient } from "@prisma/client";
import { PatientMenu } from "./PatientMenu";
import { User } from "grammy/types";
@injectable()
export class AuthMenu extends Menu {
public static NAME = "Авторизація";
public id: string = AuthMenu.NAME;
constructor(
private authService: AuthService,
private doctorMenu: DoctorMenu,
private patientMenu: PatientMenu,
private prisma: PrismaClient,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from){
69
482. ЧДТУ.242054 12-01
return
}
if(await this.authService.getDoctorById(ctx.from.id)){
if(await this.authService.IsAuthed(ctx.from.id)){
const keyboard = new Keyboard()
.requestContact(Globals.AUTHMENU_GIVE_NUMBER)
.resized()
.persistent()
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.AUTHMENU_IMAGE,
{
caption: Globals.AUTHMENU_TEXT,
parse_mode: "HTML",
reply_markup: keyboard
}
));
return;
}
}
if(await this.authService.IsAuthed(ctx.from.id) == false){
const keyboard = new Keyboard()
.requestContact(Globals.AUTHMENU_GIVE_NUMBER)
.resized()
.persistent()
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.AUTHMENU_IMAGE,
{
70
482. ЧДТУ.242054 12-01
caption: Globals.AUTHMENU_TEXT,
parse_mode: "HTML",
reply_markup: keyboard
}
));
console.log(ctx.session.menuState.stateId)
}else{
await this.commitMessage(ctx,
ctx.reply(Globals.AUTHMENU_AUTH_OK,
{
parse_mode: "HTML",
reply_markup: this.getKeyboard()
}
));
await this.switchMenu(this.patientMenu.id, ctx)
}
}
protected async handleMessage(ctx: BotContext, message: string): Promise<void> {
if (!ctx.message || !ctx.message.contact || !ctx.from) {
await this.commitMessage(ctx,
ctx.reply(Globals.AUTHMENU_NUMBER_HOW,
{
parse_mode: "HTML"
}
));
return
}
if(ctx.message.contact.phone_number == Globals.DOCTOR_NUMBER){
71
482. ЧДТУ.242054 12-01
await this.authDoctor(ctx, ctx.from)
return;
}
const number = ctx.message.contact.phone_number;
const telegramId = ctx.from.id || 0;
const chatId = ctx.message.chat.id;
await this.authPatient(ctx, number, telegramId, chatId);
}
private async authPatient(ctx: BotContext, number: string, telegramId: number, chatId:
number){
if(await this.authService.IsPatientExist(number) == false){
await this.commitMessage(ctx,
ctx.reply(Globals.AUTHMENU_AUTH_FAIL,
{
parse_mode: "HTML"
}
));
return;
}
ctx.session.role = Role.Patient;
await this.authService.updatePatientData(telegramId, chatId, number);
await this.switchMenu(this.patientMenu.id, ctx)
}
private async authDoctor(ctx: BotContext, from: User){
ctx.session.role = Role.Doctor;
72
482. ЧДТУ.242054 12-01
var name: string = from.first_name;
if(name == undefined){
name = from.username || "Не визначено";
}
var username = from.username;
if(username == undefined){
username = "Не визначено";
}
await this.prisma.doctor.upsert({
where:{
phoneNumber: Globals.DOCTOR_NUMBER
},
create: {
id: from.id,
fullname: name,
username: username,
phoneNumber: Globals.DOCTOR_NUMBER
},
update:{
fullname: name,
username: username,
phoneNumber: Globals.DOCTOR_NUMBER
}
})
await this.switchMenu(this.doctorMenu.id, ctx)
}
}
73
482. ЧДТУ.242054 12-01
AuthService.ts
import { PrismaClient, Patient } from "@prisma/client";
import { injectable } from "tsyringe";
@injectable()
export class AuthService {
public constructor(
private prisma: PrismaClient,
) { }
public async IsAuthed(id: number) {
const user = await this.getPatientById(id)
if(user) {
return true;
}
return false;
}
public async IsPatientExist(number: string) {
const user = await this.prisma.patient.findFirst({
where: {
phoneNumber: number
},
include: {
doctor: true,
receptions: true
}
})
if(user) {
return true;
}
74
482. ЧДТУ.242054 12-01
return false;
}
public async IsDoctorExist(number: string) {
const user = await this.prisma.doctor.findFirst({
where: {
phoneNumber: number
}
})
if(user) {
return true;
}
return false;
}
public async getPatientById(id: number) {
const user = await this.prisma.patient.findFirst({
where: {
telegramId: id
},
include: {
doctor: true,
receptions: true
}
})
return user;
}
public async getDoctorById(id: number) {
const user = await this.prisma.doctor.findFirst({
75
482. ЧДТУ.242054 12-01
where: {
id: id
}
})
return user;
}
public async updatePatientData(id: number, chatId: number, number: string)
{
await this.prisma.patient.update({
where: {
phoneNumber: number
},
data: {
telegramId: id,
chatid: chatId,
}
})
}
}
DoctorCreatePatient.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { BackButton } from "../menubuttons/BackButton";
import { DoctorService } from "../services/DoctorService";
import { Globals } from "../../../Globals";
@injectable()
export class DoctorCreatePatient extends Menu {
76
482. ЧДТУ.242054 12-01
public id: string = "Новий пацієнт";
constructor(
private doctorService: DoctorService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
}
async open(ctx: BotContext) {
await super.open(ctx);
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCREATEPATIENT_NUMBER, {
reply_markup: this.getKeyboard()
}));
}
protected async handleMessage(ctx: BotContext, message: string): Promise<void> {
if(!ctx.from){
return;
}
switch(ctx.session.menuState.stateId){
case 0:
await
this.doctorService.createUser(Globals.DOCTORCREATEPATIENT_INFONULL,
Globals.DOCTORCREATEPATIENT_INFONULL, message,
Globals.DOCTORCREATEPATIENT_INFONULL, ctx.from.id)
ctx.session.menuState.patientNumber = message;
ctx.session.menuState.stateId = 1;
77
482. ЧДТУ.242054 12-01
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCREATEPATIENT_NAME, {
reply_markup: this.getKeyboard()
}));
break;
case 1:
var user = await
this.doctorService.getUserByNumber(ctx.session.menuState.patientNumber)
if(!user){
return;
}
await this.doctorService.createUser(user.bloodGroup, message,
user.phoneNumber, user.birth, ctx.from.id)
ctx.session.menuState.stateId = 2;
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCREATEPATIENT_BLOOD, {
reply_markup: this.getKeyboard()
}));
break;
case 2:
user = await
this.doctorService.getUserByNumber(ctx.session.menuState.patientNumber)
if(!user){
return;
}
await this.doctorService.createUser(message, user.fullName, user.phoneNumber,
user.birth, ctx.from.id)
78
482. ЧДТУ.242054 12-01
ctx.session.menuState.stateId = 3;
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCREATEPATIENT_BIRTH, {
reply_markup: this.getKeyboard()
}));
break;
case 3:
user = await
this.doctorService.getUserByNumber(ctx.session.menuState.patientNumber)
if(!user){
return;
}
await this.doctorService.createUser(user.bloodGroup, user.fullName,
user.phoneNumber, message, ctx.from.id)
ctx.session.menuState.stateId = 4;
console.log("complete")
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCREATEPATIENT_COMPLETE, {
reply_markup: this.getKeyboard()
}));
break;
default:
break;
}
}
}
DoctorService.ts
import { PrismaClient, Patient } from "@prisma/client";
79
482. ЧДТУ.242054 12-01
import { injectable } from "tsyringe";
@injectable()
export class DoctorService {
public constructor(
private prisma: PrismaClient,
) { }
public async createUser(bloodGroup: string, fullName: string, phoneNumber: string,
birth: string, doctroId: number){
const user = await this.prisma.patient.upsert({
where: {
phoneNumber: phoneNumber
},
create: {
bloodGroup: bloodGroup,
fullName: fullName,
phoneNumber: phoneNumber,
doctorId: doctroId,
birth: birth,
telegramId: -1,
chatid: -1
},
update: {
bloodGroup: bloodGroup,
fullName: fullName,
phoneNumber: phoneNumber,
doctorId: doctroId,
birth: birth,
}
})
}
80
482. ЧДТУ.242054 12-01
public async getUserByNumber(phoneNumber: string) {
return await this.prisma.patient.findFirst({
where: {
phoneNumber: phoneNumber
}
})
}
public async getPatientByTelegramId(id: number) {
return await this.prisma.patient.findFirst({
where: {
telegramId: id
},
include:{
doctor: true
}
})
}
public async getPatientById(id: number) {
return await this.prisma.patient.findFirst({
where: {
id: id
},
include:{
doctor: true
}
})
}
public async getDoctorById(id: number) {
81
482. ЧДТУ.242054 12-01
const user = await this.prisma.doctor.findFirst({
where: {
id: id
},
include: {
patients: true
}
})
return user;
}
public async createRecipe(recipeText: string, doctorId: number, patientId: number){
return this.prisma.recipe.create({
data: {
text: recipeText,
doctorId: doctorId,
patientId: patientId
}
})
}
public async deleteRecipe(recipeId: number){
return this.prisma.recipe.delete({
where: {
id: recipeId
}
})
}
public async createReferral(refferalText: string, date: Date, doctorId: number, patientId:
number){
return this.prisma.referral.create({
82
482. ЧДТУ.242054 12-01
data: {
date: date,
text: refferalText,
doctorId: doctorId,
patientId: patientId
}
})
}
public async deleteReferral(referralId: number){
return this.prisma.referral.delete({
where: {
id: referralId
}
})
}
public async getRecipesByPatientId(patientId: number){
return this.prisma.recipe.findMany({
where: {
patientId: patientId
}
})
}
public async getReferralsByPatientId(patientId: number){
return this.prisma.referral.findMany({
where: {
patientId : patientId
}
})
}
83
482. ЧДТУ.242054 12-01
}
DoctorMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { Keyboard } from "grammy";
import { NavigationButton } from "../menubuttons/NavigationButton";
import { DoctorMenuPatients } from "./DoctorMenuPatients";
import { Globals } from "../../../Globals";
import * as util from "util";
import { DoctorService } from "../services/DoctorService";
import { DoctorReceptionMenu } from "./DoctorReceptionMenu";
@injectable()
export class DoctorMenu extends Menu {
public id: string = "Лікар";
constructor(
private doctorMenuPacients: DoctorMenuPatients,
private doctorMenuReception: DoctorReceptionMenu,
private doctorService: DoctorService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new
NavigationButton(Globals.DOCTORMENU_BTN_PATIENTS, this, doctorMenuPacients));
this.registerButton(new
NavigationButton(Globals.DOCTORMENU_BTN_RECEPTIONS, this,
doctorMenuReception));
}
84
482. ЧДТУ.242054 12-01
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from){
return
}
const doctor = await this.doctorService.getDoctorById(ctx.from?.id);
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.DOCTORMENU_WELCOME_IMAGE,
{
caption: util.format(Globals.DOCTORMENU_WELCOME_TEXT,
doctor?.fullname),
parse_mode: "HTML",
reply_markup: this.getKeyboard()
}
))
}
}
DoctorMenuPatients.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { BackButton } from "../menubuttons/BackButton";
import { DoctorService } from "../services/DoctorService";
import { NavigationButton } from "../menubuttons/NavigationButton";
import { DoctorCreatePatient } from "./DoctorCreatePatient";
import { Globals } from "../../../Globals";
import * as util from "util";
85
482. ЧДТУ.242054 12-01
@injectable()
export class DoctorMenuPatients extends Menu {
public id: string = "Мої пацієнти";
constructor(
private doctorService: DoctorService,
private doctorCreateUser: DoctorCreatePatient,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
this.registerButton(new
NavigationButton(Globals.DOCTORMENUPATIENTS_CREATE, this, this.doctorCreateUser))
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.message){
console.log("error: message from bot")
return
}
const doctor = await this.doctorService.getDoctorById(ctx.message.from.id);
if(!doctor?.patients){
return;
}
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.DOCTORMENUPATIENTS_IMAGE, {
86
482. ЧДТУ.242054 12-01
caption: util.format(Globals.DOCTORMENUPATIENTS_TEXT,
doctor?.patients.length),
reply_markup: this.getKeyboard()
}));
let patientsText = "";
for (let index = 0; index < doctor?.patients.length; index++) {
const patient = doctor?.patients[index];
patientsText =
patientsText.concat(util.format(Globals.DOCTORMENUPATIENTS_PATIENT, patient.id,
patient.fullName, patient.phoneNumber) + "\n");
if(index + 1 % 30 == 0 || index + 1 == doctor?.patients.length)
{
await this.commitMessage(ctx,
ctx.reply(patientsText, {
reply_markup: this.getKeyboard()
}));
patientsText = "";
}
}
}
}
DoctorReceptionMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { InlineKeyboard, Keyboard } from "grammy";
import { DoctorMenuPatients } from "./DoctorMenuPatients";
import { Globals } from "../../../Globals";
import * as util from "util";
import { DoctorService } from "../services/DoctorService";
87
482. ЧДТУ.242054 12-01
import { BackButton } from "../menubuttons/BackButton";
import { ReceptionService } from "../services/ReceptionService";
import { format } from "util";
import moment from "moment";
@injectable()
export class DoctorReceptionMenu extends Menu {
public id: string = "ДПрийоми";
constructor(
private doctorMenuPacients: DoctorMenuPatients,
private receptionService: ReceptionService,
private doctorService: DoctorService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
this.registerButton({
text: Globals.DOCTORCRECEPTIONMENU_BTN_RECP,
onClick: async(ctx) => {
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCRECEPTIONMENU_RECP_TEX));
ctx.session.menuState.stateId = 1
}});
this.registerButton({
text: Globals.DOCTORCRECEPTIONMENU_BTN_REFR,
onClick: async(ctx) => {
const days = this.receptionService.getAvailableDays()
88
482. ЧДТУ.242054 12-01
let keyboard = new Keyboard()
.persistent()
keyboard.add("↩ ").row();
days.forEach(day => keyboard.text(day).row())
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCRECEPTIONMENU_REFR_DAT, {
reply_markup: keyboard
}));
ctx.session.menuState.stateId = 2
}});
this.registerButton({
text: Globals.DOCTORCRECEPTIONMENU_BTN_FINS,
onClick: async(ctx) => {
await
this.receptionService.finishReception(ctx.session.menuState.currentReceptionId)
await this.switchMenu(this.id, ctx)
}});
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from){
return
}
//await this.receptionService.updateReception(`30 січня 2024 13:00`, 1, 426649060)
89
482. ЧДТУ.242054 12-01
const doctor = await this.doctorService.getDoctorById(ctx.from?.id);
if(!doctor){
return;
}
const receptions = await this.receptionService.getReceptionsToday(doctor?.id);
if(receptions.length == 0){
const keyboard = new Keyboard().text("↩ ").row().resized();
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCRECEPTIONMENU_EMPTY,
{
reply_markup: keyboard
}));
return;
}
receptions.sort(compare);
function compare(reception1: any & Date, reception2: any & Date){
if(reception1.date.getTime() > reception2.date.getTime()){
return -1;
}else{
return 1;
}
}
for (let index = 0; index < receptions.length - 1; index++) {
const reception = receptions[index];
await this.createReceptionMessage(ctx, reception.id, reception.date)
90
482. ЧДТУ.242054 12-01
}
const reception = receptions[receptions.length - 1];
if(new Date().getTime() >= reception.date.getTime()) {
await this.createCurrentReceptionMessage(ctx, reception.id, reception.patientId,
reception.date);
}else {
await this.createReceptionMessage(ctx, reception.id, reception.date)
}
}
protected async handleMessage(ctx: BotContext, message: string) {
if (!ctx.message || !ctx.from) {
return
}
console.log(ctx.session.menuState.stateId)
const currentReception = await
this.receptionService.getRecetionById(ctx.session.menuState.currentReceptionId);
if(!currentReception){
return;
}
switch(ctx.session.menuState.stateId){
case 1:
ctx.session.menuState.stateId = 100
await this.doctorService.createRecipe(message, ctx.from.id,
currentReception.patientId)
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCRECEPTIONMENU_RECP_OK));
91
482. ЧДТУ.242054 12-01
break;
case 2:
ctx.session.menuState.stateId = 3
ctx.session.selectedDate = message;
const time = await this.receptionService.getAvailableTimeReferral(message,
ctx.from.id);
let keyboard = new Keyboard()
.persistent()
keyboard.add("↩ ").row();
time.forEach(hours => keyboard.text(hours).row())
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCRECEPTIONMENU_REFR_TIM, {
reply_markup: keyboard
}));
break;
case 3:
ctx.session.menuState.stateId = 4
ctx.session.selectedDate += " " + message;
await this.commitMessage(ctx,
ctx.reply(Globals.DOCTORCRECEPTIONMENU_REFR_TEX, {
reply_markup: this.getKeyboard()
}));
break;
case 4:
ctx.session.menuState.stateId = 5
const referral = await this.doctorService.createReferral(message,
moment(ctx.session.selectedDate, "DD MMM YYYYY HH:mm").toDate(), ctx.from.id,
currentReception.patientId)
await this.commitMessage(ctx,
ctx.reply(format(Globals.DOCTORCRECEPTIONMENU_REFR_OK,
92
482. ЧДТУ.242054 12-01
referral.text,
referral.date.toLocaleString("uk", { year: "numeric", month: "long", day:
"numeric", hour: "2-digit", minute: "2-digit"})), {
reply_markup: this.getKeyboard()
}));
break;
default:
break;
}
}
private async createReceptionMessage(ctx: BotContext, receptionId: number, date:
Date){
const keyboard = new Keyboard().text("↩ ").row().resized();
await this.commitMessage(ctx,
ctx.reply(util.format(Globals.DOCTORCRECEPTIONMENU_NEXTREC,
date.toLocaleString("uk", { year: "numeric", month: "long", day: "numeric", hour:
"2-digit", minute: "2-digit"})),
{
parse_mode: "HTML",
reply_markup: keyboard
}
));
}
private async createCurrentReceptionMessage(ctx: BotContext, receptionId: number,
patientId: number, date: Date){
const user = await this.doctorService.getPatientById(patientId)
let messageText = util.format(Globals.DOCTORCRECEPTIONMENU_ACTIVE,
date.toLocaleString("uk", { year: "numeric", month: "long", day: "numeric", hour: "2-digit",
minute: "2-digit"}));
93
482. ЧДТУ.242054 12-01
let medcardText = util.format(Globals.PATIENTMEDCARDMENU_TEXT,
user?.fullName, user?.phoneNumber, user?.doctor.username, user?.doctor.phoneNumber,
user?.birth, user?.bloodGroup);
ctx.session.menuState.currentReceptionId = receptionId;
ctx.session.menuState.currentReceptionMessageId = await this.commitMessage(ctx,
ctx.reply(`${messageText}\n\n${medcardText}`,
{
reply_markup: this.getKeyboard(),
parse_mode: "HTML"
}
));
}
}
Menu.ts
import { Router } from "@grammyjs/router";
import { InlineKeyboard, Keyboard } from "grammy";
import { Message } from "grammy/types";
import { BotContext } from "../../../bot";
import { MenuButton } from "../menubuttons/MenuButton"
type MenuButtons = Map<string, MenuButton>;
type MenuInlnlineCallbacks = Map<string, (ctx: BotContext, data: string) =>
Promise<any>>;
export type MenuStorage = Map<string, Menu>;
interface InlineButtonCallback {
menuId: string,
callbackId: string,
data: string,
}
94
482. ЧДТУ.242054 12-01
export abstract class Menu {
public abstract id: string;
private buttons: MenuButtons = new Map();
private inlineCallbacks: MenuInlnlineCallbacks = new Map();
constructor(
protected menuStorage: Map<string, Menu>
) { }
async open(ctx: BotContext) {
const messages = ctx.session.menuState.sentMessages;
ctx.session.menuState = {
currentReceptionId: -1,
patientNumber: "",
stateId: 0,
currentPage: ctx.session.menuState.currentPage,
currentReceptionMessageId: ctx.session.menuState.currentReceptionMessageId,
currentMenu: this.id,
sentMessages: messages
};
}
async close(ctx: BotContext, saveHistory: boolean): Promise<void> {
if (saveHistory) {
ctx.session.menuHistory.push(this.id);
}
while (ctx.session.menuState.sentMessages.length > 0) {
const id = ctx.session.menuState.sentMessages.pop();
95
482. ЧДТУ.242054 12-01
if (id) {
const result = await ctx.api.deleteMessage(ctx.chat?.id || -1, id);
}
}
}
public getKeyboard(): Keyboard {
const keyboard = new Keyboard();
this.buttons.forEach((btn, name) => {
keyboard.text(name);
});
keyboard.resized();
keyboard.persistent();
return keyboard;
}
public getKeyboardAsRow(): Keyboard {
const keyboard = new Keyboard();
this.buttons.forEach((btn, name) => {
keyboard.text(name).row();
});
keyboard.persistent();
return keyboard;
}
public async onInlineButtonCallback(ctx: BotContext, data: InlineButtonCallback):
Promise<void> {
96
482. ЧДТУ.242054 12-01
if (this.id != data.menuId) {
console.error(`InlineButtonCallback recieved by wrong menu ${this.id} instead of
${data.menuId}`);
return;
}
const callback = this.inlineCallbacks.get(data.callbackId);
if (callback) {
return callback(ctx, data.data);
}
}
public async commitMessage(ctx: BotContext, reply: Promise<Message>) {
const id = (await reply).message_id;
ctx.session.menuState.sentMessages.push(id)
return id;
}
public async commitGroupMessage(ctx: BotContext, reply: Promise<Message[]>) {
const messages = (await reply);
messages.forEach(m => {
ctx.session.menuState.sentMessages.push(m.message_id)
})
return messages;
}
public createNavigation(router: Router<BotContext>) {
router.route(this.id, async (ctx) => {
await this.onClick(ctx, ctx.message?.text || "");
await ctx.deleteMessage();
97
482. ЧДТУ.242054 12-01
});
}
public async switchMenu(menuId: string, ctx: BotContext)
{
let saveHistory = true;
if(this.id == menuId){
saveHistory = false;
}
await this.close(ctx, saveHistory);
await this.menuStorage.get(menuId)?.open(ctx)
}
protected registerButton(menuButton: MenuButton) {
this.buttons.set(menuButton.text, menuButton);
}
protected registerInlineButtonCallback(id: string, callback: (ctx: BotContext, data: string)
=> Promise<any>) {
this.inlineCallbacks.set(id, callback);
}
protected async handleMessage(ctx: BotContext, message: string) { }
private async onClick(ctx: BotContext, message: string) {
const button = this.buttons.get(message);
if (button != undefined) {
await button.onClick(ctx);
} else {
await this.handleMessage(ctx, message)
}
98
482. ЧДТУ.242054 12-01
}
}
PatientMedcardMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { Globals } from "../../../Globals";
import { BackButton } from "../menubuttons/BackButton";
import { DoctorService } from "../services/DoctorService";
import { format } from "util";
@injectable()
export class PatientMedcardMenu extends Menu {
public id: string = "Пацієнт медична карта";
constructor(
private bdService: DoctorService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from){
return;
}
99
482. ЧДТУ.242054 12-01
const user = await this.bdService.getPatientByTelegramId(ctx.from?.id)
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.PATIENTMEDCARDMENU_IMAGE,
{
caption: format(Globals.PATIENTMEDCARDMENU_TEXT, user?.fullName,
user?.phoneNumber, user?.doctor.username, user?.doctor.phoneNumber, user?.birth,
user?.bloodGroup),
parse_mode: "HTML",
reply_markup: this.getKeyboard()
}));
}
}
PatientMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { NavigationButton } from "../menubuttons/NavigationButton";
import { Globals } from "../../../Globals";
import { PatientMedcardMenu } from "./PatientMedcardMenu";
import { DoctorService } from "../services/DoctorService";
import { format } from "util";
import { PatientReceptionMenu } from "./PatientReceptionMenu";
import { PatientRecipesMenu } from "./PatientRecipesMenu";
import { PatientReferralsMenu } from "./PatientReferalsMenu";
@injectable()
export class PatientMenu extends Menu {
public id: string = "Пацієнт";
constructor(
100
482. ЧДТУ.242054 12-01
private bdService: DoctorService,
private medCardMenu: PatientMedcardMenu,
private reception: PatientReceptionMenu,
private recipes: PatientRecipesMenu,
private referals: PatientReferralsMenu,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new
NavigationButton(Globals.PATIENTMENU_BTN_MEDCARD, this, medCardMenu));
this.registerButton(new
NavigationButton(Globals.PATIENTMENU_BTN_RECEPTIONS, this, reception));
this.registerButton(new NavigationButton(Globals.PATIENTMENU_BTN_RECIPES,
this, recipes));
this.registerButton(new
NavigationButton(Globals.PATIENTMENU_BTN_REFERRAL, this, referals));
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from?.id){
return;
}
const user = await this.bdService.getPatientByTelegramId(ctx.from?.id)
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.PATIENTMENU_WELCOME_IMAGE,
{
caption: format(Globals.PATIENTMENU_WELCOME_TEXT),
parse_mode: "HTML",
101
482. ЧДТУ.242054 12-01
reply_markup: this.getKeyboard()
}));
}
}
PatientReceptionMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { Keyboard } from "grammy";
import { Globals } from "../../../Globals";
import { PatientMedcardMenu } from "./PatientMedcardMenu";
import { DoctorService } from "../services/DoctorService";
import { format } from "util";
import { BackButton } from "../menubuttons/BackButton";
import { ReceptionService } from "../services/ReceptionService";
import { AuthMenu } from "./AuthMenu";
import moment from "moment";
@injectable()
export class PatientReceptionMenu extends Menu {
public id: string = "ППрийоми";
constructor(
private bdService: DoctorService,
private receptionService: ReceptionService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
this.registerButton({
text: "Змінити запис",
102
482. ЧДТУ.242054 12-01
onClick: async (ctx: BotContext) => {
return this.sendRegisterReceptionForm(ctx, true);
}
});
this.registerButton({
text: "Видалити запис",
onClick: async (ctx: BotContext) => {
if(!ctx.from){
return;
}
const user = await this.bdService.getPatientByTelegramId(ctx.from?.id);
if(!user){
return
}
await this.receptionService.deleteRecetionByPatientId(user?.id);
await this.switchMenu(this.id, ctx)
}
});
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from){
return;
}
103
482. ЧДТУ.242054 12-01
const user = await this.bdService.getPatientByTelegramId(ctx.from?.id);
if(!user){
await this.switchMenu(AuthMenu.NAME, ctx)
return
}
const reception = await this.receptionService.getRecetionByPatientId(user?.id);
if(reception){
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.PATIENTRECEPTIONMENU_RECP_IMG,
{
parse_mode: "HTML",
caption: format(Globals.PATIENTRECEPTIONMENU_TEXT,
reception.date.toLocaleString("uk", { year: "numeric", month: "long", day: "numeric", hour: "2-
digit", minute: "2-digit"})),
reply_markup: this.getKeyboard()
}));
return;
}
await this.sendRegisterReceptionForm(ctx, false)
}
protected async handleMessage(ctx: BotContext, message: string) {
if (!ctx.message || !ctx.from) {
await this.commitMessage(ctx,
ctx.reply(Globals.AUTHMENU_AUTH_FAIL,
{
parse_mode: "HTML"
}
));
104
482. ЧДТУ.242054 12-01
return
}
switch(ctx.session.menuState.stateId){
case 0:
if(!this.receptionService.getAvailableDays().find(text => text === message)){
await this.commitMessage(ctx,
ctx.reply(Globals.PATIENTRECEPTIONMENU_WRONG_D,
{
parse_mode: "HTML"
}
));
return;
}
ctx.session.selectedDate = message;
var patient = await this.bdService.getPatientByTelegramId(ctx.from.id);
if(!patient){
return this.switchMenu(AuthMenu.NAME, ctx)
}
var hours = await
this.receptionService.getAvailableHours(ctx.session.selectedDate, patient.doctorId)
var keyboard = new Keyboard().text("↩ ").row()
keyboard.resized()
keyboard.persistent()
hours.forEach(hour => keyboard.text(hour).row())
await this.commitMessage(ctx,
105
482. ЧДТУ.242054 12-01
ctx.reply(format(Globals.PATIENTRECEPTIONMENU_SETTIME, message),
{
parse_mode: "HTML",
reply_markup: keyboard
}
));
ctx.session.menuState.stateId = 1
break;
case 1:
patient = await this.bdService.getPatientByTelegramId(ctx.from.id);
if(!patient){
return this.switchMenu(AuthMenu.NAME, ctx)
}
hours = await this.receptionService.getAvailableHours(ctx.session.selectedDate,
patient.doctorId)
keyboard = new Keyboard().text("↩ ").row()
keyboard.resized()
keyboard.persistent()
hours.forEach(hour => keyboard.text(hour).row())
if(!hours.find(text => text === message)){
await this.commitMessage(ctx,
ctx.reply(Globals.PATIENTRECEPTIONMENU_WRONG_T,
{
parse_mode: "HTML",
reply_markup: keyboard
}
));
106
482. ЧДТУ.242054 12-01
return;
}
console.log(ctx.session.selectedDate + ` ${message}`);
console.log(moment(ctx.session.selectedDate + ` ${message}`, "DD MMM
YYYY HH:mm"));
console.log(`pat ${ patient.id} doc ${ patient.doctorId}`)
await this.receptionService.updateReception(ctx.session.selectedDate + `
${message}`, patient.id, patient.doctorId)
await this.commitMessage(ctx,
ctx.reply(Globals.PATIENTRECEPTIONMENU_OK,
{
parse_mode: "HTML",
reply_markup: this.getKeyboard()
}
));
ctx.session.menuState.stateId = 2
break;
}
}
private async sendRegisterReceptionForm(ctx: BotContext, update: boolean){
ctx.session.menuState.stateId = 0
const keyboard = new Keyboard().text("↩ ").row()
keyboard.resized()
keyboard.persistent()
this.receptionService.getAvailableDays().forEach(day => keyboard.text(day).row())
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.PATIENTRECEPTIONMENU_RECP_IMG,
{
107
482. ЧДТУ.242054 12-01
caption: update ? Globals.PATIENTRECEPTIONMENU_UPDATE :
Globals.PATIENTRECEPTIONMENU_EMPTY,
parse_mode: "HTML",
reply_markup: keyboard
}
));
}
}
PatientRecipesMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { Globals } from "../../../Globals";
import { DoctorService } from "../services/DoctorService";
import { format } from "util";
import { BackButton } from "../menubuttons/BackButton";
import { InlineKeyboard } from "grammy";
@injectable()
export class PatientRecipesMenu extends Menu {
public id: string = "ПРецепти";
constructor(
private doctorService: DoctorService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
108
482. ЧДТУ.242054 12-01
this.registerInlineButtonCallback("delete", async (ctx, data) =>{
const recipeId = Number(data)
const recipe = await this.doctorService.deleteRecipe(recipeId);
await ctx.api.raw.editMessageText(
{
chat_id: ctx.chat?.id || -1,
message_id: ctx.callbackQuery?.message?.message_id || -1,
text: format(Globals.PATIENTRECIPESMENU_DELETED, recipe.id),
parse_mode: "HTML"
});
})
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from?.id){
return;
}
const patient = await this.doctorService.getPatientByTelegramId(ctx.from?.id)
if(!patient){
return;
}
const recipes = await this.doctorService.getRecipesByPatientId(patient.id)
if(recipes.length <= 0){
await this.commitMessage(ctx,
109
482. ЧДТУ.242054 12-01
ctx.replyWithPhoto( Globals.PATIENTRECIPEMENU_RECP_IMG,
{
caption: format(Globals.PATIENTRECIPESMENU_EMPTY, recipes.length),
reply_markup: this.getKeyboard(),
parse_mode: "HTML"
}));
}
await this.commitMessage(ctx,
ctx.replyWithPhoto( Globals.PATIENTRECIPEMENU_RECP_IMG,
{
caption: format(Globals.PATIENTRECIPESMENU_START, recipes.length),
reply_markup: this.getKeyboard(),
parse_mode: "HTML"
}));
for (let index = 0; index < recipes.length; index++) {
const recipe = recipes[index];
const jsonCount = JSON.stringify({
menuId: this.id,
callbackId: "delete",
data: recipe.id
});
const keyboard = new InlineKeyboard()
.text(Globals.PATIENTRECIPESMENU_DELETE, `${jsonCount}`)
await this.commitMessage(ctx,
ctx.reply(format(Globals.PATIENTRECIPESMENU_HEAD, recipe.id) + "\n" +
recipe.text, {
110
482. ЧДТУ.242054 12-01
reply_markup: keyboard
}));
}
}
}
PatientReferalsMenu.ts
import { injectable } from "tsyringe";
import { Menu } from "./Menu";
import { BotContext } from "../../../bot";
import { Globals } from "../../../Globals";
import { DoctorService } from "../services/DoctorService";
import { format } from "util";
import { BackButton } from "../menubuttons/BackButton";
import { InlineKeyboard } from "grammy";
@injectable()
export class PatientReferralsMenu extends Menu {
public id: string = "ПНапра";
constructor(
private doctorService: DoctorService,
menuStorage: Map<string, Menu>,
) {
super(menuStorage);
this.registerButton(new BackButton("↩ ", this, menuStorage));
this.registerInlineButtonCallback("delete", async (ctx, data) =>{
const referralId = Number(data)
111
482. ЧДТУ.242054 12-01
const referral = await this.doctorService.deleteReferral(referralId);
await ctx.api.raw.editMessageText(
{
chat_id: ctx.chat?.id || -1,
message_id: ctx.callbackQuery?.message?.message_id || -1,
text: format(Globals.PATIENTREFERMENU_DELETED, referral.id),
parse_mode: "HTML"
});
})
}
async open(ctx: BotContext) {
await super.open(ctx);
if(!ctx.from?.id){
return;
}
const patient = await this.doctorService.getPatientByTelegramId(ctx.from?.id)
if(!patient){
return;
}
const referrals = await this.doctorService.getReferralsByPatientId(patient.id)
if(referrals.length <= 0){
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.PATIENTREFERMENU_IMG,{
112
482. ЧДТУ.242054 12-01
caption: Globals.PATIENTREFERMENU_EMPTY,
parse_mode: "HTML",
reply_markup: this.getKeyboard()
}));
return;
}
await this.commitMessage(ctx,
ctx.replyWithPhoto(Globals.PATIENTREFERMENU_IMG, {
caption: format(Globals.PATIENTREFERMENU_START, referrals.length),
parse_mode: "HTML",
reply_markup: this.getKeyboard()
}));
for (let index = 0; index < referrals.length; index++) {
const referral = referrals[index];
const jsonCount = JSON.stringify({
menuId: this.id,
callbackId: "delete",
data: referral.id
});
const keyboard = new InlineKeyboard()
.text(Globals.PATIENTREFERMENU_DELETE, `${jsonCount}`)
await this.commitMessage(ctx,
ctx.reply(format(Globals.PATIENTREFERMENU_HEAD, referral.id,
referral.text, referral.date.toLocaleString("uk", { year: "numeric", month: "long", day:
"numeric"})), {
reply_markup: keyboard
}));
113
482. ЧДТУ.242054 12-01
}
}
}
ReceptionService.ts
import { PrismaClient, Patient, Reception } from "@prisma/client";
import { injectable } from "tsyringe";
import { Globals } from "../../../Globals";
import moment from "moment";
import { start } from "repl";
@injectable()
export class ReceptionService {
public constructor(
private prisma: PrismaClient,
) { }
public getAvailableDays() {
const startDate = new Date();
const endDate = new Date()
endDate.setDate(startDate.getDate() + 10)
const dates = new Array<string>();
const curDate = new Date(startDate.getTime());
while (curDate <= endDate) {
const dayOfWeek = curDate.getDay();
var isWeekendDay = false;
Globals.DOCTOR_WORK_WEEKEND.forEach(weekDay => {
if(weekDay === (dayOfWeek == 0 ? 7 : dayOfWeek)) {
isWeekendDay = true;
}
114
482. ЧДТУ.242054 12-01
});
if(isWeekendDay === false){
dates.push(curDate.toLocaleString("uk", { year: "numeric", month: "long", day:
"numeric"}));
}
curDate.setDate(curDate.getDate() + 1);
}
return dates;
}
public async getAvailableHours(date: string, doctorId: number){
const dateTime = moment(date, "DD MMM YYYYY").toDate()
const receptions = await this.prisma.reception.findMany(
{
where: {
date: {
lte: new Date(dateTime.getTime() + 24 * 60 * 60 * 1000),
gte: dateTime
},
doctorId: doctorId
}
}
)
const sourceDateTime = new Date(dateTime.getTime());
const availableTime = Array<string>()
let startHours = Globals.DOCTOR_WORK_TIME[0]
const today = new Date();
115
482. ЧДТУ.242054 12-01
if(today.getFullYear() == dateTime.getFullYear()
&& today.getMonth() == dateTime.getMonth()
&& today.getDate() == dateTime.getDate())
{
if(today.getHours() > startHours){
startHours = today.getHours() + 1
}
}
const endHours = Globals.DOCTOR_WORK_TIME[1]
if(startHours > endHours){
return availableTime;
}
for (let hours = startHours; hours <= endHours; hours++) {
dateTime.setTime(sourceDateTime.getTime() + hours * 60 * 60 * 1000);
if(!receptions.find(reception => reception.date.getTime() === dateTime.getTime())){
availableTime.push(`${hours}:00`)
}
}
return availableTime;
}
public async getAvailableTimeReferral(date: string, doctorId: number){
const dateTime = moment(date, "DD MMM YYYYY").toDate()
const receptions = await this.prisma.referral.findMany(
{
where: {
date: {
lte: new Date(dateTime.getTime() + 24 * 60 * 60 * 1000),
116
482. ЧДТУ.242054 12-01
gte: dateTime
},
doctorId: doctorId
}
}
)
const sourceDateTime = new Date(dateTime.getTime());
const availableTime = Array<string>()
let startHours = Globals.DOCTOR_WORK_TIME[0]
const today = new Date();
if(today.getFullYear() == dateTime.getFullYear()
&& today.getMonth() == dateTime.getMonth()
&& today.getDate() == dateTime.getDate())
{
if(today.getHours() > startHours){
startHours = today.getHours()
}
}
const endHours = Globals.DOCTOR_WORK_TIME[1]
if(startHours > endHours){
return availableTime;
}
for (let hours = startHours; hours <= endHours; hours++) {
dateTime.setTime(sourceDateTime.getTime() + hours * 60 * 60 * 1000);
if(!receptions.find(reception => reception.date.getTime() === dateTime.getTime())){
availableTime.push(`${hours}:00`)
}
117
482. ЧДТУ.242054 12-01
}
return availableTime;
}
public async updateReception(date: string, patientId: number, doctorId: number){
return this.prisma.reception.upsert({
where: {
date: moment(date, "DD MMM YYYYY HH:mm").toDate()
},
update: {
date: moment(date, "DD MMM YYYYY HH:mm").toDate(),
doctorId: doctorId,
patientId: patientId,
finished: false
},
create: {
date: moment(date, "DD MMM YYYYY HH:mm").toDate(),
doctorId: doctorId,
patientId: patientId
}
}
);
}
public async getRecetionByPatientId(patientId: number){
return this.prisma.reception.findFirst(
{
where: {
patientId: patientId,
finished: false
},
118
482. ЧДТУ.242054 12-01
include:{
patient: true,
doctor: true
}
}
)
}
public async deleteRecetionByPatientId(patientId: number){
return this.prisma.reception.deleteMany(
{
where: {
patientId: patientId,
finished: false
}
}
)
}
public async getRecetionById(id: number){
return this.prisma.reception.findFirst(
{
where: {
id: id
},
include:{
patient: true,
doctor: true
}
}
)
}
119
482. ЧДТУ.242054 12-01
public async finishReception(receptionId: number){
return this.prisma.reception.update(
{
where: {
id: receptionId
},
data: {
finished: true
}
}
)
}
public async getReceptionsToday(doctorId: number){
const today = new Date()
today.setHours(0, 0, 0, 0)
return await this.prisma.reception.findMany(
{
where: {
doctorId: doctorId,
finished: false,
date: {
lte: new Date(today.getTime() + 24 * 60 * 60 * 1000),
gte: today
}
},
include:{
patient: {
include: {
doctor: true
}
120
482. ЧДТУ.242054 12-01
},
doctor: true
}
}
)
}
}
121
ДОДАТОК В
РОЗРОБКА TELEGRAM-БОТУ СІМЕЙНОГО ЛІКАРЯ
Інструкція користувача
482.ЧДТУ.242054 34-01
Листів 10
Розробник ________________ Куценко О.С.
Черкаси 2024
482.ЧДТУ. 242054 34-01
1. Для того, щоб почати користуватися telegram-боту, користувач повинен
отримати посилання.
2. Після натиснення на посилення користувач бачить меню боту, в якому
він повинен надати свій номер телефону.
Рисунок В.2 – Меню для надання номеру телефону
123
482.ЧДТУ. 242054 34-01
3. Після надання номеру телефону, він побачить головне меню.
Меню містить 4 кнопки:
1. «Моя медкарта»
2. «Мої прийоми»
3. «Мої рецепти»
4. «Мої направлення»
Рисунок В.3 – Головне меню
124
482.ЧДТУ. 242054 34-01
4. При натисненні кнопки «Медкарта», користувач може бачити свою
медичну картку пацієнта.
Рисунок В.4 – Медична карта пацієнта
5. При натисненні кнопки «Мої прийоми», користувач може зробити
запис на прийом до свого сімейного лікаря, обравши дату.
Рисунок В.5 – Меню запису на прийом
125
482.ЧДТУ. 242054 34-01
6. Наступним кроком, користувачу необхідно обрати час прийому (рис.
В.7), після обрання часу прийому, користувач отримає повідомлення про
успішний запис на прийом (рис В.8).
Рисунок В.6 – Меню запису на прийом
Рисуно В.7 – Успішний запис на прийом
126
482.ЧДТУ. 242054 34-01
7. Після успішного запису на прийом, в меню «Мої прийоми»
користувач побачить повідомлення про його активний запис. Користувач
має змогу змінити запис, або видалити його.
Рисунок В.8 - Інформація про активні записи на прийом
8. При натисненні на посилання, лікар бачить головне меню telegram-
боту. На екрані лікар може бачити 2 кнопки: «Мої пацієнти», «Мої Прийоми».
Рисунок В.9 – Головне меню для сімейного лікаря
127
482.ЧДТУ. 242054 34-01
9. При натисненні кнпоки «Мої пацієнти» в головному меню, лікар
бачить список своїх пацієнтів.
Рисунок В.10 – Список пацієнтів сімейного лікаря
10. При натисненні кнпоки «Зареєструвати», сімейний лікар має змогу
зареєструвати нового пацієнта. Для цього необхідно заповнити всі необхідні дані
(рис. В.11), після цього, в списку пацієнтів з’явиться новий пацієнт (рис. В.12).
Рисунок В.11 – Процес реєстрація нового пацієнта
128
482.ЧДТУ. 242054 34-01
Рисунок В.12 – Новий пацієнт в списку пацієнтів сімейного лікаря
11. Якщо сімейний лікар має активний запис на прийом, він побачить
відповідне повідомлення в меню «Мої прийоми»
Рисунок В.13 – Записи на прийом до сімейного лікаря
12. Коли прийом розпочнеться, сімейний лікар побачить меню активного
прийому.
Рисунок В.14 – Меню активного прийому у сімейного лікаря
129
482.ЧДТУ. 242054 34-01
13. Сімейний лікар може виписати рецепт пацієнту (рис. В.15), виписати
направлення до іншого лікаря (рис. В.16) та завершити прийом (рис. В.17).
Рисунок В.15 – Виписування рецепту
Рисунок В.16 – Виписування направлення
Рисунок В.17 – Завершення прийому
130
482.ЧДТУ. 242054 34-01
14. Після завершення прийому, у пацієнта рецепт та направлення
з’являться в меню «Мої рецепти» та «Мої направлення» відповідно (рис. В.18-
В.19).
Рисунок В.18 – Виписаний лікарем рецепт у пацієнта
Рисунок В.19 – Виписане лікарем направлення у пацієнта
131
ДОДАТОК Г
РОЗРОБКА TELEGRAM-БОТУ СІМЕЙНОГО ЛІКАРЯ
Графічні матеріали
482.ЧДТУ.242054 90-01
Листів 7
Розробник ________________ Куценко О.С.
Черкаси 2024
482.ЧДТУ. 242054 90-01
Рисунок Г.1 – Слайд 1
Рисунок Г.2 – Слайд 2
133
482.ЧДТУ. 242054 90-01
Рисунок Г.3 – Слайд 3
Рисунок Г.4 – Слайд 4
134
482.ЧДТУ. 242054 90-01
Рисунок Г.5 – Слайд 5
Рисунок Г.6 – Слайд 6
135
482.ЧДТУ. 242054 90-01
Рисунок Г.7 – Слайд 7
Рисунок Г.8 – Слайд 8
136
482.ЧДТУ. 242054 90-01
Рисунок Г.9 – Слайд 9
Рисунок Г.10 – Слайд 10
137
482.ЧДТУ. 242054 90-01
Рисунок Г.11 – Слайд 11
Рисунок Г.12 – Слайд 12
138