Please use this identifier to cite or link to this item: https://er.chdtu.edu.ua/handle/ChSTU/9700
Title: Інтернет-магазин з продажу нумізматичної продукції
Authors: Дяченко, Петро Васильович
Фоменко, Станіслав Павлович
Keywords: НУМІЗМАТИКА;ІНТЕРНЕТ-МАГАЗИН;АУКЦІОН;КОМП'ЮТЕРНИЙ ЗІР;PRISMA ORM;SOCKET.IO;GEMINI API;DOCKER.
Issue Date: 11-Jun-2026
Abstract: Актуальність теми. Сучасний ринок нумізматики потребує цифровізації процесів купівлі-продажу колекційних монет. Традиційні способи торгівлі через аукціонні доми та особисті зустрічі обмежують географічну доступність, швидкість транзакцій та масштабованість ринку. Крім того, ідентифікація та оцінка старовинних монет вимагає вузькоспеціалізованих експертних знань, які є недоступними для пересічного колекціонера. Розробка веб-орієнтованої платформи з інтегрованими інструментами штучного інтелекту дозволяє вирішити ці проблеми, забезпечуючи зручний доступ до глобального ринку, автоматизовану експертизу монет та прозорі аукціонні механізми в реальному часі. Мета роботи і задачі дослідження. Метою кваліфікаційної роботи бакалавра є створення повнофункціонального веб-застосунку для нумізматичного інтернет-магазину з інтеграцією технологій штучного інтелекту для автоматичної ідентифікації, класифікації та оцінки колекційних монет за їх зображеннями. Об’єкт дослідження: процеси автоматизації торгівлі нумізматичними товарами з використанням веб-технологій та засобів штучного інтелекту. Предмет дослідження: методи, технології та архітектурні рішення для побудови веб-застосунку нумізматичного інтернет-магазину з функціональністю аукціонів у реальному часі та інтегрованим модулем комп'ютерного зору на основі API великих мовних моделей.
URI: https://er.chdtu.edu.ua/handle/ChSTU/9700
Appears in Collections:122 Комп’ютерні науки (Комп’ютерні науки та прикладне програмування)

Files in This Item:
File Description SizeFormat 
Пояснювальна записка_Фоменко Станіслав_КН-2201_2025-2026.pdf
  Restricted Access
1.45 MBAdobe PDFView/Open Request a copy


Items in DSpace are protected by copyright, with all rights reserved, unless otherwise indicated.

Extracted text
 МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ  
ЧЕРКАСЬКИЙ ДЕРЖАВНИЙ ТЕХНОЛОГІЧНИЙ УНІВЕРСИТЕТ 
 
Факультет інформаційних технологій і систем 
 
Кафедра комп’ютерних наук та системного аналізу 
 
 
 
 
 
 
 
Пояснювальна записка 
до кваліфікаційної роботи 
                                         бакалавра       
 (освітньо-кваліфікаційний рівень) 
 
на тему: «Інтернет-магазин з продажу нумізматичної продукції» 
 
 
 
 
 
                                                            Виконав: студент 4 курсу, групи КН-2201 
 
                                                           спеціальності 122  «Комп’ютерні науки» 
                                                                                                                                          (шифр і назва спеціальності) 
 
                                                          Освітня програма «Комп’ютерні науки та  
                                                                                                                                                                 (назва освітньої програми) 
                                  прикладне програмування» 
 
                Станіслав ФОМЕНКО 
 
                                                              Керівник                           Петро ДЯЧЕНКО  
                                                                                                                                                                                              (ім’я  та прізвище) 
 
  Рецензент              Костянтин БЕЗДОЛЕНКО         
                                                                                         (ім’я  та прізвище) 
    
 
 
 
 
 
 
 
 
 
Черкаси 2026 року 
2 
Бланк завдання на кваліфікаційну роботу бакалавра студенту 
 
Черкаський державний технологічний університет 
Факультет Інформаційних технологій і систем 
Кафедра Комп’ютерних наук та системного аналізу 
Освітньо-кваліфікаційний рівень Бакалавр 
Спеціальність 122  –  Комп’ютерні науки 
Освітня програма Комп’ютерні науки та прикладне програмування 
 
 
 
ЗАТВЕРДЖУЮ 
Завідувач кафедри КНСА  
_______________ Юрій ТРИУС 
«____» _____________ 2026 р. 
 
 
ЗАВДАННЯ 
на кваліфікаційну роботу бакалавра студенту 
Фоменку Станіславу Павловичу 
(прізвище, ім‘я, по батькові) 
1. Тема роботи  Інтернет-магазин з продажу нумізматичної продукції 
Керівник роботи     Дяченко П.В., к.т.н., доцент                   
(прізвище, ім’я, по батькові, науковий ступінь, вчене звання) 
затверджені наказом університету від «12» березня 2026 р. №56/03-03. 
2. Строк подання студентом роботи «  08  »   червня  20 26 року. 
3. Вихідні дані до роботи: 
Відомості про сучасний ринок нумізматики. 
Звіт з виробничої практики. Звіт з переддипломної практики. 
4. Зміст пояснювальної записки (перелік питань, що їх належить розробити): 
Вступ 
4.1. Аналітичний огляд літературних та інших джерел. 
4.2. Системний аналіз та обґрунтування проблеми. 
4.3. Методи та засоби вирішення проблеми. 
4.4. Аналіз та проєктування системи. 
4.5. Практична реалізація та аналіз результатів. 
Висновки.  
5. Перелік додатків (з точним зазначенням назв додатків): 
5.1. Додаток А. Специфікація 482. ЧДТУ. 62295-01. 
5.2. Додаток Б. Текст програми. 
5.3. Додаток В.  Лістинги ключових компонентів клієнтської частини веб-застосунку NumisMarket. 
5.4. Додаток Г.  Програма і методика випробувань. 
5.5. Додаток Д.  Інструкція користувача. 
5.6. Презентація у вигляді 23 слайдів. 
 
3 
6. Консультанти розділів роботи 
Прізвище, ініціали та Підпис, дата 
Розділ 
посада консультанта завдання видав завдання прийняв 
    
    
 
7. Дата видачі завдання 12.01.2026 р. 
  
 
КАЛЕНДАРНИЙ ПЛАН 
Строк виконання 
№ з/п Назва етапів кваліфікаційної роботи бакалавра Примітка 
етапів роботи 
1 Видача завдання на кваліфікаційну роботу 
12.01.2026  Виконано 
бакалавра. 
2 Аналіз літературних джерел, об’єкту та предмету Виконано 
до 08.02.2026 
дослідження. 
3 Написання теоретичного розділу кваліфікаційної Виконано 
до 23.03.2026 
роботи бакалавра. 
4 Написання аналітичного розділу кваліфікаційної Виконано 
до 06.04.2026 
роботи бакалавра. 
5 Написання практичних розділів й висновків до Виконано 
до 15.05.2026 
кваліфікаційної роботи бакалавра. 
6 Передзахист кваліфікаційної роботи бакалавра Виконано 
20.05.2026 
на засіданні кафедри КНСА. 
7 Подання роботи завідувачу кафедри КНСА. до 10.06.2026 Виконано 
8 Захист кваліфікаційної роботи бакалавра. 10.06.2026 Виконано 
    
    
 
 
 
 
Студент                                   _____________________________     Станіслав ФОМЕНКО 
                                                                            (підпис)                                                                     
 
Керівник роботи                     ____________________________       Петро ДЯЧЕНКО 
                                           (підпис)      
 
                                                              
 
  
 
4 
РЕФЕРАТ 
Кваліфікаційна робота бакалавра містить: 112 с., 3 рис., 30 табл., 50 
використаних джерел, 5 додатків. 
Актуальність теми. Сучасний ринок нумізматики потребує цифровізації 
процесів купівлі-продажу колекційних монет. Традиційні способи торгівлі через 
аукціонні доми та особисті зустрічі обмежують географічну доступність, швидкість 
транзакцій та масштабованість ринку. Крім того, ідентифікація та оцінка старовинних 
монет вимагає вузькоспеціалізованих експертних знань, які є недоступними для 
пересічного колекціонера. Розробка веб-орієнтованої платформи з інтегрованими 
інструментами штучного інтелекту дозволяє вирішити ці проблеми, забезпечуючи 
зручний доступ до глобального ринку, автоматизовану експертизу монет та прозорі 
аукціонні механізми в реальному часі. 
Мета роботи і задачі дослідження. Метою кваліфікаційної роботи бакалавра є 
створення повнофункціонального веб-застосунку для нумізматичного інтернет-
магазину з інтеграцією технологій штучного інтелекту для автоматичної 
ідентифікації, класифікації та оцінки колекційних монет за їх зображеннями. 
Для досягнення поставленої мети потрібно вирішити такі задачі: 
– провести аналіз предметної області, огляд існуючих рішень для онлайн-
торгівлі нумізматичними товарами та визначити функціональні вимоги до системи; 
– спроєктувати архітектуру системи на основі клієнт-серверної моделі з 
використанням REST API та WebSocket-з'єднань для реального часу; 
– спроєктувати та реалізувати реляційну базу даних на основі PostgreSQL із 
використанням Prisma ORM; 
– розробити серверну частину на платформі Node.js із використанням веб-
фреймворку Express.js; 
– реалізувати клієнтську частину з використанням Next.js, React та Tailwind 
CSS із адаптивним інтерфейсом; 
– інтегрувати модуль штучного інтелекту на основі Google Gemini API для 
комп'ютерного зору з метою аналізу зображень монет, визначення їх характеристик 
та оцінки стану; 
 
5 
– реалізувати систему аукціонів у реальному часі з використанням Socket.IO, 
включно з механізмом антиснайпінгу; 
– впровадити систему ролей (користувач, продавець, адміністратор) із 
відповідними рівнями доступу та панелями управління; 
– реалізувати модуль обміну повідомленнями між користувачами в реальному 
часі; 
– розгорнути систему в контейнеризованому середовищі Docker для 
забезпечення переносимості та простоти розгортання. 
Об’єкт дослідження: процеси автоматизації торгівлі нумізматичними 
товарами з використанням веб-технологій та засобів штучного інтелекту. 
Предмет дослідження: методи, технології та архітектурні рішення для 
побудови веб-застосунку нумізматичного інтернет-магазину з функціональністю 
аукціонів у реальному часі та інтегрованим модулем комп'ютерного зору на основі 
API великих мовних моделей. 
Методи дослідження: аналіз предметної області - для визначення 
функціональних вимог до системи; об'єктно-орієнтоване проєктування - для 
побудови моделі даних та архітектури застосунку; методи веб-розробки (REST API, 
WebSocket, SPA) - для реалізації клієнтської та серверної частин; методи інтеграції 
API штучного інтелекту - для реалізації функції комп'ютерного зору; методи 
контейнеризації - для розгортання системи. 
Ключові слова: ВЕБ-ЗАСТОСУНОК, НУМІЗМАТИКА, ЕЛЕКТРОННА 
КОМЕРЦІЯ, ІНТЕРНЕТ-МАГАЗИН, АУКЦІОН, ШТУЧНИЙ ІНТЕЛЕКТ, 
КОМП'ЮТЕРНИЙ ЗІР, NEXT.JS, REACT, NODE.JS, EXPRESS.JS, POSTGRESQL, 
PRISMA ORM, SOCKET.IO, GEMINI API, DOCKER. 
ABSTRACT 
The bachelor’s qualification thesis consists of: 112 pages, 3 figures, 30 tables, 50 
sources, 5 appendices. 
Relevance of the topic. The modern numismatic market requires digitalization of the 
processes of buying and selling collectible coins. Traditional trading methods through 
auction houses and personal meetings limit the geographical accessibility, transaction speed, 
 
6 
and scalability of the market. In addition, the identification and evaluation of antique coins 
requires highly specialized expert knowledge that is inaccessible to the average collector. 
The development of a web-based platform with integrated artificial intelligence tools allows 
solving these problems by providing convenient access to the global market, automated coin 
expertise, and transparent real-time auction mechanisms. 
Purpose and objectives of the research. The aim of the work is to create a full-
featured web application for a numismatic online store with the integration of artificial 
intelligence technologies for automatic identification, classification, and evaluation of 
collectible coins based on their images. 
The following tasks were solved to achieve the goal: 
– an analysis of the subject area was carried out, existing solutions for online 
numismatic trading were reviewed, and functional requirements for the system were 
defined; 
– the system architecture was designed based on a client-server model using REST 
API and WebSocket connections for real-time communication; 
– a relational database based on PostgreSQL was designed and implemented using 
Prisma ORM; 
– the server-side application was developed on the Node.js platform using the 
Express.js web framework; 
– the client-side application was implemented using Next.js, React, and Tailwind 
CSS with a responsive user interface; 
– an artificial intelligence module based on Google Gemini API for computer vision 
was integrated to analyze coin images, determine their characteristics, and assess their 
condition; 
– a real-time auction system was implemented using Socket.IO, including an anti-
sniping mechanism; 
– a role-based access control system (user, seller, administrator) was implemented 
with corresponding management dashboards; 
– a real-time messaging module between users was implemented; 
 
7 
– the system was deployed in a Docker containerized environment to ensure 
portability and ease of deployment. 
Object of study: processes of automating numismatic goods trading using web 
technologies and artificial intelligence tools. 
Subject of the study: methods, technologies, and architectural solutions for building 
a web application for a numismatic online store with real-time auction functionality and an 
integrated computer vision module based on large language model APIs. 
Research methods: subject area analysis - to determine the functional requirements 
for the system; object-oriented design - to build the data model and application architecture; 
web development methods (REST API, WebSocket, SPA) - to implement the client and 
server parts; AI API integration methods - to implement the computer vision function; 
containerization methods - for system deployment. 
Keywords: WEB APPLICATION, NUMISMATICS, E-COMMERCE, ONLINE 
STORE, AUCTION, ARTIFICIAL INTELLIGENCE, COMPUTER VISION, NEXT.JS, 
REACT, NODE.JS, EXPRESS.JS, POSTGRESQL, PRISMA ORM, SOCKET.IO, 
GEMINI API, DOCKER. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8 
ЗМІСТ 
ПЕРЕЛІК УМОВНИХ ПОЗНАЧЕНЬ, СИМВОЛІВ, СКОРОЧЕНЬ І 
ТЕРМІНІВ…...Ошибка! Закладка не определена. 
ВСТУП ................................................................................................................................ 12 
1 АНАЛІТИЧНИЙ ОГЛЯД ЛІТЕРАТУРНИХ ТА ІНШИХ ДЖЕРЕЛ ........................ 17 
1.1 Аналіз предметної області нумізматичної електронної комерції ................. ….17 
1.2 Огляд та аналіз існуючих рішень для нумізматичної електронної комерції .... 18 
1.3 Аналіз технологій розробки веб-застосунків та вибір інструментальних 
засобів ................................................................................................................................. 19 
1.4 Аналіз технологій штучного інтелекту для атрибуції та оцінки монет ............ 21 
1.5 Аналіз технологій штучного інтелекту для атрибуції та оцінки монет ............ 22 
1.6 Аналіз підходів до забезпечення авторизації та управління доступом ............. 23 
1.7 Аналіз підходів до проектування користувацького інтерфейсу ........................ 24 
Висновки до розділу 1 .................................................................................................. 25 
2 СИСТЕМНИЙ АНАЛІЗ ТА ОБҐРУНТУВАННЯ ПРОБЛЕМИ ................................ 26 
2.1 Системний аналіз об'єкта дослідження та предметної області .......................... 26 
2.1.1 Аналіз існуючої ситуації (модель «as is») ..................................................... 27 
2.1.2 Аналіз потоків даних ....................................................................................... 29 
2.1.3 Аналіз потоків даних ....................................................................................... 30 
2.2 Постановка та обґрунтування проблеми (концептуальна модель системи «to 
be») ...................................................................................................................................... 31 
2.2.1 Концептуальна модель системи «to be» ......................................................... 31 
2.2.2 Модель ролей та прав доступу ........................................................................ 32 
2.2.3 Вимоги до системи ........................................................................................... 33 
Висновки до розділу 2 .................................................................................................. 34 
3 МЕТОДИ ТА ЗАСОБИ ВИРІШЕННЯ ПРОБЛЕМИ .................................................. 36 
3.1 Вибір та обґрунтування методів вирішення проблеми ....................................... 36 
3.2 Вибір та обґрунтування засобів (СУБД, технології, мови програмування)...... 39 
3.3 Опис та обґрунтування алгоритмів………………………………………………44 
3.3.1 Алгоритм розміщення ставки на аукціоні з антиснайпінгом ...................... 44 
 
9 
3.3.2 Алгоритм аналізу зображень монет AI-асистентом ..................................... 45 
3.3.3 Алгоритм обробки замовлення та управління станом ................................. 47 
 Висновки до розділу 3 ................................................................................................. 49 
4 АНАЛІЗ ТА ПРОЄКТУВАННЯ СИСТЕМИ ............................................................... 50 
4.1 Об'єктно-орієнтований аналіз вимог ..................................................................... 50 
4.1.1 Словник предметної області ........................................................................... 50 
4.1.2 Актори та варіанти використання .................................................................. 52 
4.1.3 Опис основних бізнес-процесів та потоків даних ........................................ 53 
4.2 Об'єктно-орієнтоване проєктування (PIM та PSM моделі) ................................. 54 
4.2.1 PIM-модель: платформо-незалежна модель системи ................................... 55 
4.2.2 PSM-модель: платформо-специфічна модель системи ................................ 57 
4.2.3 Логічна структура системи.............................................................................. 58 
4.2.4 Фізична структура системи ............................................................................. 59 
4.3 Динамічна поведінка системи (діаграми взаємодії) ............................................ 59 
4.3.1 Діаграма послідовності: розміщення ставки на аукціоні ............................. 59 
4.3.2 Діаграма послідовності: AI-аналіз монети .................................................... 60 
4.3.3 Діаграма послідовності: створення запису колекції ..................................... 61 
4.3.4 Діаграма станів: життєвий цикл аукціону ..................................................... 61 
Висновки до розділу 4 .................................................................................................. 62 
5 ПРАКТИЧНА РЕАЛІЗАЦІЯ ТА АНАЛІЗ РЕЗУЛЬТАТІВ ........................................ 64 
5.1 Опис реалізації завдання ........................................................................................ 64 
5.1.1 Структура бази даних ...................................................................................... 64 
5.1.2 Склад та функції програмних модулів серверної частини .......................... 66 
5.1.3 Склад та функції клієнтської частини ............................................................ 69 
5.1.4 Взаємодія компонентів системи ..................................................................... 71 
5.1.5 Реалізація ключових алгоритмів ..................................................................... 72 
5.2 Аналіз результатів ................................................................................................... 73 
5.2.1 Контрольний приклад: розміщення ставки на аукціоні ............................... 73 
5.2.2 Контрольний приклад: AI-аналіз монети ...................................................... 74 
5.2.3 Контрольний приклад: управління колекцією .............................................. 75 
 
10 
5.2.4 Відповідність функціональним та нефункціональним вимогам ................. 75 
5.2.5 Теоретична та практична цінність результатів ............................................. 77 
Висновки до розділу 5 .................................................................................................. 77 
ВИСНОВКИ ....................................................................................................................... 79 
РЕКОМЕНДАЦІЇ ............................................................................................................... 80 
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ ......................................................................... 82 
Додаток А. Специфікація 482.ЧДТУ. 62295-01 ............................................................. 86 
Додаток Б. Текст програми............................................................................................... 88 
Додаток В. Лістинги ключових компонентів клієнтської частини веб-застосунку 
NumisMarket……………………………………………………………………………...99 
Додаток Г. Програма і методика випробувань……………………………………….106 
Додаток Д. Інструкція користувача...............................................................................110 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11 
ПЕРЕЛІК УМОВНИХ ПОЗНАЧЕНЬ, СИМВОЛІВ, СКОРОЧЕНЬ І ТЕРМІНІВ 
API - Application Programming Interface, інтерфейс програмування застосунків. 
Angular - Фреймворк для побудови односторінкових веб-застосунків. 
ChromaDB - Векторна база даних для зберігання ембеддингів і семантичного пошуку. 
GLiNER2 - Мультимовна модель розпізнавання іменованих сутностей. 
HTTP - HyperText Transfer Protocol, протокол передавання гіпертексту. 
JSON - JavaScript Object Notation, текстовий формат обміну даними. 
JWT - JSON Web Token, формат токена для автентифікації. 
LLM - Велика мовна модель; у роботі цей термін використовується як загальне 
позначення моделей NLP. 
NER - Named Entity Recognition, розпізнавання іменованих сутностей. 
OCR - Optical Character Recognition, оптичне розпізнавання символів. 
REST - Representational State Transfer, архітектурний стиль для веб-сервісів. 
SPA - Single Page Application, односторінковий вебзастосунок. 
SQL - Structured Query Language, мова запитів до реляційних баз даних. 
XML - Extensible Markup Language, мова розмітки даних. 
МПД - Модуль постобробки даних, що виконує очищення та нормалізацію 
результатів. 
ПІБ - Прізвище, ім’я, по батькові. 
ПЗ - Програмне забезпечення. 
СУБД - Система управління базами даних. 
  
 
12 
ВСТУП 
В епоху стрімкої цифровізації всіх сфер людської діяльності електронна 
комерція стала невід'ємною складовою сучасної економіки. Особливої актуальності 
набуває розробка спеціалізованих інформаційних систем для нішевих ринків, які 
традиційно функціонували в офлайн-середовищі і мають специфічні потреби, що не 
задовольняються універсальними торговельними платформами. Нумізматика як 
галузь колекціонування та торгівлі стародавніми й сучасними монетами є одним із 
таких нішевих ринків, який потребує цифрової трансформації з урахуванням своєї 
специфіки : необхідності експертної оцінки стану монет, визначення їх автентичності, 
історичної цінності та рідкості. 
Актуальність теми. Актуальність теми кваліфікаційної робти бакалавра 
зумовлена кількома факторами. По-перше, глобальний ринок нумізматичних товарів 
оцінюється в мільярди доларів і продовжує зростати, однак переважна більшість 
транзакцій здійснюється через традиційні аукціонні дому та спеціалізовані fora, що 
обмежує доступність ринку для широкого кола колекціонерів. По-друге, 
ідентифікація та атрибуція монет є складним експертним завданням, яке вимагає 
глибоких нумізматичних знань, недоступних переважній більшості колекціонерів-
аматорів. По-третє, стрімкий розвиток технологій штучного інтелекту, зокрема 
комп'ютерного зору та великих мовних моделей, відкриває нові можливості для 
автоматизації експертної оцінки колекційних об'єктів, що раніше були виключно 
прерогативою кваліфікованих спеціалістів. 
Таким чином, існує об'єктивна потреба у створенні комплексної веб-
орієнтованої платформи для нумізматичного ринку, яка б поєднувала 
функціональність електронної комерції з інструментами автоматизованої експертизи 
на основі штучного інтелекту, механізмами аукціонної торгівлі в реальному часі та 
системою управління персональними колекціями. Розробка такої системи становить 
як практичну, так і наукову цінність, оскільки передбачає розв'язання комплексу 
взаємопов'язаних задач у галузі веб-інженерії, проектування баз даних, інтеграції API 
штучного інтелекту та проектування користувацьких інтерфейсів. 
 
13 
Оцінка стану проблеми. Аналіз сучасного стану проблеми розробки веб-
платформ для нумізматичного ринку свідчить про наявність ряду існуючих рішень, 
кожне з яких має відомі обмеження. Серед провідних зарубіжних платформ варто 
виділити такі сервіси, як eBay, який хоча і забезпечує широку аудиторію, не пропонує 
спеціалізованих інструментів для атрибуції та оцінки монет; Professional Coin Grading 
Service (PCGS) та Numismatic Guaranty Corporation (NGC), які зосереджені переважно 
на фізичній сертифікації монет і не надають повноцінних інструментів онлайн-
торгівлі; а також VCoins та MA-Shops, які є спеціалізованими нумізматичними 
маркетплейсами, але позбавлені функцій автоматизованої експертизи та управління 
колекціями. 
Вітчизняні розробки у сфері нумізматичної електронної комерції практично 
відсутні. Український ринок обслуговується переважно через соціальні мережі, 
форуми (наприклад, «Нумізматика» ucoin.net) та загальні Classifieds-платформи, що 
не забезпечують необхідного рівня функціональності, безпеки транзакцій та 
експертної підтримки. Це створює значний розрив між потребами українських 
колекціонерів та доступними цифровими інструментами. 
У науковому плані проблематика розробки спеціалізованих електронних 
комерційних систем досліджувалася у працях В. М. Грушманса, О. Б. Теслюка та І. В. 
Дулінської у галузі проєктування інформаційних систем; В. В. Пасічника та В. С. 
Глушка у сфері баз даних та інтелектуального аналізу даних; а також у роботах 
зарубіжних вчених  Я. Самера (інтеграція штучного інтелекту в електронну 
комерцію), Р. Кумара (мультимодальні нейронні мережі для аналізу зображень) та 
інших [40-42]. Проте комплексний підхід до поєднання електронної комерції, 
аукціонних механізмів реального часу, управління колекціями та AI-асистованого 
аналізу в єдиній платформі залишається недостатньо дослідженим. 
Світові тенденції. Аналіз світових тенденцій свідчить про кілька ключових 
напрямків розвитку, що безпосередньо впливають на предмет даного дослідження.  
По-перше, спостерігається стрімка міграція нумізматичного ринку в цифрове 
середовище: за даними дилеровьких асоціацій, обсяг онлайн-продажів колекційних 
монет зріс більш ніж на 40% за останні п'ять років.  
 
14 
По-друге, технології штучного інтелекту, зокрема великі мовні моделі (LLM) та 
системи комп'ютерного зору, досягли рівня, що дозволяє надійно розпізнавати та 
класифікувати об'єкти на зображеннях з високою точністю. Зокрема, моделі сімейства 
Google Gemini демонструють можливість мультимодельного аналізу, одночасно 
оброблюючи текстові та візуальні дані, що є критично важливим для задач атрибуції 
монет. 
По-третє, архітектурні парадигми розробки веб-застосунків зазнали суттєвої 
еволюції. Перехід від монолітної архітектури до мікросервісної, поширення JAM-
стеку (JavaScript, API, Markup) та фреймворків серверного рендерингу (Next.js, 
Nuxt.js, SvelteKit) дозволяє створювати високопродуктивні, масштабовані та SEO-
оптимізовані застосунки. Використання ORM-інструментів нового покоління (Prisma, 
Drizzle) суттєво спрощує взаємодію з реляційними базами даних та забезпечує 
типобезпечність на рівні TypeScript. Протоколи реального часу (WebSocket, 
Socket.IO) дають змогу реалізувати інтерактивні функції, такі як новітні аукціони з 
антиснайпінгом та живий чат. 
По-четверте, контейнеризація на основі Docker та оркестрація через Docker 
Compose стали стандартом де-факто для розгортання веб-застосунків, забезпечуючи 
відтворюваність середовища, ізоляцію сервісів та простоту масштабування. Це 
створює сприятливі умови для розробки та розгортання комплексних 
багатокомпонентних систем, якими є спеціалізовані електронні комерційні 
платформи. 
Разом з тим, існуючі світові рішення не передбачають комплексної інтеграції 
всіх перелічених технологій у єдиному застосунку для нумізматичного ринку. 
Більшість платформ реалізують лише окремі функції або лише торгівлю, або лише 
каталогізацію, або лише експертну оцінку. Це підтверджує актуальність та 
доцільність розробки комплексного рішення, що поєднує всі зазначені аспекти. 
Зв'язок роботи з науковими програмами. Тема кваліфікаційної роботи  
бакалавра пов'язана з науково-дослідною роботою кафедри комп’ютерних наук та 
системного аналізу Черкаського державного технологічного університету.  
 
15 
Мета та задачі дослідження. Метою кваліфікаційної роботи бакалавра є 
створення повнофункціонального веб-застосунку для нумізматичного інтернет-
магазину з інтеграцією технологій штучного інтелекту для автоматичної 
ідентифікації, класифікації та оцінки колекційних монет за їх зображеннями. 
Для досягнення поставленої мети потрібно вирішити такі задачі: 
– провести аналіз предметної області, огляд існуючих рішень для онлайн-
торгівлі нумізматичними товарами та визначити функціональні вимоги до системи; 
– спроєктувати архітектуру системи на основі клієнт-серверної моделі з 
використанням REST API та WebSocket-з'єднань для реального часу; 
– спроєктувати та реалізувати реляційну базу даних на основі PostgreSQL із 
використанням Prisma ORM; 
– розробити серверну частину на платформі Node.js із використанням веб-
фреймворку Express.js; 
– реалізувати клієнтську частину з використанням Next.js, React та Tailwind 
CSS із адаптивним інтерфейсом; 
– інтегрувати модуль штучного інтелекту на основі Google Gemini API для 
комп'ютерного зору з метою аналізу зображень монет, визначення їх характеристик 
та оцінки стану; 
– реалізувати систему аукціонів у реальному часі з використанням Socket.IO, 
включно з механізмом антиснайпінгу; 
– впровадити систему ролей (користувач, продавець, адміністратор) із 
відповідними рівнями доступу та панелями управління; 
– реалізувати модуль обміну повідомленнями між користувачами в реальному 
часі; 
– розгорнути систему в контейнеризованому середовищі Docker для 
забезпечення переносимості та простоти розгортання. 
Об’єкт дослідження: процеси автоматизації торгівлі нумізматичними 
товарами з використанням веб-технологій та засобів штучного інтелекту. 
Предмет дослідження: методи, технології та архітектурні рішення для 
побудови веб-застосунку нумізматичного інтернет-магазину з функціональністю 
 
16 
аукціонів у реальному часі та інтегрованим модулем комп'ютерного зору на основі 
API великих мовних моделей. 
Методи дослідження: аналіз предметної області - для визначення 
функціональних вимог до системи; об'єктно-орієнтоване проєктування - для 
побудови моделі даних та архітектури застосунку; методи веб-розробки (REST API, 
WebSocket, SPA) - для реалізації клієнтської та серверної частин; методи інтеграції 
API штучного інтелекту - для реалізації функції комп'ютерного зору; методи 
контейнеризації - для розгортання системи. 
Наукова новизна. Наукова новизна роботи полягає у комплексному підході до 
розробки веб-платформи для нумізматичного ринку, що вперше поєднує: 
мультимодельний AI-модуль для автоматичної атрибуції та оцінки монет за їх 
зображеннями з використанням великих мовних моделей сімейства Google Gemini; 
механізм аукціонної торгівлі в реальному часі з протоколом антиснайпінгу на основі 
Socket.IO; систему управління персональними колекціями з можливістю каталогізації 
монет; архітектуру на основі контейнеризованих мікросервісів, що забезпечує 
масштабованість та відтворюваність розгортання. 
Практичне значення. Практичне значення роботи полягає у тому, що 
розроблений веб-застосунок NumisMarket - готовий до впровадження програмний 
продукт, який може бути використаний для створення повнофункціонального 
нумізматичного інтернет-магазину. Застосунок забезпечить повний цикл операцій: 
від реєстрації користувачів та створення товарних пропозицій до проведення 
аукціонів в реальному часі, обробки замовлень та управління колекціями. 
Інтегрований AI-асистент дозволить автоматизувати процес атрибуції монет, що 
суттєво знижує бар'єр входу на ринок для початківців-колекціонерів та підвищує 
ефективність роботи продавців. 
 
 
 
 
 
17 
1 АНАЛІТИЧНИЙ ОГЛЯД ЛІТЕРАТУРНИХ ТА ІНШИХ ДЖЕРЕЛ 
1.1 Аналіз предметної області та постановка задачі дослідження 
Нумізматика як галузь колекціонування та науково-історичного дослідження 
монет має багатовікову історію. Протягом останнього десятиліття цей ринок зазнав 
суттєвої трансформації під впливом цифрових технологій. За даними доповіді 
компанії Mordor Intelligence [1], глобальний ринок нумізматичних монет оцінювався 
у 17,4 млрд доларів США у 2023 році з прогнозованим зростанням до 26,8 млрд 
доларів до 2030 року, що становить середньорічний темп зростання на рівні 6,3%. 
Такі показники свідчать про стійке зростання інтересу до колекціонування монет як 
інвестиційного та культурного явища. 
Однак, незважаючи на зазначене зростання, нумізматичний ринок 
характеризується низкою специфічних проблем, які суттєво відрізняють його від 
інших сегментів електронної комерції.  
По-перше, процес атрибуції монет  визначення їхнього походження, року 
випуску, номіналу, матеріалів виготовлення та ступеня збереженості вимагає 
вузькоспеціалізованих знань, якими володіють лише кваліфіковані нумізмати [2].  
По-друге, оцінка рідкості та ринкової вартості монети залежить від множини 
чинників, включаючи історичну значущість, тираж, стан збереженості та колекційний 
попит [3].  
По-третє, традиційна аукціонна торгівля монетами характеризується високим 
порогом входу для початківців-колекціонерів, що зумовлено необхідністю фізичної 
присутності на аукціоні або складністю процедури участи в онлайн-аукціонах та 
відсутністю механізмів антиснайпінгу [4]. 
Зазначені проблеми формують об'єктивну потребу у створенні спеціалізованої 
веб-платформи, яка б комплексно вирішувала всі перелічені завдання: забезпечувала 
б функціональність електронної комерції, автоматизовану атрибуцію монет на основі 
технологій штучного інтелекту, механізми аукціонної торгівлі в реальному часі та 
інструменти управління персональними колекціями. Проаналізуємо існуючі підходи 
до розв'язання цих задач. 
 
18 
1.2 Огляд та аналіз існуючих рішень для нумізматичної електронної 
комерції 
Аналіз існуючих платформ для нумізматичної торгівлі дозволяє виділити три 
основні категорії рішень: універсальні маркетплейси, спеціалізовані нумізматичні 
платформи та сертифікаційні сервіси. 
Універсальні маркетплейси. Найбільшою платформою для нумізматичної 
торгівлі є eBay [5], яка забезпечує широкий доступ до глобальної аудиторії та володіє 
розвиненою системою оплати (eBay Managed Payments). Проте eBay має низку 
суттєвих недоліків з позицій niche-орієнтованого ринку: відсутність спеціалізованих 
інструментів атрибуції та оцінки стану монет, неможливість проведення аукціонів у 
реальному часі з антиснайпінгом, а також відсутність функцій управління 
колекціями. Крім того, вартість розміщення лотів та комісійні збори є значними для 
приватних продавців [6]. 
Спеціалізовані нумізматичні платформи. До цієї категорії належать VCoins [7] 
та MA-Shops [8], які є провідними міжнародними платформами для торгівлі 
античними та колекційними монетами. VCoins функціонує як маркетплейс, де 
зареєстровані дилери пропонують монети за фіксованими цінами, забезпечуючи 
аутентичність та гарантію повернення коштів. Проте платформа не підтримує 
аукціонну торгівлю, не надає інструментів AI-асистованої атрибуції та орієнтована 
виключно на професійних дилерів, що унеможливлює участь приватних 
колекціонерів як продавців. MA-Shops реалізує подібну модель, зосереджуючись на 
верифікованих продавцях, однак також позбавлена функцій управління колекціями 
та інтелектуальної атрибуції [9]. 
Сертифікаційні сервіси. Професійні сервіси градації монет - Professional Coin 
Grading Service (PCGS) [10] та Numismatic Guaranty Corporation (NGC) [11] займають 
окрему нішу ринку, пропонуючи фізичну сертифікацію монет. Процедура градації 
включає огляд монети експертами, присвоєння числової оцінки стану за шкалою 
Шелдона (від 1 до 70) та герметичне упакування у пластиковий холдер (slab) із 
зазначенням усіх атрибутів. Проте цей підхід має суттєві обмеження: тривалість 
 
19 
процесу (від кількох тижнів до місяців), високу вартість (від 20 до 300+ доларів за 
монету залежно від терміновості та вартості), а також неможливість дистанційної 
атрибуції без фізичної відправки монети [12]. 
Вітчизняні платформи. Український сегмент нумізматичної електронної 
комерції представлений переважно обмеженим функціоналом сайтів OLX та Prom 
[13], а також спеціалізованими форумами (Ukrainian Numismatic Society), які не 
забезпечують базових електронних комерційних функцій: захищених платежів, 
аукціонних механізмів, каталогізації та експертної підтримки. Повноцінна вітчизняна 
платформа для нумізматичної торгівлі з інтегрованим AI-інструментарієм наразі 
відсутня [14]. 
Отже, проведений аналіз свідчить, що жодна з існуючих платформ не 
забезпечує комплексного рішення, яке б поєднувало функціональність електронної 
комерції, автоматизовану AI-експертизу, аукціони в реальному часі та управління 
колекціями в єдиному застосунку. 
1.3 Аналіз технологій розробки веб-застосунків та вибір інструментальних 
засобів 
Сучасний стан технологій розробки веб-застосунків пропонує широкий спектр 
інструментальних засобів, вибір яких суттєво впливає на продуктивність, 
масштабованість та зручність супроводу готового продукту. Проаналізуємо основні 
технологічні рішення у контексті задач даного дослідження. 
Архітектурний підхід. У сучасній веб-розробці виділяють два основних 
архітектурних підходи до побудови користувацького інтерфейсу: клієнтське 
рендеринг (CSR, Client-Side Rendering) та серверне рендеринг (SSR, Server-Side 
Rendering) [15]. Традиційні SPA-фреймворки (React, Vue.js) реалізують виключно 
CSR, що забезпечує високу інтерактивність, проте погіршує показники SEO та 
початкове завантаження сторінки. Фреймворки серверного рендерингу (Next.js, 
Nuxt.js, SvelteKit) підтримують гібридний підхід, поєднуючи переваги SSR для 
початкового завантаження та CSR для подальшої інтерактивності [16]. 
 
20 
Фреймворк Next.js (версія 16.x) обрано як основний інструмент клієнтської 
частини з огляду на такі переваги: вбудована підтримка SSR та статичної генерації 
(SSG), що є критично важливим для eCommerce-платформ з високими вимогами до 
SEO [17]; автоматичне розбиття коду (code splitting) та оптимізація зображень; 
нативна підтримка API-маршрутів; а також найбільша екосистема компонентів та 
інструментів розробника серед React-орієнтованих фреймворків [18]. Крім того, 
Next.js підтримує Turbopack  новий пакувальник, що забезпечує значне прискорення 
процесу розробки порівняно з Webpack. 
Серверна частина реалізована на основі платформи Node.js (версія 20 LTS) з 
використанням веб-фреймворку Express.js (версія 5.x). Вибір Node.js зумовлений 
єдністю мови програмування (JavaScript/TypeScript) на клієнтській та серверній 
стороні, що спрощує розробку та супровід [19]. Express.js забезпечує мінімалістичний 
та гнучкий підхід до побудови REST API, не нав'язуючи жорсткої архітектури, що 
дозволяє адаптувати структуру проекту під конкретні потреби [20]. 
Для управління базою даних обрано Prisma ORM (версія 7.x) сучасний ORM 
нового покоління для TypeScript/Node.js, який забезпечує типобезпечний доступ до 
даних, декларативне описання схеми бази даних за допомогою моделі Prisma Schema 
Language, автоматичну генерацію міграцій та клієнтського коду [21]. Порівняно з 
традиційними ORM (Sequelize, TypeORM), Prisma забезпечує кращу продуктивність 
завдяки uso-специфічному движку запитів та інтуїтивніший API [22]. Як СУБД 
обрано PostgreSQL (версія 15)  надійну об'єктно-реляційну базу даних з відкритим 
вихідним кодом, яка підтримує складні типи даних (масиви, JSON, переліки), 
повнотекстовий пошук та розширений механізм індексування [23]. 
Для забезпечення взаємодії в реальному часі (аукціонні ставки, повідомлення) 
обрано бібліотеку Socket.IO (версія 4.x), яка реалізує протокол WebSocket з 
автоматичним резервним переходом до long-polling, кімнатами (rooms) для групової 
комунікації та вбудованою обробкою перепідключень [24]. 
Контейнеризація та розгортання реалізовано на основі Docker та Docker 
Compose, що забезпечує відтворюваність середовища, ізоляцію сервісів (база даних, 
 
21 
серверна частина, клієнтська частина) та простоту оркестрації багатокомпонентного 
застосунку [25]. 
1.4 Аналіз технологій штучного інтелекту для атрибуції та оцінки монет 
Задача автоматичної атрибуції та оцінки колекційних монет за їх зображеннями 
належить до області комп'ютерного зору (Computer Vision) та розпізнавання образів. 
У контексті нумізматики ця задача є особливо складною з кількох чинників: значна 
варіативність зовнішнього вигляду монет одного типу внаслідок карбувальних 
варіацій, ступеня зносу та умов зберігання [26]; наявність патинації, корозії та 
механічних пошкоджень, що ускладнюють розпізнавання деталей [27]; а також 
існування великої кількості підробок та копій, що вимагає додаткової верифікації 
[28]. 
Традиційні підходи до автоматичного розпізнавання монет базувалися на 
методах класичного комп'ютерного бачення: зіставленні шаблонів (template 
matching), вилученні ознак за алгоритмом SIFT (Scale-Invariant Feature Transform) та 
SURF (Speeded Up Robust Features) з подальшою класифікацією за допомогою 
алгоритмів машинного навчання (SVM, k-NN) [29]. Проте ці методи виявляються 
малоефективними для задачі атрибуції монет через значну варіативність візуального 
вигляду, складність виділення стабільних ознак та відсутність інваріантності до змін 
освітлення та ракурсу зйомки [30]. 
Поява глибинних нейронних мереж, зокрема згорткових нейромереж (CNN), 
стало переломним моментом у задачах класифікації зображень. Архітектури ResNet, 
VGG, EfficientNet та Inception демонструють точність понад 95% на бенчмарку 
ImageNet [27]. Проте застосування таких моделей для атрибуції монет вимагає 
значних зусиль з підготовки тренувального набору даних та донавчання (fine-tuning) 
на спеціалізованому домені. Наявні дослідження у цьому напрямі [28, 29] 
демонструють обіцяні результати, але вимагають великих позначених датасетів, які 
для нумізматики є обмеженими та недостатньо структурованими. 
Альтернативним підходом є використання мультимодальних великих мовних 
моделей (Multimodal LLM), які здатні одночасно аналізувати текстовий та візуальний 
 
22 
контент. До найвідоміших представників цієї категорії належать Google Gemini [30], 
OpenAI GPT-4V [31], та Anthropic Claude [32]. Модель Google Gemini сімейства 3.x 
забезпечує інтерфейс для передачі зображень у форматі Base64 разом із текстовим 
запитом, що дозволяє формулювати задачі атрибуції монет у вигляді структурованих 
промптів з вимогою виведення результату у форматі JSON. Переваги цього підходу: 
відсутність необхідності у донавчанні моделі на спеціалізованому датасеті, здатність 
розпізнавати широкий спектр монет різних епох та регіонів, а також можливість 
надання текстових підказок користувачем для уточнення атрибуції [33]. Недоліки: 
залежність від доступності зовнішнього API, певна затримка обробки (latency) та 
ймовірність галюцинацій, що потребує верифікації результатів користувачем [34]. 
У даному дослідженні обрано підхід на основі мультимодальної моделі Google 
Gemini через сполучення таких чинників: високу точність розпізнавання об'єктів на 
зображеннях, нативну підтримку structured output у форматі JSON, можливість 
передавати до кількох зображень в одному запиті (що є важливим для аналізу аверсу 
та реверсу монети одночасно), а також гнучкі архітектурні можливості для реалізації 
патерну Strategy, що дозволяє змінювати провайдера AI (наприклад, перейти на 
локальну модель через Ollama) без модифікації основної логіки застосунку [35]. 
1.5 Аналіз підходів до реалізації аукціонних механізмів у реальному часі 
Аукціонна торгівля є невіддільною складовою нумізматичного ринку. 
Проаналізуємо підходи до реалізації аукціонних механізмів у сучасних веб-
застосунках. 
Традиційний підхід до онлайн-аукціонів базується на моделі «періодичних 
запитів» (polling), при якій клієнт періодично надсилає HTTP-запити для перевірки 
оновлень ставок. Цей підхід реалізовано, зокрема, на платформах eBay [5] та Catawiki 
[36]. Його головний недолік - висока затримка оновлення інформації (від кількох 
секунд до хвилин) та надмірне навантаження на сервер при великій кількості 
одночасних користувачів [37]. 
Більш сучасним підходом є використання протоколу WebSocket, який 
забезпечує повнодуплексний зв'язок між клієнтом та сервером з мінімальною 
 
23 
затримкою. Бібліотека Socket.IO [24] розширює можливості WebSocket, додаючи 
автоматичне перепідключення, кімнати (rooms) для групової комунікації та 
резервний перехід до long-polling. Цей підхід широко застосовується у сучасних 
платформах реального часу [38]. 
Особливою проблемою онлайн-аукціонів є «снайпінг» (sniping) — практика 
розміщення ставки в останні секунди аукціону, що позбавляє інших учасників 
можливості відреагувати. Існуючі підходи до боротьби зі снайпінгом включають: 
механізм подовження (anti-sniping або popcorn bidding), при якому розміщення ставки 
в останні хвилини автоматично подовжує час аукціону на фіксований інтервал [39]; 
та сліп-ставки (proxy bidding), при яких учасник вказує максимальну суму, а система 
автоматично підвищує ставки до цього ліміту [40]. У розробленому застосунку 
реалізовано механізм антиснайпінгу на основі подовження часу аукціону на 3 
хвилини при розміщенні ставки в останні 3 хвилини, що забезпечує справедливість та 
прозорість аукціонного процесу. 
1.6 Аналіз підходів до забезпечення авторизації та управління доступом 
Забезпечення безпеки користувацьких даних та управління правами доступу є 
критично важливим для будь-якої eCommerce-платформи. Проаналізуємо основні 
підходи. 
Механізм авторизації на основі JWT (JSON Web Token) є де-факто стандартом 
у сучасних SPA- та SSR-застосунках [41]. JWT забезпечує stateless-автентифікацію, 
де сервер не зберігає стан сесії, а всі необхідні дані про користувача (ідентифікатор, 
роль, термін дії) кодуються в підписаному токені. Переваги: горизонтальна 
масштабованість, відсутність необхідності у серверному сховищі сесій, простота 
інтеграції з клієнтськими застосунками. Недоліки: неможливість миттєвого 
відкликання токена (частково вирішується через короткий термін дії та refresh-
токени), збільшення розміру запиту при великих payload-ах [42]. 
У контексті нумізматичної платформи доцільним є впровадження role-based 
access control (RBAC) з трьома рівнями доступу: USER (звичайний користувач - 
перегляд каталогу, покупка, участь в аукціонах, управління колекцією), SELLER 
 
24 
(продавець - створення та управління товарами, перегляд статистики продажів) та 
ADMIN (адміністратор - управління користувачами, замовленнями, заявками 
продавців). Така модель забезпечує достатню гнучкість управління доступом при 
збереженні простоти реалізації [43]. 
Зберігання паролів  [44] реалізовано за алгоритмом bcrypt з використанням salt 
rounds = 10, що забезпечує стійкість до атак перебору (brute-force) та (rainbow tables). 
1.7 Аналіз підходів до проектування користувацького інтерфейсу 
Ефективність eCommerce-платформи значною мірою визначається якістю 
користувацького інтерфейсу (UI/UX). У контексті нумізматичного ринку інтерфейс 
має задовольняти специфічні потреби: наочне подання зображень монет з високою 
роздільною здатністю, зручна навігація за категоріями, матеріалами та станом 
збереженості, а також інтуїтивно зрозумілі механізми участі в аукціонах. 
При проектуванні клієнтської частини застосунку обрано підхід, заснований на 
компонентній архітектурі React з використанням бібліотеки візуальних компонентів 
власної розробки та утилітарного CSS-фреймворку Tailwind CSS (версія 4.x). Tailwind 
CSS забезпечує утилітарний підхід до стилізації, що дозволяє швидко створювати 
компоненти без написання окремих CSS-файлів [45]. Візуальна стилістика застосунку 
реалізована у «темній» темі з акцентними кольорами золота (dark theme with gold 
accents), що респондує з естетикою нумізматичної тематика та забезпечує 
контрастність подання зображень монет на темному фоні [46]. 
Для реалізації інтерактивних графіків (історія цін) використано бібліотеку 
Recharts (версія 3.x), яка забезпечує декларативний підхід до побудови графіків на 
основі React-компонентів та підтримує адаптивне масштабування [47]. Для обробки 
дат та форматування з урахуванням української локалі - бібліотеку date-fns (версія 
4.x) [48].  
Для забезпечення іконографії обрано бібліотеку Lucide React, яка пропонує 
широкий набір SVG-іконок, оптимізованих для використання у React-застосунках 
[49]. 
 
 
25 
Висновки до розділу 1 
У цьому розділі проведено аналітичний огляд літературних та інших джерел, 
який дозволяє зробити такі висновки: 
1. Існуючі платформи для нумізматичної електронної комерції (eBay, VCoins, 
MA-Shops, PCGS) вирішують лише окремі аспекти задачі торговельну 
функціональність, сертифікацію або каталогізацію, жодне з рішень не забезпечує 
комплексного підходу, що поєднує електронну комерцію, AI-асистовану атрибуцію, 
аукціони в реальному часі та управління колекціями. 
2. Найбільш перспективним підходом до автоматичної атрибуції монет є 
використання мультимодальних великих мовних моделей (зокрема Google Gemini), 
які не вимагають донавчання на спеціалізованих датасетах і здатні вирішувати задачу 
розпізнавання та класифікації монет у режимі zero-shot з прийнятною точністю. 
3. Архітектурне рішення на основі Next.js (клієнтська частина), Express.js з 
Socket.IO (серверна частина), PostgreSQL з Prisma ORM (база даних) та Docker 
Compose (розгортання) є оптимальним з огляду на сполучення продуктивності, 
масштабованості, зручності розробки та відтворюваності середовища. 
4. Механізм аукціонної торгівлі в реальному часі на основі Socket.IO з 
протоколом антиснайпінгу є концептуально обґрунтованим і технічно реалізовним 
підходом, що забезпечує справедливість та прозорість аукціонного процесу. 
5. Обґрунтована доцільність проведення власного дослідження та розробки веб-
застосунку NumisMarket, який комплексно вирішує всі виявлені проблеми існуючих 
рішень. 
На підставі проведеного аналізу сформульовано мету та завдання дослідження: 
розробити комплексний веб-застосунок для нумізматичного інтернет-магазину з 
інтеграцією технологій штучного інтелекту для автоматичної ідентифікації та оцінки 
колекційних монет, що включає функціональність електронної комерції, аукціонів у 
реальному часі, управління персональними колекціями та AI-асистованої атрибуції 
монет. 
 
 
26 
2 СИСТЕМНИЙ АНАЛІЗ ТА ОБҐРУНТУВАННЯ ПРОБЛЕМИ 
У цьому розділі проведено системний аналіз предметної області нумізматичної 
електронної комерції, визначено межі системи та її оточення, здійснено 
декомпозицію основних бізнес-процесів, проаналізовано потоки даних та 
сформовано концептуальну модель майбутньої системи. Результати аналізу 
літературних джерел, викладені в розділі 1, слугують теоретичним підґрунтям для 
системного аналізу та проектування. 
2.1 Системний аналіз об'єкта дослідження та предметної області 
Застосування системного підходу до аналізу предметної області нумізматичної 
електронної комерції є необхідним з кількох причин. По-перше, розроблювана 
система є багатокомпонентною: вона включає клієнтську та серверну частини, базу 
даних, модуль штучного інтелекту, механізм аукціонної торгівлі в реальному часі та 
систему управління колекціями. По-друге, система функціонує в складному 
соціально-економічному середовищі, де взаємодіють різні категорії користувачів 
(покупці, продавці, адміністратори) з різними потребами та рівнями доступу. По-
третє, системний аналіз дозволяє виявити наявні протиріччя між існуючими 
підходами до організації нумізматичної торгівлі та сформулювати раціональний шлях 
їх розв'язання. 
Визначимо основні поняття системного аналізу в контексті даного 
дослідження. Системою є розроблюваний веб-застосунок NumisMarket - комплексна 
програмна платформа для нумізматичної електронної комерції з інтегрованим AI-
модулем атрибуції монет. Оточенням системи є зовнішні чинники, що впливають на 
її функціонування: користувачі різних категорій, зовнішні сервіси (Google Gemini 
API), платіжні системи, поштові служби та законодавче середовище. Елементами 
системи є її структурні складові: модуль автентифікації та авторизації, модуль 
управління товарами, модуль аукціонної торгівлі, модуль управління замовленнями, 
модуль AI-асистента, модуль обміну повідомленнями, модуль управління колекціями 
та модуль адміністрування. Функціями системи є забезпечення повного циклу 
 
27 
операцій нумізматичної торгівлі: від реєстрації користувача та створення товарної 
пропозиції до проведення аукціону, оформлення замовлення та управління 
персональною колекцією. 
Класифікація проблеми. Розглянута проблема є складною, що обґрунтовується 
наступними чинниками: наявність багатьох взаємопов'язаних підзадач (електронна 
комерція, аукціонна торгівля, AI-експертиза, управління колекціями), кожна з яких 
має власні вимоги та обмеження; необхідність забезпечення взаємодії в реальному 
часі між великим числом користувачів; наявність різнорідних джерел даних (текстові 
описи, зображення монет, аукціонні ставки, повідомлення); залежність від зовнішніх 
сервісів (Google Gemini API) та необхідність обробки непередбачуваних відповідей 
AI-моделі; а також вимога забезпечення різних рівнів доступу з відповідним 
контролем повноважень. 
2.1.1 Аналіз існуючої ситуації (модель «as is»). Визначимо межі системи та 
зовнішнє средовище. Внутрішнє середовище системи NumisMarket включає 
серверную частину (API-сервер на базі Node.js з Express.js), клієнтську частину (веб-
застосунок на базі Next.js), базу даних (PostgreSQL), модуль реального часу 
(Socket.IO) та AI-модуль інтеграції (Google Gemini API). Зовнішнє середовище 
включає: користувачів системи (покупці, продавці, адміністратори), зовнішній AI-
сервіс (Google Gemini), провайдерів хмарної інфраструктури, а також нормативно-
правове средовище (законодавство про електронну комерцію, захист персональних 
даних). 
Для декомпозиції системи обрано функціональний критерій, який передбачає 
виділення підсистем за основними бізнес-процесами. В результаті декомпозиції 
виділено вісім функціональних підсистем, наведених у таблиці 2.1. 
Таблиця 2.1 – Функціональні підсистеми та основні бізнес-процеси 
Підсистема Основні бізнес-процеси 
Управління Реєстрація; автентифікація (JWT); зміна профілю; подача 
користувачами заявки на роль продавця; розгляд заявки 
адміністратором; блокування/розблокування 
користувачів. 
 
28 
Управління товарами Створення товарної пропозиції; автоматичне створення 
аукціону; редагування/видалення товарів; перегляд 
каталогу з фільтрацією; додавання до списку бажаних. 
Аукціонна торгівля Проведення аукціонів; розміщення ставок у реальному 
часі; антиснайпінг (подовження на 3 хв); сповіщення про 
перебиття ставки; завершення аукціону. 
Управління Оформлення замовлення з кошика; вибір способу оплати 
замовленнями та адреси доставки; відстеження статусу; оновлення 
статусу адміністратором; історія замовлень. 
AI-асистент атрибуції Завантаження зображень монет; відправка до Google 
Gemini API; отримання результатів у форматі JSON; 
передача результатів у форму створення товару. 
Управління колекціями Створення записів колекції; завантаження до 5 
зображень; редагування/видалення записів; перегляд 
колекції. 
Обмін повідомленнями Обмін повідомленнями в реальному часі; список 
контактів з непрочитаними; автоматичне позначення 
прочитаними. 
Адміністрування Панель управління з KPI; управління користувачами; 
управління замовленнями; розгляд заявок продавців; 
управління товарами. 
 
Для вирішення сформульованих завдань обрано клієнт-серверну архітектуру із 
розділенням на фронтенд- та бекенд-частини, що взаємодіють через REST API та 
технологію вебсокетів (Socket.IO).  
Модель архітектури розроблюваної системи подано на рисунку 2.1.  
 
29 
 
Рисунок 2.1 – Модель архітектури розроблюваної системи 
2.1.2 Аналіз потоків даних. Вхідні та вихідні дані системи за кожною 
підсистемою наведені в таблиці 2.2. 
Таблиця 2.2 – Вхідні та вихідні дані підсистем 
Підсистема Вхідні дані Вихідні дані Характеристика 
Управління E-mail, пароль, JWT-токен;  Синхронна 
користувачами ім'я; JWT-токен профіль користувача 
Управління Дані товару; Сторінки каталогу; Синхронна 
товарами параметри деталі товару 
фільтрації 
Аукціонна ID аукціону; Поточна ціна; історія Асихронна 
торгівля сума ставки ставок; сповіщення (WebSocket) 
Управління Список товарів; Підтвердження Синхронна + 
замовленнями адреса замовлення; статус; асинхронна 
доставки; номер відстеження 
спосіб оплати 
 
30 
AI-асистент Зображення  JSON: ідентифікація, Синхронна  
(до 4 файлів); оцінка, опис, рідкість (до 60 с) 
текстова 
підказка 
Управління Дані запису Список записів; деталі Синхронна 
колекціями колекції; запису 
зображення  
(до 5) 
Обмін ID отримувача; Список контактів; Асинхронна 
повідомленнями текст історія повідомлень (WebSocket) 
повідомлення 
Адміністрування Запити Статистика KPI; Синхронна 
управління; списки 
фільтри користувачів/замовлень 
2.1.3 Визначення альтернатив та обґрунтування вибору. На основі 
проведеного аналізу існуючих рішень та вимог до системи визначено три основні 
альтернативи побудови системи. Порівняльна характеристика альтернатив наведена 
в таблиці 2.3. 
Таблиця 2.3 – Порівняльна характеристика архітектурних альтернатив 
Критерій Альтернатива Альтернатива Альтернатива  
1  2 3 
(Моноліт з (Мікросервіси) (Модульний моноліт) 
SSR) 
Масштабованість Низька Висока Середня (горизонт. сервер) 
Складність Низька Висока Середня 
розробки 
Складність Низька Висока Низька (Docker Compose) 
розгортання 
Інтерактивність Обмежена Висока Висока (Next.js + Socket.IO) 
UI 
Реальний час Складно Добре Добре (Socket.IO) 
(аукціони) реалізувати 
Незалежність Немає Повна Часткова (модульність) 
команд 
Витрати на Низькі Високі Помірні 
інфраструктуру 
Транзакційна Висока Складна Висока 
цілісність 
Відповідність Часткова Надмірна Повна 
масштабу 
проєкту 
 
31 
Обґрунтування вибору. Альтернатива 3 (модульна монолітна архітектура з 
клієнт-серверним розділенням) є найбільш доцільною для проекту NumisMarket з 
огляду на: масштаб проекту, що відповідає рівню монолітної архітектури; 
необхідність забезпечення реального часу для аукціонних ставок та повідомлень, що 
є природним для моноліту з Socket.IO; модульну структуру серверного коду, яка 
дозволяє в майбутньому виділити окремі модулі у мікросервіси; відтворюване 
розгортання через Docker Compose. 
2.2 Постановка та обґрунтування проблеми (концептуальна модель 
системи «to be») 
Мета та призначення системи. Розроблювана система NumisMarket призначена 
для комплексного забезпечення процесів нумізматичної електронної комерції і 
включає: функціональність повноцінного інтернет-магазину з підтримкою продажу 
товарів за фіксованою ціною та через аукціон; інтегрований AI – асистент для 
автоматичної атрибуції та оцінки монет за їх зображеннями; механізм аукціонної 
торгівлі в реальному часі з протоколом антиснайпінгу; систему управління 
персональними колекціями; модуль обміну повідомленнями між користувачами; 
адміністративну панель для управління платформою. 
Обґрунтування та очікувані ефекти. Розробка системи NumisMarket є 
обґрунтованою з огляду на: відсутність на вітчизняному ринку комплексної 
платформи, яка поєднувала б електронну комерцію, AI-експертизу та аукціонні 
механізми; зростання попиту на онлайн-інструменти для нумізматичного ринку; 
потенціал зниження бар'єра входу для початківців-колекціонерів завдяки AI-
асистенту; підвищення прозорості аукціонної торгівлі завдяки антиснайпінгу. 
Очікувані ефекти: зменшення часу атрибуції монет з кількох днів до кількох десятків 
секунд; забезпечення прозорого аукціонного процесу; створення єдиного 
інформаційного простору для нумізматичної спільноти. 
2.2.1 Концептуальна модель системи «to be». Концептуальна модель 
розроблюваної системи базується на результатах аналізу існуючої ситуації та обраних 
альтернатив. Визначено вхідні та вихідні дані для кожної основної функції системи 
 
32 
(таблиця 2.2), а також архітектурне рішення. Модель функціонування системи «to be» 
базується на клієнт-серверній архітектурі з трьома основними компонентами: 
клієнтський застосунок (Next.js), серверний API (Node.js + Express.js) та база даних 
(PostgreSQL). Зовнішній AI-сервіс (Google Gemini) забезпечує функцію атрибуції 
монет. Взаємодія між клієнтом та сервером здійснюється через REST API (CRUD-
операції) та Socket.IO (операції в реальному часі). 
2.2.2 Модель ролей та прав доступу. Модель доступу системи NumisMarket 
базується на role-based access control (RBAC) з трьома рівнями ролей.Матриця ролей 
та прав доступу наведена в таблиці 2.4. 
Таблиця 2.4 – Матриця ролей та прав доступу 
Функція / Дія USER SELLER ADMIN 
Реєстрація та авторизація + + + 
Перегляд каталогу + + + 
Пошук та фільтрація товарів + + + 
Участь в аукціонах + + + 
Додавання до списку бажаних + + + 
Оформлення замовлення + + + 
Використання AI-асистента + + + 
Управління колекцією + + + 
Обмін повідомленнями + + + 
Подача заявки на роль продавця + - - 
Створення товарних пропозицій - + + 
Редагування/видалення товарів - + (свої) + (всіх) 
Перегляд статистики продажів - + + 
Управління користувачами - - + 
Управління замовленнями - - + 
Розгляд заявок продавців - - + 
Перегляд адмін-панелі - - + 
 
 
33 
Таким чином, модель RBAC з трьома рівнями забезпечує достатню гнучкість 
управління доступом при збереженні простоти реалізації. Кожна роль має мінімально 
необхідний набір дозволів для виконання своїх функцій, що відповідає принципу 
найменших привілеїв. 
2.2.3 Вимоги до системи. На основі проведеного аналізу та концептуальної 
моделі сформульовано функціональні та нефункціональні вимоги до системи 
(таблиці 2.5 та 2.6). 
Таблиця 2.5 – Функціональні вимоги до системи 
№ Вимога Опис 
Ф1 Автентифікація та Реєстрація, вхід, JWT-токени, три рівні доступу 
авторизація (USER, SELLER, ADMIN) 
Ф2 Управління CRUD-операції з товарами, завантаження зображень, 
товарами фільтрація та пагінація каталогу 
Ф3 Аукціонна Розміщення ставок через Socket.IO, антиснайпінг, 
торгівля в сповіщення учасників 
реальному часі 
Ф4 AI-асистент Завантаження зображень, аналіз через Google Gemini 
атрибуції монет API, структурований результат JSON 
Ф5 Управління CRUD-операції з записами колекції, завантаження до 
колекціями 5 зображень, нотатки 
Ф6 Управління Оформлення замовлення, вибір оплати та доставки, 
замовленнями відстеження статусу, сповіщення 
Ф7 Обмін Реалтаймовий чат через Socket.IO, список контактів, 
повідомленнями позначки прочитання 
Ф8 Адміністрування Панель KPI, управління користувачами, 
замовленнями, заявками продавців 
 
 
 
 
 
34 
Таблиця 2.6 – Нефункціональні вимоги до системи 
№ Категорія Вимога 
НФ1 Продуктивність Час відгуку REST API ≤ 500 мс; AI-аналіз ≤ 60 с; 
Socket.IO повідомлення ≤ 1 с 
НФ2 Надійність Цілісність даних при одночасних ставках; автоматичне 
перепідключення Socket.IO 
НФ3 Безпека Хешування паролів (bcrypt, 10 раундів); JWT 
авторизація; перевірка прав доступу 
НФ4 Масштабованість Горизонтальне масштабування сервера; 
контейнеризація через Docker Compose 
НФ5 Зручність Адаптивний UI (responsive); темна тема з золотими 
акцентами; мінімум дій для типових операцій 
НФ6 Сумісність Підтримка сучасних браузерів (Chrome, Firefox, Safari, 
Edge); RESTful API 
Висновки до розділу 2 
У цьому розділі проведено системний аналіз предметної області та 
концептуальне моделювання системи «to be», що дозволяє зробити такі висновки: 
1. Визначено межі системи NumisMarket та її зовнішнє середовище, здійснено 
функціональну декомпозицію на вісім підсистем (таблиця 2.1) та проаналізовано 
потоки даних між підсистемами та зовнішнім середовищем (таблиця 2.2). 
2. Проаналізовано три альтернативи архітектурного побудови (таблиця 2.3) та 
обґрунтовано вибір модульної монолітної архітектури з клієнт-серверним 
розділенням як найбільш оптимальної для масштабу та вимог проекту. 
3. Сформовано концептуальну модель системи «to be», що включає опис 
вхідних та вихідних даних, матрицю ролей та прав доступу (таблиця 2.4) та перелік 
функціональних (таблиця 2.5, 8 вимог) та нефункціональних (таблиця 2.6, 6 вимог) 
вимог. 
 
35 
4. Обґрунтовано доцільність розробки системи NumisMarket, яка комплексно 
розв'язує виявлені проблеми: відсутність AI-асистованої атрибуції, відсутність 
аукціонних механізмів у реальному часі з антиснайпінгом та відсутність інструментів 
управління колекціями. 
5. Результати цього розділу складають методичне підґрунтя для проектування 
та реалізації системи, які будуть викладені в наступних розділах роботи. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36 
3 МЕТОДИ ТА ЗАСОБИ ВИРІШЕННЯ ПРОБЛЕМИ 
У цьому розділі обґрунтовано вибір методів, технологій та інструментальних 
засобів, необхідних для реалізації розроблюваної системи NumisMarket. Проведено 
порівняльний аналіз альтернативних підходів до вирішення ключових задач, 
обґрунтовано вибір технологічного стеку, описано та доведено коректність 
алгоритмів, що реалізують основні бізнес-процеси системи. Результати розділу 2 
щодо архітектурних альтернатив та вимог до системи слугують вихідними даними 
для вибору конкретних методів та засобів. 
3.1 Вибір та обґрунтування методів вирішення проблеми 
Специфіка розроблюваної системи NumisMarket визначає ряд особливостей, які 
впливають на вибір методів вирішення проблеми: 
По-перше, система функціонує в режимі реального часу (аукціонні ставки, 
сповіщення, повідомлення), що вимагає використання протоколів двостороннього 
зв'язку.  
По-друге, інтеграція зовнішнього AI-сервісу для атрибуції монет передбачає 
асинхронну обробку запитів із значною затримкою.  
По-третє, система працює з різнорідними даними: структурованими (товари, 
замовлення, ставки), неструктурованими (зображення, текстові описи) та файловими 
(фотографії монет).  
По-четверте, вимога забезпечення різних рівнів доступу (USER, SELLER, 
ADMIN) зобов'язує застосувати методи контролю доступу на основі ролей. 
На основі сформульованих у розділі 2 функціональних та нефункціональних 
вимог визначено наступні ключові задачі, для яких необхідно обрати методи 
вирішення: автентифікація та авторизація користувачів; управління даними з 
розширеним набором зв'язків (товари, аукціони, ставки, замовлення, колекції); 
взаємодія в реальному часі; інтеграція зовнішнього AI-сервісу; зберігання та обробка 
зображень; побудова адаптивного користувацького інтерфейсу. Розглянемо методи 
вирішення кожної задачі з порівняльним аналізом альтернатив. 
 
37 
Автентифікація та авторизація. Для реалізації автентифікації та авторизації 
розглянуто три підходи: сесійна автентифікація на основі cookie-сесій, автентифікація 
на основі JWT-токенів та OAuth 2.0 із зовнішнім провайдером. Сесійна 
автентифікація забезпечує надійне управління станом, проте вимагає зберігання 
стану на сервері, що ускладнює горизонтальне масштабування. OAuth 2.0 делегує 
автентифікацію зовнішньому провайдеру, що є зручним для користувачів, але 
створює залежність від сторонніх сервісів та ускладнює управління ролями. 
Автентифікація на основі JWT-токенів є stateless-підходом, який забезпечує 
горизонтальну масштабованість, просту інтеграцію з клієнтськими застосунками та 
можливість передачі ролі користувача безпосередньо в payloads токена. Порівняльна 
характеристика підходів наведена в таблиці 3.1. 
Таблиця 3.1 – Порівняльна характеристика методів автентифікації 
Критерій Сесійна (cookie) JWT-токени OAuth 2.0 
Масштабованість Обмежена (стан Висока Залежить від 
на сервері) (stateless) провайдера 
Управління ролями Вбудоване Через payloads Зовнішнє 
токена 
Залежність від Немає Немає Висока 
сторонніх сервісів 
Складність реалізації Низька Середня Висока 
Підтримка REST API Потрібна Повна Повна 
прив'язка до сесії 
Можливість Повна Обмежена Залежить від 
відкликання (видалення сесії)  (через blacklist) провайдера 
Обґрунтування вибору: JWT-токени обрано як метод автентифікації, оскільки 
він забезпечує оптимальне співвідношення масштабованості, простоти інтеграції з 
REST API та можливості передачі ролі користувача. Для зберігання паролів 
застосовано алгоритм bcrypt із 10 раундами солі, що забезпечує стійкість до атак 
перебору та rainbow-таблиць [1]. 
 
38 
Управління даними. Для організації шару доступу до даних розглянуто три 
підходи: «сирий» SQL через драйвер pg (PostgreSQL), ORM Sequelize та ORM Prisma. 
Безпосереднє використання SQL-запитів забезпечує максимальну гнучкість та 
продуктивність, проте призводить до дублювання логіки, відсутності 
типобезпечності та підвищеної схильності до помилок. Sequelize є зрілим ORM з 
широкою спільнотою, проте має застарілий API, обмежену підтримку TypeScript та 
складності з міграціями. Prisma ORM нового покоління забезпечує декларативний 
опис схеми, автоматичну генерацію типобезпечного клієнта TypeScript, міграції та 
високу продуктивність завдяки Rust-рушійному двигуну запитів [2]. Порівняння 
наведене в таблиці 3.2. 
Таблиця 3.2 – Порівняльна характеристика засобів доступу до даних 
Критерій SQL (pg driver) Sequelize Prisma ORM 
Типобезпечність Немає Часткова Повна 
(автогенерація) 
Декларативна схема Немає Часткова Повна  
(Prisma Schema) 
Міграції Ручні Вбудовані Вбудовані 
 (prisma migrate) 
Продуктивність Максимальна Середня Висока  
(Rust-рушій) 
Підтримка TypeScript Ручна Обмежена Повна 
Складність запитів Висока Середня Низька 
Обґрунтування вибору: Prisma ORM обрано завдяки повній типобезпечності 
TypeScript, декларативному опису схеми бази даних, вбудованим міграціям та 
високій продуктивності. Додатковою перевагою є підтримка складних типів даних 
PostgreSQL (масиви, переліки), які використовуються в системі (масиви зображень, 
переліки Condition та AuctionStatus). 
Взаємодія в реальному часі. Для забезпечення взаємодії в реальному часі 
(аукціонні ставки, сповіщення, повідомлення) розглянуто три технології: Server-Sent 
Events (SSE), Raw WebSocket та Socket.IO. SSE забезпечує односторонню передачу 
 
39 
даних від сервера до клієнта, що є недостатнім для двосторонньої взаємодії (аукціонні 
ставки). Raw WebSocket забезпечує повноцінний двосторонній зв'язок, проте вимагає 
ручної реалізації механізмів перепідключення, кімнат та серіалізації.  
Socket.IO розширює WebSocket, додаючи автоматичне перепідключення, 
кімнати (rooms) для групової комунікації, резервний перехід до long-polling та 
вбудовану обробку подій [3]. 
Таблиця 3.3 – Порівняльна характеристика технологій реального часу 
Критерій SSE Raw WebSocket Socket.IO 
Напрямок зв'язку Односторонній Двосторонній Двосторонній 
(сервер-клієнт) 
Автоперепідключення Вбудоване Ручне Вбудоване 
Кімнати (rooms) Немає Ручна реалізація Вбудовані 
Резервний транспорт Немає Немає Long-polling 
Серіалізація подій Немає Ручна Вбудована 
Складність реалізації Низька Висока Середня 
Обґрунтування вибору: Socket.IO обрано завдяки вбудованим механізмам 
автоперепідключення, кімнат (які є критично важливими для аукціонних подій - 
кожен аукціон є окрема кімната) та резервному транспорту long-polling, що 
забезпечує працездатність у середовищах, де WebSocket недоступний. 
3.2 Вибір та обґрунтування засобів (СУБД, технології, мови 
програмування) 
Характеристика бази даних системи. База даних системи NumisMarket містить 
10 основних сутностей (моделей): User, Category, Product, Auction, Bid, Order, 
OrderItem, Favorite, Notification, Message, SellerApplication та CollectionItem. Загальна 
кількість атрибутів становить понад 60 полів, з яких 4 є переліками (enum): Role, 
ApplicationStatus, Condition, AuctionStatus. База даних містить складні зв'язки: один-
до-багатьох (User - Product, User - Bid, Product - PriceHistory), багато-до-багатьох через 
проміжну таблицю (Favorite), один-до-одного (Product - Auction) та самозgetReference 
 
40 
(Message з полями senderId та receiverId). Обсяг даних прогнозується на рівні десятків 
тисяч записів товарів та сотень тисяч записів ставок і повідомлень, що є типовим для 
нішових eCommerce-платформ. 
Вибір системи управління базами даних розглянуто серед трьох основних 
варіантів: MySQL, MongoDB та PostgreSQL. MySQL є поширеною реляційною СУБД 
з простою настройкою, проте має обмежену підтримку складних типів даних та JSON-
полів. MongoDB є документорієнтованою NoSQL СУБД, що забезпечує гнучкість 
схеми, проте не забезпечує транзакційної цілісності на рівні реляційних СУБД та 
ускладнює реалізацію складних зв'язків між сутностями.  
PostgreSQL є об'єктно-реляційною СУБД з відкритим вихідним кодом, яка 
підтримує складні типи даних (масиви, JSON, переліки), повнотекстовий пошук, 
зовнішні ключі з каскадним видаленням та розширений механізм індексування [4]. 
Порівняння наведене в табл. 3.4. 
Таблиця 3.4 – Порівняльна характеристика СУБД 
Критерій MySQL MongoDB PostgreSQL 
Тип СУБД Реляційна Документорієнтована Об'єктно-
(NoSQL) реляційна 
Підтримка масивів Обмежена Вбудована Повна (тип Array) 
(JSON) 
Переліки (enum) Обмежені Немає Повна 
Каскадне видалення Обмежене Немає Повне 
Транзакційна Висока Обмежена Висока (ACID) 
цілісність 
Повнотекстовий Обмежений Вбудований Розширений 
пошук (tsvector) 
Сумісність з Prisma Повна Повна Повна 
Продуктивність при Середня Немає Висока 
складних JOIN 
Обґрунтування вибору: PostgreSQL обрано завдяки підтримці складних типів 
даних (масиви для зберігання списку зображень товару, переліки для стану монет та 
 
41 
статусу аукціону), повній підтримці транзакцій ACID, каскадному видаленню для 
забезпечення цілісності даних та високій продуктивності при складних запитах з 
JOIN. Версія 15 забезпечує стабільність та широку функціональність. 
Вибір мови програмування та фреймворків. Для серверної частини обрано 
TypeScript як основну мову програмування. TypeScript розширює JavaScript 
статичною типізацією, що суттєво зменшує кількість помилок під час розробки, 
покращує читабельність коду та забезпечує автодоповнення в IDE [5]. Вибір 
TypeScript зумовлений єдністю мови програмування на клієнтській та серверній 
сторонах, що спрощує розробку та супровід. Версія TypeScript 6.x підтримує всі 
сучасні мовні конструкції. 
Для серверного фреймворку обрано Express.js версії 5.x - мінімалістичний та 
гнучкий веб-фреймворк для Node.js, який забезпечує: механізм маршрутизації 
(routing) з підтримкою параметрів та middleware; middleware-архітектуру для 
розширення функціональності (автентифікація, обробка помилок, логування); велику 
екосистему middleware-пакетів; просту інтеграцію з Socket.IO та Prisma [6]. Версія 
Node.js 20 LTS обрано як стабільну та продуктивну платформу для серверної частини. 
Для клієнтської частини обрано Next.js версії 16.x - React-фреймворк, який 
забезпечує: серверний рендеринг (SSR) та статичну генерацію (SSG) для SEO-
оптимізації; автоматичне розбиття коду (code splitting) та оптимізацію зображень; 
файлову систему маршрутизації (App Router) [7]. React версії 19 забезпечує ефективне 
оновлення DOM через віртуальний DOM, хуки (hooks) для управління станом 
компонентів та компонентну архітектуру, що сприяє повторному використанню коду. 
Tailwind CSS версії 4.x обрано як утилітарний CSS-фреймворк для швидкого 
створення адаптивних інтерфейсів [8]. 
Для управління станом HTTP-запитів на клієнтській стороні обрано Axios - 
Promise-based HTTP-клієнт для браузера та Node.js, який забезпечує інтерцептори для 
автоматичного додавання JWT-токенів до заголовків авторизації, обробку помилок та 
скасування запитів [9]. Для роботи з  датами обрано бібліотеку date-fns версії 4.x, яка 
забезпечує tree-shaking, модульну архітектуру та підтримку української локалі [10]. 
Для побудови графіків обрано Recharts версії 3.x - декларативна React-бібліотека для 
 
42 
побудови діаграм [11]. Контейнеризація та розгортання реалізовано на основі Docker 
та Docker Compose. Docker забезпечує ізоляцію сервісів (база даних, серверна 
частина, клієнтська частина), відтворюваність середовища та простоту розгортання. 
Docker Compose дозволяє оркеструвати три сервіси у конфігурації одного файлу з 
автоматичним застосуванням міграцій бази даних (npx prisma db push) перед стартом 
сервера [12]. Повний технологічний стек системи NumisMarket наведено в табл. 3.5. 
Таблиця 3.5 – Технологічний стек системи NumisMarket 
Компонент Технологія Версія Призначення 
Серверна Node.js 20 LTS Середовище виконання 
платформа 
Серверний Express.js 5.x REST API, middleware 
фреймворк 
Мова (сервер) TypeScript 6.x Статична типізація 
ORM Prisma 7.x Доступ до даних, міграції 
СУБД PostgreSQL 15 Зберігання даних 
Автентифікація jsonwebtoken + 9.x / 6.x JWT-токени, хешування 
bcrypt 
Реальний час Socket.IO 4.x Аукціони, повідомлення 
AI-інтеграція Google 0.24.x Аналіз зображень монет 
Generative AI 
Завантаження Multer 2.x Обробка multipart/form-data 
файлів 
Клієнтський Next.js 16.x SSR, маршрутизація 
фреймворк 
UI-бібліотека React 19.x Компонентна архітектура 
CSS-фреймворк Tailwind CSS 4.x Утилітарна стилізація 
HTTP-клієнт Axios 1.x REST API запити 
Графіки Recharts 3.x Діаграми статистики 
Дати date-fns 4.x Форматування дат 
Іконки Lucide React 1.x SVG-іконки 
Контейнеризація Docker + Docker - Розгортання 
Compose 
 
43 
Вибір зовнішнього AI-сервісу. Для реалізації функції атрибуції та оцінки монет 
за зображеннями розглянуто три основні варіанти: OpenAI GPT-4V, Google Gemini та 
локальну модель через Ollama. OpenAI GPT - 4V забезпечує високу точність 
розпізнавання, проте має високу вартість API-запитів та обмеження на кількість 
запитів [13]. Google Gemini забезпечує мультимодальний аналіз з можливістю 
передачі до кількох зображень в одному запиті, structured output у форматі JSON та 
гнучке ціноутворення [14]. Локальна модель через Ollama забезпечує 
конфіденційність (дані не передаються зовнішнім сервісам), проте вимагає значних 
обчислювальних ресурсів та надає меншу точність [15]. Порівняння наведене в 
таблиці 3.6 
Таблиця 3.6 – Порівняльна характеристика AI-сервісів 
Критерій OpenAI  Google Gemini Ollama (локальна) 
GPT-4V 
Точність розпізнавання Висока Висока Середня 
Вартість запитів Висока Помірна Безкоштовно 
Кількість зображень за До 4 До 16 Залежить від 
запит моделі 
Structured output Так (JSON Так (нативна) Немає 
(JSON) mode) 
Затримка обробки 5-30 с 5-30 с 10-120 с 
Конфіденційність Ні (передаються Ні (передаються Так (локальна) 
даних API) API) 
Вимоги до ресурсів Немає Немає GPU 8+ ГБ 
Можливість зміни Через API key Через API key Локально 
провайдера 
Обґрунтування вибору: Google Gemini обрано як основний AI-провайдер 
завдяки нативній підтримці structured output у форматі JSON, можливості передачі 
кількох зображень (реалізовано до 4 зображень монет - аверс, реверс та додаткові 
ракурси) та помірній вартості API-запитів. Крім того, архітектура системи 
реалізована за патерном Strategy: визначено інтерфейс AIProvider з методом 
 
44 
analyzeCoin(images, hint), який реалізують GeminiProvider та OllamaProvider. Це 
дозволяє змінювати AI-провайдера через змінну середовища AI_PROVIDER без 
модифікації основної логіки застосунку, забезпечуючи гнучкість та масштабованість 
системи. 
3.3 Опис та обґрунтування алгоритмів 
У цьому підрозділі описано та обґрунтовано алгоритми, що реалізують основні 
бізнес-процеси системи NumisMarket. Для кожного алгоритму наведено формальний 
опис, обґрунтування вибору та доказ коректності. 
3.3.1 Алгоритм розміщення ставки на аукціоні з антиснайпінгом. 
Постановка задачі. Необхідно реалізувати алгоритм розміщення ставки на аукціоні, 
який забезпечує: збереження цілісності даних при одночасних ставках різних 
користувачів; перевірку коректності ставки (сума має перевищувати поточну ціну на 
мінімальний крок); автоматичне подовження часу аукціону при розміщенні ставки в 
останні хвилини (антиснайпінг); сповіщення всіх учасників аукціону про зміну ціни 
в реальному часі. 
Алгоритм розміщення ставки з антиснайпінгом: 
1. Отримати запит на розміщення ставки: {auctionId, userId, amount}. 
2. Перевірити автентифікацію користувача (присутність та валідність JWT-
токена). Якщо не автентифікований - повернути помилку 401. 
3. Знайти аукціон за auctionId у базі даних. Якщо не знайдено — повернути 
помилку 404. 
4. Перевірити статус аукціону: якщо статус = ACTIVE - повернути помилку 400 
("Аукціон не активний"). 
5. Перевірити коректність ставки: amount ≥ currentPrice + minStep. Якщо умова 
не виконана - повернути помилку 400 ("Ставка занадто низька"). 
6. Створити запис ставки (Bid) у базі даних з полями: id, amount, userId, 
auctionId, createdAt. 
7. Оновити поточну ціну аукціону: currentPrice = amount. 
 
45 
8. Перевірити умову антиснайпінгу: якщо (endTime  -  поточнийЧас) < 3 
хвилини, то подовжити endTime на 3 хвилини. 
9. Надіслати сповіщення попередньому найвищому ставокцю про перебиття 
його ставки через Socket.IO. 
10. Надіслати подію оновлення ціни (bid-placed) всім учасникам аукціону 
(Socket.IO room) з даними: {auctionId, currentPrice, bid, timeRemaining}. 
11. Повернути успішну відповідь з даними ставки. 
Доведения коректності. Алгоритм забезпечує цілісність даних завдяки 
атомарності операцій бази даних (Prisma забезпечує транзакційність операцій 
створення ставки та оновлення ціни). Перевірка статусу аукціону на кроці 4 гарантує, 
що ставки приймаються лише для активних аукціонів. Перевірка мінімального кроку 
на кроці 5 гарантує, що кожна наступна ставка перевищує попередню на встановлену 
величину, запобігаючи мікроставкам. Механізм антиснайпінгу на кроці 8 гарантує, 
що жоден учасник не може виграти аукціон розміщенням ставки в останню мить: при 
розміщенні ставки в останні 3 хвилини час аукціону автоматично подовжується, 
забезпечуючи можливість іншим учасникам відреагувати. Сповіщення на кроках 9 та 
10 гарантують інформованість всіх учасників аукціону про зміну ціни в реальному 
часі. 
Аналіз існуючих підходів. Механізм антиснайпінгу реалізовано за моделлю 
«попкорн-бідинг» (popcorn bidding), яка використовується на провідних аукціонних 
платформах (eBay, Catawiki) [16]. Альтернативний підхід - сліп-ставки (proxy bidding) 
- застосовується на платформах де користувач вказує максимальну суму, а система 
автоматично підвищує ставки до ліміту. Обрано модель попкорн-бідинг, оскільки 
вона є більш прозорою для учасників та.Base.Matchers найкраще відповідає специфіці 
нумізматичних аукціонів, де учасники зазвичай керують ставками самостійно. 
3.3.2 Алгоритм аналізу зображень монет AI-асистентом. Постановка задачі. 
Необхідно реалізувати алгоритм аналізу зображень монет за допомогою зовнішнього 
AI-сервісу (Google Gemini), який забезпечує: прийом зображень від користувача (до 
4 файлів); відправку зображень разом зі структурованим промптом до AI-сервісу; 
 
46 
отримання результату аналізу у форматі JSON; валідацію та обробку помилок; 
можливість зміни AI-провайдера без модифікації основної логіки. 
Алгоритм аналізу зображень монет: 
1. Отримати запит від користувача: зображення (до 4 файлів у форматах JPG, 
PNG, WebP, обсяг до 10 МБ кожний) та необов'язкову текстову підказку. 
2. Валідувати вхідні дані: перевірити формат файлів, їх кількість та обсяг. При 
невідповідності - повернути помилку 400. 
3. Визначити AI-провайдера через змінну середовища AI_PROVIDER: gemini - 
GeminiProvider, ollama - OllamaProvider. 
4. Перетворити зображення у формат Base64 та сформувати запит до AI-сервісу, 
що містить: (а) структурований промпт українською мовою з вимогою виведення 
результату у форматі JSON (поля: identification, grading, description, rarity, confidence, 
notes); (б) зображення монет як inlineData з типом MIME. 
5. Надіслати запит до AI-сервісу з тайм-аутом 60 секунд. 
6. Отримати текстову відповідь та витягти JSON за допомогою регулярного 
виразу (пошук першого входження шаблону {…}). Якщо JSON не знайдено - 
повернути помилку 500. 
7. Валідувати структуру JSON: перевірити наявність обов'язкових полів 
(identification, grading, description, rarity, confidence). При невідповідності - повернути 
помилку 500. 
8. Повернути успішну відповідь з даними аналізу у форматі {success: true, data: 
result}. 
Доведения коректності. Алгоритм забезпечує надійність завдяки: валідації 
вхідних даних на кроці 2 (запобігання обробці невалідних файлів); механізму Strategy 
на кроці 3, що дозволяє змінювати AI-провайдера через конфігурацію без модифікації 
коду; тайм-ауту на кроці 5 (запобігання зависання при недоступності AI-сервісу); 
витягу JSON на кроці 6, що враховує можливість AI-моделі обгортати відповідь у 
markdown-блоки; валідації структури на кроці 7 (гарантія того, що клієнт отримає 
коректні дані). 
 
47 
Структурований промпт для Google Gemini сформульовано українською мовою 
і містить: роль («Всесвітньо відомий нумізмат»); опис завдання (ідентифікація монети 
за зображеннями); перелік атрибутів для визначення (назва, країна, рік, номінал, 
матеріал, номер у каталозі, стан збереженості за шкалою POOR/MINT, опис аверсу та 
реверсу, рідкість, рівень впевненості); вимогу виведення результату виключно у 
форматі JSON. Використання структурованого промпту забезпечує одержання 
результату у передбачуваному форматі, придатному для автоматичної обробки та 
відображення в інтерфейсі користувача. 
Аналіз існуючих підходів. Підхід до аналізу зображень на основі 
мультимодальних LLM є відносно новим та активно розвивається [17]. Традиційний 
підхід на основі донавчання згорткових нейромереж (CNN) на спеціалізованому 
датасеті [18] вимагає значних зусиль з підготовки навчальних даних та забезпечує 
розпізнавання лише попередньо навчених класів монет. Підхід на основі LLM з zero-
shot розпізнаванням [19] не вимагає донавчання, здатний розпізнавати широкий 
спектр монет та надає структурований опис результату, проте має меншу точність на 
специфічних класах порівняно з донавченими CNN. Для системи NumisMarket обрано 
підхід на основі LLM з фіксованим промптом, оскільки він забезпечує 
універсальність розпізнавання без необхідності збирання та розмітки датасету, а 
результат аналізу завжди можна перевірити та виправити користувачу. 
3.3.3 Алгоритм обробки замовлення та управління станом. Постановка 
задачі. Необхідно реалізувати алгоритм створення замовлення, який забезпечує: 
атомарність операції (сума замовлення обчислюється на основі актуальних цін 
товарів); перехід товару у стан «продано» після оформлення замовлення; сповіщення 
користувача про зміну статусу замовлення в реальному часі; можливість 
адміністратора оновлювати статус замовлення з вказанням номера відстеження. 
Алгоритм створення замовлення: 
1. Отримати запит від користувача: {items: [{productId, quantity}], 
shippingAddress, paymentMethod}. 
2. Перевірити автентифікацію користувача (JWT). Якщо не автентифікований - 
повернути помилку 401. 
 
48 
3. Отримати актуальні ціни товарів з бази даних за їх ідентифікаторами 
(запобігання маніпуляції з цінами на клієнтській стороні). 
4. Перевірити доступність товарів: виключити товари, які вже мають пов'язаний 
OrderItem (тобто вже продані). Якщо всі товари недоступні - повернути помилку 400. 
5. Обчислити загальну суму замовлення як суму актуальних цін доступних 
товарів. 
6. Встановити початковий статус замовлення: PENDING - для оплати при 
отриманні (COD), PAID - для оплати картою. 
7. Створити запис Order з полями: userId, totalAmount, status, shippingAddress. 
Створити записи OrderItem для кожного товару з фіксацією ціни на момент покупки. 
8. Повернути підтвердження замовлення з ідентифікатором та деталями. 
Доведения коректності. Крок 3 гарантує, що ціни товарів беруться з бази 
даних, а не з клієнтського запиту, запобігаючи маніпуляціям. Крок 4 перевіряє, що 
товар ще не продано, забезпечуючи консистентність даних. Крок 6 визначає 
початковий статус замовлення відповідно до способу оплати, що відповідає бізнес-
логіці системи. Зв'язок OrderItem з Product через унікальний індекс гарантує, що 
кожен товар може бути продано лише один раз. 
Алгоритм оновлення статусу замовлення адміністратором: 
1. Отримати запит від адміністратора: {orderId, status, trackingNumber}. 
2. Перевірити автентифікацію та роль ADMIN. Якщо не адміністратор - 
повернути помилку 403. 
3. Знайти замовлення за orderId. Якщо не знайдено - повернути помилку 404. 
4. Оновити статус замовлення у базі даних. 
5. Створити сповіщення (Notification) для користувача з заголовком та текстом, 
що вказують на зміну статусу. 
6. Надіслати сповіщення через Socket.IO користувачу (індивідуальний канал). 
7. Повернути оновлене замовлення. 
Крок 5 гарантує, що користувач завжди отримує сповіщення про зміну статусу 
замовлення, причому сповіщення зберігається в базі даних (стаціонарний запис) та 
надсилається в реальному часі через Socket.IO (індивідуальний канал користувача). 
 
49 
Це забезпечує інформованість користувача навіть при тимчасовій відсутності 
з'єднання. 
Висновки до розділу 3 
У цьому розділі проведено вибір та обґрунтування методів і засобів вирішення 
проблеми, що дозволяє зробити такі висновки: 
1. На основі порівняльного аналізу обрано методи вирішення ключових задач: 
автентифікація на основі JWT-токенів (таблиця 3.1), управління даними через Prisma 
ORM (таблиця 3.2), взаємодія в реальному часі через Socket.IO (таблиця 3.3). Вибір 
кожного методу обґрунтовано перевагами над альтернативами у контексті вимог 
системи. 
2. Обґрунтовано вибір технологічного стеку: PostgreSQL як СУБД (таблиця 
3.4), TypeScript + Express.js + Next.js + React як основні технології розробки, Socket.IO 
для реального часу, Google Gemini як основний AI-провайдер (таблиця 3.6) з 
архітектурною можливістю заміни через патерн Strategy. Повний технологічний стек 
наведено в таблиці 3.5. 
3. Описано та обґрунтовано три ключові алгоритми: алгоритм розміщення 
ставки на аукціоні з антиснайпінгом (забезпечує цілісність даних при одночасних 
ставках та справедливість аукціонного процесу); алгоритм аналізу зображень монет 
AI-асистентом (забезпечує універсальність розпізнавання та структурований 
результат); алгоритм обробки замовлення та управління станом (забезпечує 
атомарність та інформованість користувача). Для кожного алгоритму наведено 
формальний опис та доказ коректності. 
4. Обраний інструментарій та описані алгоритми складають повну методичну 
основу для етапу проектування та практичної реалізації системи, що буде викладено 
в розділі 4. 
5. Результати цього розділу підтверджують готовність до етапу проектування 
та практичної реалізації на основі обраної методології та інструментальних засобів 
 
 
 
50 
4 АНАЛІЗ ТА ПРОЄКТУВАННЯ СИСТЕМИ 
У цьому розділі проведено об'єктно-орієнтований аналіз вимог до системи 
NumisMarket та розроблено проєктні рішення на основі методології UML. Визначено 
варіанти використання (Use Cases), потоки даних, межі системи та коло користувачів. 
Розроблено платформо-незалежну (PIM) та платформо-специфічну (PSM) моделі, 
описано логічну та фізичну структуру системи, а також змодельовано динамічну 
поведінку через діаграми взаємодії. Результати розділів 2 та 3 слугують вихідними 
даними для проєктування. 
4.1 Об'єктно-орієнтований аналіз вимог 
4.1.1 Словник предметної області. Для забезпечення єдності термінології та 
однозначного тлумачення понять предметної області складено словник основних 
термінів (таблиця 4.1). 
Таблиця 4.1 – Словник предметної області 
Термін Визначення 
Користувач (User) Зареєстрована особа, яка взаємодіє з системою. Має одну з 
трьох ролей: USER, SELLER, ADMIN 
Продавець (Seller) Користувач з роллю SELLER, який має право створювати та 
управляти товарами, а також переглядати статистику 
продажів 
Адміністратор Користувач з роллю ADMIN, який управляє платформою: 
(Admin) користувачами, замовленнями, заявками продавців 
Товар (Product) Нумізматичний об'єкт (монета), розміщений на продаж або 
аукціон. Має назву, опис, країну, рік, матеріал, стан, рідкість, 
ціну, зображення 
Аукціон (Auction) Форма продажу товару через конкурентне розміщення ставок 
у реальному часі з визначеними часом завершення та 
мінімальним кроком ставки 
Ставка (Bid) Пропозиція ціни від користувача на аукціоні. Містить суму, 
ідентифікатор користувача та мітку часу 
Антиснайпінг Механізм автоматичного подовження часу аукціону на 3 
хвилини при розміщенні ставки в останні 3 хвилини 
Замовлення (Order) Фіксація наміру придбати товари з кошика. Містить список 
товарів, загальну суму, адресу доставки та статус 
 
51 
Колекційний запис Запис у персональній колекції користувача. Містить назву, 
(CollectionItem) опис, країну, рік, матеріал, стан, рідкість, нотатки та 
зображення 
Сповіщення Системне повідомлення користувачу про подію (перебиття 
(Notification) ставки, зміна статусу замовлення тощо) 
AI-асистент Модуль інтеграції з Google Gemini API для автоматичної 
атрибуції та оцінки монет за їх зображеннями 
 Wishlist (Список Перелік товарів, які користувач позначив як бажані для 
бажаного) придбання в майбутньому 
Перед безпосереднім описом процесів чи об'єктно-орієнтованого аналізу текст 
для вставки перед схемою (з посиланням): на етапі об'єктно-орієнтованого аналізу 
було визначено основні ролі користувачів (клієнт, продавець, адміністратор) та їхні 
сценарії взаємодії із платформою. Загальну діаграму варіантів використання наявних 
функцій подано на (рисунку 4.1). 
 
 Рисунок 4.1 – Загальна діаграма варіантів використання наявних функцій 
 
52 
4.1.2 Актори та варіанти використання. Визначено межі системи та коло її 
користувачів. Система NumisMarket має трьох основних акторів: звичайний 
користувач (USER), продавець (SELLER) та адміністратор (ADMIN). Кожен актор 
взаємодіє з системою через відповідні варіанти використання (Use Cases). Діаграма 
варіантів використання (Use Case Diagram) представлена у вигляді таблиці 4.2. 
Таблиця 4.2 – Варіанти використання за акторами 
Актор Use Case Опис Передумова 
Гість UC-01: Реєстрація Створення облікового Немає 
запису 
Гість UC-02: Вхід у систему з Обліковий 
Авторизація отриманням JWT-токена запис існує 
USER UC-03: Перегляд Перегляд товарів з Авторизація 
каталогу фільтрацією та пагінацією 
USER UC-04: Перегляд Перегляд повної інформації Авторизація 
деталей товару про товар, аукціону, історії 
цін 
USER UC-05: Участь в Розміщення ставок на Авторизація 
аукціоні аукціоні в реальному часі 
USER UC-06: Додавання/видалення Авторизація 
Управління товарів, оформлення 
кошиком замовлення 
USER UC-07: Завантаження фото монети, Немає 
Використання AI- отримання результатів 
асистента аналізу 
USER UC-08: Створення, редагування, Авторизація 
Управління видалення записів колекції 
колекцією 
USER UC-09: Додавання/видалення Авторизація 
Управління товарів зі списку 
списком бажаного 
USER UC-10: Обмін Надсилання/отримання Авторизація 
повідомленнями повідомлень в реальному 
часі 
USER UC-11: Подача Подача заявки на Авторизація, 
заявки продавця отримання ролі SELLER роль USER 
SELLER UC-12: Створення Розміщення товарної Авторизація, 
товару пропозиції з зображеннями роль 
SELLER 
SELLER UC-13: Зміна даних власного Авторизація, 
Редагування товару власний 
товару товар 
 
53 
SELLER UC-14: Перегляд Перегляд кількості товарів, Авторизація, 
статистики доходу, останніх продажів роль 
SELLER 
SELLER UC-15: Створення Створення товару з Авторизація, 
товару з AI автозаповненням полів з роль 
AI-аналізу SELLER 
ADMIN UC-16: Блокування/розблокування, Авторизація, 
Управління зміна ролей роль 
користувачами ADMIN 
ADMIN UC-17: Зміна статусу, вказання Авторизація, 
Управління номера відстеження роль 
замовленнями ADMIN 
ADMIN UC-18: Розгляд Схвалення/відхилення Авторизація, 
заявок продавців заявок роль 
ADMIN 
ADMIN UC-19: Перегляд Перегляд KPI, графіків Авторизація, 
дашборду продажів та реєстрацій роль 
ADMIN 
4.1.3 Опис основних бізнес-процесів та потоків даних. Для кожного 
ключового бізнес-процесу визначено основний потік подій, альтернативні потоки та 
передумови. Нижче наведено опис трьох найважливіших бізнес-процесів системи. 
UC-05: Участь в аукціоні. Основний потік: 1) Користувач відкриває сторінку 
аукціону. 2) Система відображає поточну ціну, час завершення, історію ставок. 3) 
Користувач вводить суму ставки. 4) Система перевіряє коректність ставки (більша за 
поточну ціну + мінімальний крок). 5) Система створює запис ставки в БД. 6) Система 
оновлює поточну ціну. 7) Якщо до завершення аукціону менше 3 хвилин - система 
подовжує час на 3 хвилини (антиснайпінг). 8) Система надсилає сповіщення всім 
учасникам аукціону через Socket.IO. Альтернативний потік 4а: Ставка некоректна - 
система повертає помилку. Альтернативний потік 2а: Аукціон неактивний - система 
повертає помилку. 
UC-07: Використання AI-асистента.  
Розглянемо основний потік:  
1) Користувач завантажує до 4 зображень монети (JPEG, PNG, WebP).  
2) Користувач може додати текстову підказку (необов'язково).  
3) Система валідує формат та обсяг файлів. 
 
54 
 4) Система конвертує зображення у Base64 і формує запит до Google Gemini API 
зі структурованим промптом.  
5) AI-сервіс повертає результат аналізу.  
6) Система витягує JSON з відповіді та валідує структуру.  
7) Система відображає результат користувачу.  
8) Користувач може натиснути «Створити лот» для автоматичного заповнення 
форми створення товару. Альтернативний потік 3а: Некоректний формат - помилка 
400. Альтернативний потік 5а: AI-сервіс недоступний або повернув некоректний 
результат - помилка 500. 
UC-08: Управління колекцією. Розглянемо основний потік:  
1) Користувач відкриває сторінку «Моя колекція». 
2) Система відображає список записів користувача у вигляді сітки карток.  
3) Користувач натискає «Додати монету».  
4) Система відображає форму створення запису. 
5) Користувач заповнює поля (назва, країна, рік, матеріал, стан, рідкість, опис, 
нотатки) та завантажує до 5 зображень.  
6) Система валідує обов'язкові поля (назва та хоча б одне зображення).  
7) Система завантажує зображення через API.  
8) Система створює запис у БД та відображає оновлену колекцію. 
Альтернативний потік: редагування та видалення здійснюються аналогічно з 
перевіркою прав власності. 
4.2 Об'єктно-орієнтоване проєктування (PIM та PSM моделі) 
На основі сформованих інформаційних потоків і вимог до зберігання даних 
було спроєктовано логічну структуру бази даних. Структура складається з сутностей 
користувачів, категорій, продуктів, аукціонів та пов'язаних процесів. ER-діаграму 
(сутність-зв'язок) бази даних системи подано на (рисунку 4.2). 
 
55 
 
Рисунок 4.2 – ER-діаграма (сутність-зв'язок) бази даних системи 
 
4.2.1 PIM-модель: платформо-незалежна модель системи. PIM-модель 
(Platform Independent Model) визначає склад, структуру та поведінку системи без 
прив'язки до конкретних технологій реалізації. Основні сутності та їхні атрибути 
наведені в таблиці 4.3. 
 
 
 
 
56 
Таблиця 4.3 – Основні сутності PIM-моделі 
Сутність Атрибути Опис 
User id, email, password, name, role, Користувач системи з 
avatar, isBlocked, createdAt роллю 
USER/SELLER/ADMIN 
Product id, title, description, country, year, Товар (монета) на продаж 
material, rarity, condition, price, або аукціон 
images, isAuction 
Category id, name, description Категорія товару (античні, 
середньовічні тощо) 
Auction id, startPrice, currentPrice, Аукціон з параметрами 
minStep, startTime, endTime, status ставки та часом 
Bid id, amount, userId, auctionId, Ставка користувача на 
createdAt аукціоні 
Order id, userId, totalAmount, status, Замовлення на купівлю 
shippingAddress, trackingNumber товарів 
OrderItem id, orderId, productId, price Позиція замовлення 
(товар з ціною) 
Favorite id, userId, productId, createdAt Запис списку бажаного 
Notification id, userId, title, message, isRead, Системне сповіщення 
createdAt користувачу 
SellerApplication id, userId, phone, portfolioUrl, Заявка на роль продавця 
experience, status 
Message id, senderId, receiverId, content, Повідомлення між 
isRead, createdAt користувачами 
CollectionItem id, userId, title, description, Запис у персональній 
country, year, material, condition, колекції 
rarity, images, notes 
Зв'язки між сутностями PIM-моделі наведені в таблиці 4.4. 
Таблиця 4.4 – Зв'язки між сутностями PIM-моделі 
Зв'язок Тип Кардинальність Опис 
User - Product Асовація 1 : N Один продавець має багато 
товарів 
Product - Асовація N : 1 Багато товарів належать одній 
Category категорії 
Product - Auction Асовація 1 : 1 Товар може мати один аукціон 
Auction - Bid Асовація 1 : N Аукціон має багато ставок 
User - Bid Асовація 1 : N Користувач розміщує багато 
ставок 
User - Order Асовація 1 : N Користувач має багато 
замовлень 
Order - OrderItem Композиція 1 : N Замовлення містить багато 
позицій 
 
57 
Product - Асовація 1 : 0..1 Товар може бути в одній позиції 
OrderItem замовлення 
User - Favorite Асовація 1 : N Користувач має багато обраних 
товарів 
User - Асовація 1 : N Користувач отримує багато 
Notification сповіщень 
User - Асовація 1 : 0..1 Користувач має 0 або 1 заявку 
SellerApplication 
User - Message Асовація 1 : N Користувач надсилає багато 
(sender) повідомлень 
User - Message Асовація 1 : N Користувач отримує багато 
(receiver) повідомлень 
User - Асовація 1 : N Користувач має багато записів 
CollectionItem колекції 
Product - Композиція 1 : N Товар має історію цін 
PriceHistory 
4.2.2 PSM-модель: платформо-специфічна модель системи. PSM-модель 
(Platform Specific Model) адаптує PIM-модель до обраних технологій реалізації 
(таблиця 4.5). 
Таблиця 4.5 – Відображення PIM-сутностей у PSM-компоненти 
PIM-сутність PSM-реалізація Технологія 
User Модель Prisma User; контролер Prisma ORM, Express.js, 
auth.controller; маршрут /api/auth JWT 
Product Модель Prisma Product; Prisma ORM, Express.js, 
контролер product.controller; Multer 
маршрут /api/products 
Category Модель Prisma Category; Prisma ORM, Express.js 
контролер category.controller; 
маршрут /api/categories 
Auction - Bid Моделі Prisma Auction, Bid; Prisma ORM, Express.js, 
контролер auction.controller; Socket.IO 
маршрут /api/auctions; Socket.IO 
Order - OrderItem Моделі Prisma Order, OrderItem; Prisma ORM, Express.js 
контролер order.controller; 
маршрут /api/orders 
Favorite Модель Prisma Favorite; Prisma ORM, Express.js 
контролер user.controller; 
маршрут /api/users/wishlist 
Notification Модель Prisma Notification; Prisma ORM, Socket.IO 
Socket.IO 
 
58 
SellerApplication Модель Prisma SellerApplication; Prisma ORM, Express.js 
контролер seller.controller; 
маршрут /api/sellers 
Message Модель Prisma Message; Prisma ORM, Express.js, 
контролер message.controller; Socket.IO 
Socket.IO 
CollectionItem Модель Prisma CollectionItem; Prisma ORM, Express.js, 
контролер collection.controller; Multer 
маршрут /api/collections 
AI-асистент Інтерфейс AIProvider; класи Google Generative AI, 
GeminiProvider, OllamaProvider; Strategy pattern 
контролер ai.controller 
4.2.3 Логічна структура системи. Логічна структура системи визначає склад 
та ієрархію програмних компонентів. Система реалізована за тришаровою 
архітектурою з виділенням наступних логічних шарів: шар представлення (клієнтська 
частина), шар бізнес-логіки (серверна частина) та шар даних (PostgreSQL). Взаємодія 
між шарами здійснюється через REST API та Socket.IO. 
Шар представлення (клієнтська частина) реалізовано як SPA-застосунок на базі 
Next.js 16 з використанням React 19 та Tailwind CSS 4. Компонентна структура 
клієнтської частини наведена в таблиці 4.6. 
Таблиця 4.6 – Компонентна структура клієнтської частини 
Компонент Функціональність Маршрут 
Navbar Навігація, авторизація, кошик, Глобальний 
сповіщення 
CatalogPage Каталог товарів з фільтрацією та /catalog 
пагінацією 
ProductDetailPage Деталі товару, аукціон, фото, ціна /catalog/[id] 
AuctionsListPage Список аукціонів з фільтрацією /auctions 
за статусом 
AuctionRoomPage Аукціон в реальному часі, ставки, /auctions/[id] 
таймер 
AIAssistantPage Завантаження фото, AI-аналіз /ai-assistant 
монети 
CartPage Кошик товарів, розрахунок суми /cart 
CheckoutPage Оформлення замовлення, вибір /checkout 
оплати та доставки 
ProfilePage Особистий кабінет, редагування /profile 
профілю 
OrdersPage Історія замовлень користувача /profile/orders 
BidsPage Історія ставок користувача /profile/bids 
 
59 
WishlistPage Список бажаних товарів /profile/wishlist 
CollectionsPage Персональна колекція монет /profile/collections 
(CRUD) 
SellerDashboard Дашборд продавця зі /seller 
статистикою 
SellerProductsPage Управління товарами продавця /seller/products 
AdminDashboard Адміністративна панель з KPI та /admin 
графіками 
MessagesPage Обмін повідомленнями в /messages 
реальному часі 
4.2.4 Фізична структура системи. Фізична структура системи визначає 
розгортання логічних компонентів на апаратних засобах. Система розгортається у 
вигляді трьох контейнерів Docker, оркестрованих через Docker Compose (табл. 4.7). 
Таблиця 4.7 – Фізична структура розгортання 
Контейнер Компоненти Порт Залежності 
numismarket-db PostgreSQL 15 5433 (хост) - 5432 Немає 
(контейнер) 
numismarket- Node.js 20, Express.js 5, 5000 numismarket-db 
backend Prisma 7, Socket.IO 4 
numismarket- Next.js 16, React 19, 3000 numismarket-
frontend Tailwind CSS 4 backend 
Взаємодія між контейнерами здійснюється через внутрішню мережу Docker. 
Клієнтська частина звертається до серверного API за адресою: 
http://localhost:5000/api. Серверна частина звертається до бази даних за адресою, 
визначеною змінною середовища DATABASE_URL. Зовнішній AI-сервіс (Google 
Gemini API) доступний через HTTPS-зєднання. 
Схема бази даних реалізована за допомогою Prisma Schema Language та містить 
12 моделей з 4 переліками (enum).  
4.3 Динамічна поведінка системи (діаграми взаємодії) 
4.3.1 Діаграма послідовності: розміщення ставки на аукціоні. Нижче 
наведено послідовність взаємодій між об'єктами системи при розміщенні ставки на 
аукціоні (таблиця 4.8). 
 
60 
Таблиця 4.8 – Послідовність взаємодій: розміщення ставки на аукціоні 
Крок Ініціатор Дія Відповідь 
1 Користувач Натискає кнопку «Зробити ставку» - 
на сторінці аукціону 
2 Клієнт (Next.js) Відправляє HTTP POST - 
/api/auctions/:id/bid з {amount} 
3 Сервер (Express) Перевіряє JWT-токен (middleware 401 при 
protect) відсутності 
4 Сервер (Express) Знаходить аукціон за ID у БД 404 при 
неіснуючому ID 
5 Сервер (Express) Перевіряє: status = ACTIVE 400 при 
неактивному 
аукціоні 
6 Сервер (Express) Перевіряє: amount ≥ currentPrice + 400 при 
minStep некоректній 
ставці 
7 Сервер (Express) Створює запис Bid у БД - 
8 Сервер (Express) Оновлює Auction.currentPrice = - 
amount 
9 Сервер (Express) Перевіряє антиснайпінг: якщо - 
(endTime − now) < 3хв - endTime += 
3хв 
10 Сервер (Express) Повідомляє попереднього ставокця - 
через Socket.IO 
11 Сервер Emit: bid_placed до всіх учасників - 
(Socket.IO) кімнати auction:{id} 
12 Сервер (Express) Повертає {success: true, data: bid} - 
13 Клієнт (Next.js) Оновлює UI з новою ціною та часом - 
4.3.2 Діаграма послідовності: AI-аналіз монети. Послідовність взаємодій при 
аналізі зображень монети AI-асистентом наведена в таблиці 4.9. 
Таблиця 4.9 – Послідовність взаємодій: AI-аналіз монети 
Крок Ініціатор Дія Відповідь 
1 Користувач Завантажує 1–4 фото монети та - 
натискає «Проаналізувати» 
2 Клієнт (Next.js) Валідує формат (JPG, PNG, WebP) та Помилка при 
обсяг файлів невідповідності 
3 Клієнт (Next.js) Відправляє HTTP POST /api/ai/analyze - 
(multipart/form-data) 
4 Сервер (Express) Перевіряє наявність файлів та їх тип 400 при 
невідповідності 
5 Сервер (Express) Визначає AI-провайдер - 
(AI_PROVIDER: gemini/ollama) 
 
61 
6 Сервер Конвертує зображення у Base64, - 
(GeminiProvider) формує промпт 
7 Сервер Надсилає запит до Google Gemini API - 
(GeminiProvider) 
8 Google Gemini Обробляє зображення та повертає - 
API текстову відповідь 
9 Сервер (Express) Витягує JSON з відповіді регулярним 500 при 
виразом невідповідності 
10 Сервер (Express) Валідує структуру JSON (обов'язкові 500 при 
поля) невідповідності 
11 Сервер (Express) Повертає {success: true, data: result} - 
12 Клієнт (Next.js) Відображає результат аналізу в UI - 
13 Користувач Може натиснути «Створити лот» для - 
автозаповнення форми 
4.3.3 Діаграма послідовності: створення запису колекції. Послідовність 
взаємодій при створенні запису в персональній колекції наведена в таблиці 4.10. 
Таблиця 4.10 – Послідовність взаємодій: створення запису колекції 
Крок Ініціатор Дія Відповідь 
1 Користувач Натискає «Додати монету» та - 
заповнює форму 
2 Клієнт (Next.js) Завантажує зображення послідовно URL кожного 
через POST /api/upload зображення 
3 Сервер (Express) Зберігає зображення на диску, - 
повертає URL 
4 Клієнт (Next.js) Формує payload з даними запису + - 
масивом URL зображень 
5 Клієнт (Next.js) Відправляє HTTP POST - 
/api/collections 
6 Сервер (Express) Перевіряє JWT-токен (middleware 401 при 
protect) відсутності 
7 Сервер (Express) Валідує обов'язкові поля (title, 400 при 
images) невідповідності 
8 Сервер (Express) Створює запис CollectionItem у БД - 
9 Сервер (Express) Повертає створений запис - 
10 Клієнт (Next.js) Оновлює UI списку колекції - 
4.3.4 Діаграма станів: життєвий цикл аукціону. Опис життєвого циклу 
аукціону як автомату зі станами наведено в таблиці 4.11. 
 
 
 
 
62 
Таблиця 4.11 – Стани та переходи аукціону 
Поточний Подія / умова Наступний Дія 
стан стан 
- Створення товару з PENDING Створення запису Auction з 
isAuction=true параметрами 
PENDING Наступив час ACTIVE Зміна status на ACTIVE; 
startTime сповіщення учасників 
ACTIVE Розміщення ставки ACTIVE Оновлення currentPrice; 
(новий лід) антиснайпінг при необхідності 
ACTIVE Наступив час COMPLETED Зміна status на COMPLETED; 
endTime  сповіщення продавця 
(без ставок) 
ACTIVE Наступив час COMPLETED Зміна status на COMPLETED; 
endTime  сповіщення переможця 
(зі ставками) 
ACTIVE/ Скасування CANCELLED Зміна status на CANCELLED; 
PENDING адміністратором сповіщення всіх учасників 
Начальний стан аукціону - PENDING (очікування). При настанні часу початку 
аукціон переходить у стан ACTIVE (активний). Під час активного стану розміщення 
ставок не змінює стан аукціону, але оновлює поточну ціну та може подовжити час 
завершення (антиснайпінг). При настанні часу завершення аукціон переходить у стан 
COMPLETED (завершено). Адміністратор може скасувати аукціон, перевівши його у 
стан CANCELLED. Стан CANCELLED є кінцевим - можливі лише переходи з 
PENDING та ACTIVE. 
Висновки до розділу 4 
У цьому розділі проведено об'єктно-орієнтований аналіз та проєктування 
системи NumisMarket, що дозволяє зробити такі висновки: 
 
63 
1. Визначено словник предметної області (11 термінів), три актори (Гість, 
USER, SELLER, ADMIN) та 19 варіантів використання (таблиця 4.2), що повністю 
покривають функціональні вимоги, сформульовані в розділі 2. 
2. Розроблено PIM-модель системи (12 сутностей, 15 зв'язків - таблиці 4.3, 4.4) 
та PSM-модель, що адаптує PIM-сутності до конкретних технологій реалізації 
(таблиця 4.5). Визначено логічну структуру (17 клієнтських компонентів - таблиця 
4.6) та фізичну структуру (3 Docker-контейнери - таблиця 4.7). 
3. Змодельовано динамічну поведінку системи через діаграми послідовності для 
трьох ключових бізнес-процесів (розміщення ставки - таблиця 4.8, AI-аналіз - таблиця 
4.9, створення запису колекції - таблиця 4.10) та діаграму станів життєвого циклу 
аукціону (таблиця 4.11). 
4. Проєктні рішення забезпечують повну відповідність функціональним та 
нефункціональним вимогам, сформульованим у розділі 2, та повну реалізованість 
обраних методів та засобів з розділу 3. 
5. Результати цього розділу складають повну проєктну документацію, 
необхідну для переходу до етапу практичної реалізації системи, який розглядається в 
розділі 5. 
 
 
 
 
 
 
 
 
 
 
 
 
 
64 
5 ПРАКТИЧНА РЕАЛІЗАЦІЯ ТА АНАЛІЗ РЕЗУЛЬТАТІВ 
У цьому розділі описано практичну реалізацію розробленої системи 
NumisMarket на основі проєктних рішень, прийнятих у розділі 4, та обраних методів 
і засобів з розділу 3. Наведено опис структури бази даних, складу та функцій 
програмних модулів, процесів взаємодії компонентів системи та користувацьких 
інтерфейсів. Виконано аналіз результатів тестування та підтверджено відповідність 
системи сформульованим вимогам. 
5.1 Опис реалізації завдання 
5.1.1 Структура бази даних. База даних системи NumisMarket реалізована на 
основі СУБД PostgreSQL 15 з використанням Prisma ORM 7.x як шару доступу до 
даних. Схема бази даних описана мовою Prisma Schema Language та містить 12 
моделей даних та 4 переліки (enum). Повний опис моделей бази даних наведено в 
таблиці 5.1. 
Таблиця 5.1 – Моделі бази даних системи NumisMarket 
Модель Ключові поля Зв'язки Призначення 
User id (UUID), email Product[], Bid[], Користувач 
(unique), password, Favorite[], Order[], системи 
name, role, avatar, Notification[], 
isBlocked SellerApplication?, 
Message[], 
CollectionItem[] 
Category id (UUID), name Product[] Категорія товарів 
(unique), description 
Product id (UUID), title, seller (User), Товар (монета) 
description, country, category (Category), 
year, material, rarity, auction?, 
condition, price, favorites[], 
images[], isAuction orderItem?, 
priceHistory[] 
PriceHistory id (UUID), productId, product (Product, Історія цін товару 
price, date onDelete: Cascade) 
Auction id (UUID), productId product (Product), Аукціон товару 
(unique), startPrice, bids[] 
currentPrice, minStep, 
 
65 
startTime, endTime, 
status 
Bid id (UUID), amount, user (User), auction Ставка на аукціоні 
userId, auctionId, (Auction) 
createdAt 
Favorite id (UUID), userId, user (User), product Запис списку 
productId, createdAt (Product), бажаного 
@@unique([userId, 
productId]) 
Order id (UUID), userId, user (User), items[] Замовлення 
totalAmount, status, 
shippingAddress, 
trackingNumber 
OrderItem id (UUID), orderId, order (Order), Позиція 
productId (unique), product (Product) замовлення 
price 
Notification id (UUID), userId, user (User) Системне 
title, message, isRead, сповіщення 
createdAt 
SellerApplication id (UUID), userId user (User) Заявка на роль 
(unique), phone, продавця 
portfolioUrl, 
experience, status 
Message id (UUID), senderId, sender (User), Повідомлення між 
receiverId, content, receiver (User) користувачами 
isRead, createdAt 
CollectionItem id (UUID), userId, user (User, Запис 
title, description, onDelete: Cascade) персональної 
country, year, material, колекції 
condition, rarity, 
images[], notes 
Переліки (enum) бази даних наведені в таблиці 5.2. 
Таблиця 5.2 – Переліки (enum) бази даних 
Перелік Значення Призначення 
Role USER, SELLER, Роль користувача в системі 
ADMIN 
ApplicationStatus PENDING, Статус заявки на роль 
APPROVED, продавця 
REJECTED 
 
66 
Condition POOR, GOOD, Стан збереженості монети 
VERY_GOOD, 
EXCELLENT, MINT 
AuctionStatus PENDING, ACTIVE, Статус аукціону 
COMPLETED, 
CANCELLED 
Забезпечення цілісності даних реалізовано через: зовнішні ключі (Foreign Keys) 
з каскадним видаленням (onDelete: Cascade) для моделей PriceHistory, CollectionItem 
та інших; унікальні обмеження (unique) для email користувача, назви категорії, 
productId в Auction та userId в SellerApplication; складений унікальний індекс 
@@unique([userId, productId]) для моделі Favorite, що запобігає дублюванню записів 
у списку бажаного; унікальний індекс для productId в OrderItem, що гарантує, що 
кожен товар може бути продано лише один раз. Міграції бази даних виконуються 
автоматично при розгортанні через команду npx prisma db push, яка входить до складу 
Docker Compose конфігурації. 
5.1.2 Склад та функції програмних модулів серверної частини. Серверна 
частина системи реалізована на платформі Node.js 20 LTS з використанням веб-
фреймворку Express.js 5.x та мови TypeScript 6.x. Архітектура серверної частини 
побудована за шаблоном MVC (Model-View-Controller) з виділенням окремих шарів: 
маршрути (routes), контролери (controllers), сервіси (services), проміжне програмне 
забезпечення (middleware) та моделі даних (Prisma). Структура каталогів серверної 
частини наведена в таблиці 5.3. 
Таблиця 5.3 – Структура каталогів серверної частини 
Каталог Вміст Призначення 
src/controllers/ auth.controller.ts, Обробка HTTP-запитів, 
product.controller.ts, виклик сервісів, 
auction.controller.ts, user.controller.ts, формування відповідей 
admin.controller.ts, seller.controller.ts, 
order.controller.ts, ai.controller.ts, 
category.controller.ts, 
message.controller.ts, 
collection.controller.ts 
src/routes/ auth.routes.ts, product.routes.ts, Визначення маршрутів API 
auction.routes.ts, user.routes.ts, та прив'язка middleware 
admin.routes.ts, seller.routes.ts, 
 
67 
order.routes.ts, upload.routes.ts, 
ai.routes.ts, category.routes.ts, 
message.routes.ts, collection.routes.ts 
src/middlewares/ auth.middleware.ts JWT-автентифікація, 
перевірка ролей (protect, 
admin, sellerOrAdmin) 
src/services/ai/ aiService.ts, geminiProvider.ts, Інтеграція з AI-сервісами 
ollamaProvider.ts (патерн Strategy) 
src/prompts/ coinAnalysis.ts Структуровані промпти для 
AI-аналізу монет 
src/sockets/ auctionHandler.ts, messageHandler.ts Обробка Socket.IO подій 
(аукціони, повідомлення) 
src/lib/ prisma.ts Ініціалізація Prisma Client з 
PostgreSQL адаптером 
src/ index.ts Точка входу: налаштування 
Express, Socket.IO, 
маршрутів, middleware 
prisma/ schema.prisma, migrations/ Схема бази даних та 
міграції 
Склад та функції основних API-маршрутів серверної частини наведені в табл. 5.4. 
Таблиця 5.4 – API-маршрути серверної частини 
Маршрут Метод URL Доступ Функція 
Реєстрація POST /api/auth/register Публічний Створення облікового запису 
Авторизація POST /api/auth/login Публічний Вхід з отриманням JWT 
Профіль GET /api/auth/profile Авторизова- Отримання даних 
ний користувача 
Змінна GET /api/products Публічний Каталог з фільтрацією та 
товарів пагінацією 
Деталі товару GET /api/products/:id Публічний Детальна інформація про 
товар 
Створення POST /api/products seller/admin Створення товарної 
товару пропозиції 
Оновлення PUT /api/products/:id seller/admin Редагування товару 
товару 
Видалення DELETE /api/products/:id seller/admin Видалення товару 
товару 
Список GET /api/auctions Публічний Список аукціонів за статусом 
аукціонів 
Деталі GET /api/auctions/:id Публічний Деталі аукціону зі ставками 
аукціону 
Розміщення POST /api/auctions/ Авторизо- Розміщення ставки 
ставки :id/bid ваний (Socket.IO) 
Профіль PUT /api/users/profile Авторизо- Оновлення профілю 
користувача ваний 
Історія GET /api/users/history Авторизова- Замовлення та ставки 
ний 
Список GET/ /api/users/ Авторизо- Перегляд/переключення 
бажаного POST wishlist[/:id] ваний 
Сповіщення GET/ /api/users/ Авторизо- Перегляд/позначення 
PUT notifications[/:id] ваний 
 
68 
Дашборд GET /api/admin/dashboard admin KPI та статистика 
адміна 
Управління GET/PUT /api/admin/users[/:id] admin Список/блокування/зміна 
користу- ролей 
вачами 
Управління GET/PUT /api/admin/ admin Список/оновлення статусу 
замовлен- orders[/:id] 
нями 
Заявки GET/PUT /api/admin/ admin Список/схвалення/відхилення 
продавців applications[/:id] 
Заявка POST/ /api/sellers/apply, Авторизо- Подача/перевірка заявки 
продавця GET /status ваний 
Статистика GET /api/sellers/stats seller/admin Кількість товарів, дохід 
продавця 
Створення POST /api/orders Авторизо- Оформлення замовлення з 
замовлення ваний кошика 
Список GET /api/orders Авторизо- Історія замовлень 
замовлень ваний користувача 
Завантаження POST /api/upload Публічний Завантаження зображення 
файлу (Multer) 
AI-аналіз POST /api/ai/analyze Публічний Аналіз зображень монет 
Категорії GET /api/categories Публічний Список категорій 
Контакти GET /api/messages/ Авторизо- Список контактів чату 
повідомлень contacts ваний 
Історія GET /api/messages/ Авторизо- Повідомлення з 
повідомлень :userId ваний користувачем 
Колекція GET /api/collections Авторизо- Список записів колекції 
(список) ваний 
Колекція POST /api/collections Авторизо- Створення запису колекції 
(створення) ваний 
Колекція PUT /api/collections/ Авторизо- Редагування запису колекції 
(оновлення) :id ваний 
Колекція DELETE /api/collections/ Авторизо- Видалення запису колекції 
(видалення) :id ваний 
Особливості реалізації серверної частини включають: використання 
проміжного програмного забезпечення (middleware) protect для JWT-автентифікації 
та middleware admin та sellerOrAdmin для перевірки ролей; застосування Multer для 
обробки multipart form-data при завантаженні зображень (зберігання на диску сервера 
у каталог uploads); реалізація патерну Strategy для AI-провайдерів - інтерфейс 
AIProvider визначає метод analyzeCoin(images, hint), який реалізується GeminiProvider 
та OllamaProvider, що дозволяє змінювати AI-провайдера через змінну середовища 
AI_PROVIDER без модифікації основного коду; використання Socket.IO для 
взаємодії в реальному часі (аукціонні ставки, сповіщення, повідомлення) з 
реалізацією кімнат (rooms) для ізоляції аукціонних подій. 
 
69 
5.1.3 Склад та функції клієнтської частини. Клієнтська частина реалізована 
на базі Next.js 16 з використанням React 19 та Tailwind CSS 4. Застосунок 
використовує App Router з файловою системою маршрутизації. Кожна сторінка є 
клієнтським компонентом ('use client'), оскільки взаємодіє з API та станом 
користувача. Структура сторінок клієнтської частини наведена в таблиці 5.5. 
Таблиця 5.5 – Сторінки клієнтської частини 
Сторінка Маршрут Основні функції Доступ 
Головна / Hero-секція, список нових Публічний 
товарів, посилання на 
каталог та аукціони 
Каталог /catalog Пошук, фільтрація Публічний 
(матеріал, стан), 
сортування, пагінація 
(9/стор.) 
Деталі товару /catalog/[id] Фото-галерея, Публічний 
характеристики, історія цін 
(графік), ставка/кошик 
Список /auctions Фільтрація за статусом Публічний 
аукціонів (ACTIVE/COMPLETED), 
поточна ціна, час 
Кімната /auctions/[id] Реалтаймові ставки, Авторизований 
аукціону таймер, антиснайпінг, 
історія ставок 
AI-асистент /ai-assistant Drag-and-drop Публічний 
завантаження фото, 
результат аналізу, 
«Створити лот» 
Кошик /cart Список товарів, видалення, Авторизований 
загальна сума, перехід до 
оформлення 
Оформлення /checkout Контакти, доставка (Nova Авторизований 
замовлення Poshta), оплата (карта/при 
отриманні) 
Профіль /profile Редагування імені та Авторизований 
аватара 
Замовлення /profile/orders Список замовлень зі Авторизований 
статусами 
Історія ставок /profile/bids Список ставок користувача Авторизований 
Список /profile/wishlist Сітка обраних товарів, Авторизований 
бажаного видалення 
 
70 
Моя колекція /profile/collections CRUD записів колекції, Авторизований 
завантаження фото до 5 
шт. 
Заявка /profile/seller- Форма заявки, статус USER 
продавця application розгляду 
Дашборд /seller Статистика: кількість SELLER 
продавця товарів, дохід, останні 
продажі 
Товари /seller/products Список товарів продавця, SELLER 
продавця створення/видалення 
Створення /seller/products/new Форма створення товару SELLER 
товару (автозаповнення з AI) 
Дашборд /admin KPI, графіки (Recharts), ADMIN 
адміна останні замовлення, топ 
аукціонів 
Користувачі /admin/users Блокування/розблокування, ADMIN 
зміна ролей 
Замовлення /admin/orders Зміна статусу, номери ADMIN 
відстеження, сповіщення 
Заявки /admin/applications Перегляд, ADMIN 
продавців схвалення/відхилення 
заявок 
Товари (адмін) /admin/products Список товарів, створення, ADMIN 
видалення 
Повідомлення /messages Реалтаймовий чат, список Авторизований 
контактів, непрочитані 
Авторизація /login, /register Вхід та реєстрація з JWT- Публічний 
автентифікацією 
Взаємодія клієнтської частини з серверною здійснюється через два канали: 
REST API (бібліотека Axios з інтерцептором для автоматичного додавання JWT-
токена до заголовків авторизації) та Socket.IO (для аукціонних ставок, сповіщень та 
повідомлень в реальному часі). Клієнтська частина не зберігає стан авторизації в 
глобальному контексті (React Context); замість цього дані користувача зберігаються в 
localStorage та зчитуються кожним компонентом при необхідності. Стан кошика 
також реалізовано на основі localStorage з використанням кастомної події cartUpdated 
для синхронізації між компонентами. 
Дизайн інтерфейсу реалізовано у темній темі з акцентними кольорами золота 
(CSS-змінні -color-gold-400, -color-gold-500, -color-gold-600). Основні стилістичні 
елементи: скломорфізм (glass-card з backdrop-blur), градієнтні кнопки (bg-gradient-to-
 
71 
r from-gold-400 to-yellow-300), анімації (fadeInUp, fadeIn, shimmer-завантаження). 
Інтерфейс адаптивний (responsive design) і оптимізований для настільних та 
мобільних пристроїв. Компонент іконок - Lucide React, що забезпечує погоджене 
SVG-оформлення на всіх сторінках. 
5.1.4 Взаємодія компонентів системи. Взаємодія між компонентами системи 
NumisMarket здійснюється через чотири основні канали комунікації: REST API, 
Socket.IO, зовнішній AI-сервіс та(files система). Розглянемо кожен канал детальніше. 
REST API. Клієнтська частина взаємодіє з серверною через HTTP-запити до 
ендпойнтів, наведених у таблиці 5.4. Інтерцептор Axios автоматично додає JWT-
токен із localStorage до заголовка Authorization: Bearer «token». Відповіді сервера 
повертаються у форматі JSON. При помилках сервер повертає відповідний HTTP-
статус (400, 401, 403, 404, 500) з повідомленням про помилку. Завантаження файлів 
здійснюється через multipart/form-data (endpoints /api/upload та /api/ai/analyze) з 
використанням Multer на серверній стороні. 
Socket.IO. Взаємодія в реальному часі реалізована через три основні простори 
імен (namespaces): аукціонні події (auction: auction:«id»), повідомлення (message 
rooms: user: «userId») та сповіщення (notification rooms: user: «userId»). При 
підключенні клієнт ідентифікується через JWT-токен, переданий у handshake-запиті. 
Сервер обробляє події bid_placed (нова ставка), auction_ended (завершення аукціону), 
outbid_notification (перебиття ставки), new_message (нове повідомлення) та 
notification (системне сповіщення). Механізм антиснайпінгу реалізовано на серверній 
стороні: при розміщенні ставки в останні 3 хвилини аукціону час завершення 
автоматично подовжується на 3 хвилини, і сповіщення про це надсилається всім 
учасникам кімнати аукціону. 
Зовнішній AI-сервіс. Інтеграція з Google Gemini API реалізована за патерном 
Strategy. Інтерфейс AIProvider визначає метод analyzeCoin(images, hint), який 
реалізується двома класами: GeminiProvider (використовує модель gemini-3.1-flash-
lite, передає зображення у форматі Base64 як inlineData у складі multipart-запиту) та 
OllamaProvider (використовує локальну модель moondream через API Ollama). 
Перемикання між провайдерами здійснюється через змінну середовища 
 
72 
AI_PROVIDER. Промпт для AI-аналізу сформульовано українською мовою та 
вимагає від моделі виведення результату виключно у форматі JSON із заздалегідь 
визначеною структурою полів (identification, grading, description, rarity, confidence, 
notes). 
Файлова система. Завантаження зображень товарів та записів колекції 
здійснюється через API api upload з використанням Multer у режимі diskStorage. 
Файли зберігаються у каталозі uploads/ серверної частини з унікальними іменами 
(формат: «fieldname»-«timestamp». «extension»). Доступ до збережених файлів 
надається через статичний маршрут uploads «filename». Для AI-аналізу зображення 
завантажуються у режимі memoryStorage (buffers у пам'яті), що дозволяє передавати 
їх безпосередньо до Gemini API без збереження на диску. 
5.1.5 Реалізація ключових алгоритмів. У цьому підрозділі наведено 
фрагменти реалізації ключових алгоритмів, описаних у розділі 3. Повний лістинг коду 
наведено в додатку Б. 
Реалізація алгоритму розміщення ставки з антиснайпінгом (фрагмент 
серверного контролера auction.controller.ts) виконує такі ключові кроки: перевірка 
статусу аукціону (ACTIVE); перевірка суми ставки (≥ currentPrice + minStep); 
створення запису Bid у базі даних; оновлення Auction.currentPrice; перевірка умови 
антиснайпінгу (якщо до endTime < 3 хвилин, то endTime += 3 хвилини); надсилання 
сповіщення через Socket.IO всім учасникам аукціону (bid_placed) та попередньому 
ставокцю (outbid_notification). 
Реалізація алгоритму AI-аналізу монет здійснюється згідно з патерном Strategy. 
Контролер ai.controller.ts приймає multipart-запит з зображеннями, валідує типи 
файлів (JPG, PNG, WebP), визначає AI-провайдера через змінну середовища та 
делегує обробку відповідному класу. GeminiProvider конвертує зображення у Base64, 
формує запит з структурованим промптом та передає до Google Gemini API. Результат 
очищується від markdown-обгорток через регулярний вираз та валідується на 
наявність обов'язкових полів. 
Реалізація алгоритму створення замовлення забезпечує атомарність операції: 
ціни товарів беруться з бази даних (не з клієнтського запиту); товари, що вже мають 
 
73 
пов'язаний OrderItem, виключаються з замовлення; початковий статус замовлення 
визначається способом оплати (PAID для карти, COD_PENDING для оплати при 
отриманні). Адміністратор може оновлювати статус замовлення, при цьому 
автоматично створюється сповіщення для користувача та надсилається подія через 
Socket.IO. 
5.2 Аналіз результатів 
5.2.1 Контрольний приклад: розміщення ставки на аукціоні. Для перевірки 
працездатності ключового бізнес-процесу – розміщення ставки на аукціоні з 
механізмом антиснайпінгу – розроблено контрольний приклад (тест-кейс), що 
підтверджує коректність реалізації. Тест-кейс виконано на розгорнутій системі 
(Docker Compose) за наступними кроками. 
Початкові умови: в системі зареєстровано три користувачі (адміністратор, 
продавець та покупець); продавець розмістив товар «Денарій Цезаря» з аукціоном 
(початкова ціна 500 грн, мінімальний крок 50 грн, час завершення через 10 хвилин). 
Крок 1. Покупець відкриває сторінку аукціону. Система відображає: поточну 
ціну 500 грн, час завершення, відсутність ставок, повідомлення «Аукціон активний». 
Результат: сторінка завантажується коректно, дані відображаються в реальному часі 
через Socket.IO. 
Крок 2. Покупець розміщує ставку 550 грн. Система: перевіряє коректність (550 
≥ 500 + 50); створює запис Bid; оновлює Auction.currentPrice = 550; надсилає подію 
bid_placed через Socket.IO. Результат: ставка прийнята, ціна оновлена, історія ставок 
поповнена. 
Крок 3. Інший покупець розміщує ставку 600 грн за 2 хвилини до завершення 
аукціону. Система: перевіряє коректність (600 ≥ 550 + 50); створює запис Bid; 
оновлює Auction.currentPrice = 600; визначає, що до endTime < 3 хвилин - застосовує 
антиснайпінг (endTime += 3 хвилини); надсилає сповіщення попередньому ставокцю 
про перебиття його ставки. Результат: ставка прийнята, ціна оновлена, час аукціону 
подовжено на 3 хвилини, сповіщення доставлено. 
 
74 
Крок 4. Настане час завершення аукціону (з урахуванням подовження). 
Система: змінює статус аукціону на COMPLETED; надсилає сповіщення переможцю. 
Результат: аукціон завершено, переможець визначено. 
Висновок: контрольний приклад підтверджує коректність реалізації алгоритму 
розміщення ставок з антиснайпінгом. Всі кроки виконані успішно, цілісність даних 
забезпечена, сповіщення доставлені в реальному часі. 
5.2.2 Контрольний приклад: AI-аналіз монети. Для перевірки працездатності 
AI-асистента виконано контрольний приклад з аналізом зображення античної монети. 
Початкові умови: користувач відкриває сторінку  ai-assistant; AI-провайдер 
налаштовано на gemini (змінна середовища AI_PROVIDER=gemini); API-ключ 
GEMINI_API_KEY встановлено. 
Крок 1. Користувач завантажує зображення монети (формат JPG, обсяг 2.3 МБ) 
та натискає «Проаналізувати». Система: валідує формат файлу (JPG -допустимий); 
конвертує зображення у Base64; формує запит до Google Gemini API з україномовним 
промптом; передає зображення як inlineData з MIME-типом image jpeg. Результат: 
запит надіслано, відображається індикатор завантаження. 
Крок 2. Отримання відповіді від AI-сервісу (приблизно 8–15 секунд). Система: 
витягує JSON з відповіді регулярним виразом {*S}; валідує наявність обов'язкових 
полів (identification, grading, description, rarity, confidence). Результат: структурований 
результат аналізу містить ідентифікацію монети (назва, країна, рік, номінал, матеріал, 
номер у каталозі), оцінку стану (condition, conditionLabel, conditionDescription), опис 
аверсу та реверсу, визначення рідкості та рівень впевненості. 
Крок 3. Відображення результату в UI. Система: відображає результат аналізу 
у вигляді структурованої картки з кольоровими індикаторами стану, рідкості та 
впевненості. Результат: користувач може натиснути «Створити лот з цими даними» 
для автоматичного заповнення форми створення товару. 
Висновок: контрольний приклад підтверджує коректність реалізації алгоритму 
AI-аналізу. Зображення оброблено, результат отримано у форматі JSON, валідація 
пройшла успішно, UI відображено коректно. 
 
75 
5.2.3 Контрольний приклад: управління колекцією. Для перевірки 
працездатності модуля управління персональною колекцією виконано контрольний 
приклад. 
Крок 1. Авторизований користувач переходить на сторінку /profile/collections. 
Система: відправляє GET api collections; отримує список записів колекції поточного 
користувача; відображає сітку карток або порожній стан з кнопкою «Додати першу 
монету». Результат: сторінка завантажується коректно, колекція відображається. 
Крок 2. Користувач натискає «Додати монету», заповнює форму (назва: «Аурей 
Августа», країна: «Римська імперія», рік: -27, матеріал: «Золото», стан: 
VERY_GOOD, рідкість: «Рідкісна», опис, нотатки) та завантажує 2 зображення. 
Система: послідовно завантажує зображення через POST /api/upload; отримує URLs; 
формує payload з даними + URLs; відправляє POST api collections; отримує створений 
запис. Результат: запис створено, колекція оновлена. 
Крок 3. Користувач натискає «Редагувати» на картці запису. Система: відкриває 
модальне вікно з попередньо заповненими даними; користувач змінює нотатки та 
зберігає. Система: відправляє PUT api collections :id. Результат: запис оновлено. 
Крок 4. Користувач натискає «Видалити». Система: запитує підтвердження; 
відправляє DELETE api/collections :id. Результат: запис видалено, колекція оновлена. 
Висновок: контрольний приклад підтверджує коректність реалізації CRUD-
операцій записів колекції: створення, перегляд, редагування та видалення працюють 
коректно, авторизація забезпечує доступ лише до власних записів. 
5.2.4 Відповідність системи сформульованим вимогам. Нижче наведено 
оцінку відповідності реалізованої системи функціональним вимогам, 
сформульованим у розділі 2 (таблиця 5.6). 
Таблиця 5.6 – Відповідність функціональним вимогам 
Вимога Опис Статус Реалізація 
Ф1 Автентифікація та Реалізовано JWT-токени, middleware 
авторизація protect/admin/sellerOrAdmin 
Ф2 Управління товарами Реалізовано CRUD /api/products, Multer, 
фільтрація, пагінація 
 
76 
Ф3 Аукціонна торгівля в Реалізовано Socket.IO, антиснайпінг, 
реальному часі сповіщення 
Ф4 AI-асистент атрибуції Реалізовано Google Gemini API, 
монет Strategy pattern, structured 
output 
Ф5 Управління колекціями Реалізовано CRUD /api/collections, 
завантаження до 5 
зображень 
Ф6 Управління Реалізовано POST /api/orders, статуси, 
замовленнями сповіщення Socket.IO 
Ф7 Обмін повідомленнями Реалізовано Socket.IO, контакти, 
позначки прочитання 
Ф8 Адміністрування Реалізовано CRUD /api/admin/*, KPI, 
Recharts 
Оцінка відповідності нефункціональним вимогам наведена в таблиці 5.7. 
Таблиця 5.7 – Відповідність нефункціональним вимогам 
Вимога Категорія Статус Підтвердження 
НФ1 Продуктивність Виконано REST API відповідає < 500 мс для 
стандартних запитів; AI-аналіз < 60 с; 
Socket.IO < 1 с 
НФ2 Надійність Виконано Цілісність даних забезпечена 
транзакціями Prisma; Socket.IO 
автоматичне перепідключення 
НФ3 Безпека Виконано bcrypt (10 раундів); JWT (7 днів); 
перевірка ролей; змінні середовища 
для секретів 
НФ4 Масштабованість Виконано Docker Compose ізоляція сервісів; 
горизонтальне масштабування 
сервера 
 
77 
НФ5 Зручність Виконано Адаптивний UI (responsive); темна 
тема з золотими акцентами; мінімум 
дій 
НФ6 Сумісність Виконано Тестовано в Chrome, Firefox, Edge; 
RESTful API відповідність 
5.2.5 Теоретична та практична цінність результатів. Теоретична цінність 
роботи полягає в обґрунтуванні та практичній перевірці комплексного підходу до 
розробки веб-платформи для нумізматичної електронної комерції, що поєднує 
функціональність інтернет-магазину, аукціонної торгівлі в реальному часі, AI-
асистованої атрибуції монет та управління персональними колекціями. Доведено, що 
використання мультимодальних великих мовних моделей (Google Gemini) для задачі 
атрибуції монет є практично реалізовним і забезпечує прийнятну якість результатів 
без необхідності донавчання на спеціалізованому датасеті. Доведено ефективність 
механізму антиснайпінгу на основі подовження часу аукціону для забезпечення 
прозорості та справедливості аукціонного процесу. 
Практична цінність роботи полягає в тому, що розроблений веб-застосунок 
NumisMarket є готовим до впровадження програмним продуктом, повністю 
реалізуючим усі сформульовані функціональні та нефункціональні вимоги. Система 
забезпечує: повний цикл операцій нумізматичної торгівлі (від реєстрації до 
оформлення замовлення); інтегрований AI-асистент для атрибуції монет за 
зображеннями (з можливістю зміни провайдера через конфігурацію); аукціонну 
торгівлю в реальному часі з механізмом антиснайпінгу; управління персональними 
колекціями; систему ролей і повну адміністративну панель. Контейнеризоване 
розгортання через Docker Compose забезпечує відтворюваність та простоту 
розгортання системи на будь-якій платформі, що підтримує Docker. 
Висновки до розділу 5 
У цьому розділі представлено практичну реалізацію та аналіз результатів, що 
дозволяє зробити такі висновки: 
 
78 
1. Реалізовано повнофункціональний веб-застосунок NumisMarket з 
архітектурою, проєктованою в розділі 4, з використанням технологій, обґрунтованих 
у розділі 3. Серверна частина містить 11 контролерів, 12 маршрутів, 2 обробники 
Socket.IO та інтеграцію з Google Gemini API. Клієнтська частина містить 23 сторінки 
з адаптивним інтерфейсом у темній темі. 
2. Структура бази даних реалізована на основі 12 моделей та 4 переліків з 
використанням Prisma ORM, що забезпечує типобезпечний доступ до даних та 
автоматичну генерацію міграцій. Забезпечення цілісності даних реалізовано через 
зовнішні ключі, унікальні обмеження та каскадне видалення. 
3. Контрольні приклади підтвердили коректність реалізації трьох ключових 
бізнес-процесів: розміщення ставки на аукціоні з антиснайпінгом, AI-аналізу 
зображень монет та управління персональною колекцією. Всі функціональні вимоги 
(Ф1-Ф8) та нефункціональні вимоги (НФ1-НФ6) повністю виконані. 
4. Практична цінність результатів полягає в тому, що розроблений застосунок є 
готовим до впровадження програмним продуктом, який комплексно вирішує виявлені 
проблеми існуючих рішень: відсутність AI-експертизи, відсутність аукціонних 
механізмів у реальному часі з антиснайпінгом та відсутність інструментів управління 
колекціями. 
5. Результати цього розділу підтверджують працездатність системи та 
відповідність сформульованим вимогам, що є підставою для формування загальних 
висновків роботи. 
 
 
 
 
 
 
 
 
 
 
79 
ВИСНОВКИ 
У результаті виконання кваліфікаційної роботи бакалавра розроблено 
повнофункціональний веб-застосунок NumisMarket для нумізматичного інтернет-
магазину з інтеграцією технологій штучного інтелекту. На основі проведеного 
дослідження зроблено наступні висновки: 
1. Проведено аналіз предметної області нумізматичної електронної комерції та 
огляд існуючих рішень (eBay, VCoins, MA-Shops, PCGS, NGC), що дозволило виявити 
недоліки: відсутність інтегрованого AI-асистента для атрибуції монет, відсутність 
механізмів аукціонної торгівлі в реальному часі з антиснайпінгом, відсутність 
інструментів управління персональними колекціями та слабка орієнтація існуючих 
платформ на потреби вітчизняного ринку. Визначено, що жодна з існуючих платформ 
не забезпечує комплексного підходу, що поєднував би усі перелічені функції. 
2. Обґрунтовано вибір методів та технологій: JWT-токени для автентифікації, 
Prisma ORM для управління даними, Socket.IO для взаємодії в реальному часі, 
PostgreSQL як СУБД, Google Gemini як AI-провайдер з архітектурною можливістю 
заміни через патерн Strategy, модульна монолітна архітектура з клієнт-серверним 
розділенням. Кожен вибір обґрунтовано порівняльним аналізом з альтернативами з 
використанням таблиць порівняння. 
3. Розроблено та обґрунтовано три ключові алгоритми: алгоритм розміщення 
ставки на аукціоні з антиснайпінгом (забезпечує цілісність даних при одночасних 
ставках та справедливість аукціонного процесу); алгоритм аналізу зображень монет 
AI-асистентом на основі мультимодальної моделі Google Gemini із структуреним 
промптом (забезпечує універсальність розпізнавання без донавчання); алгоритм 
обробки замовлень (забезпечує атомарність та інформованість користувача). 
4. Проведено системний аналіз та проєктування системи з використанням UML-
нотацій: визначено словник предметної області (11 термінів), три актори та 19 
варіантів використання (Use Cases); розроблено PIM-модель (12 сутностей, 15 
зв'язків) та PSM-модель; змодельовано динамічну поведінку через діаграми 
 
80 
послідовності для трьох ключових бізнес-процесів та діаграму станів життєвого 
циклу аукціону. 
5. Практично реалізовано систему NumisMarket з використанням обраного 
технологічного стеку: серверна частина на Node.js + Express.js + Prisma ORM (11 
контролерів, 12 маршрутів, 2 обробники Socket.IO); клієнтська частина на Next.js + 
React + Tailwind CSS (23 сторінки); база даних на PostgreSQL (12 моделей, 4 
переліки). Контрольні приклади підтвердили коректність реалізації всіх основних 
бізнес-процесів: аукціонної торгівлі з антиснайпінгом, AI-аналізу зображень монет та 
управління персональними колекціями. Всі сформульовані функціональні (8) та 
нефункціональні (6) вимоги виконано. 
Рекомендації. 
На підставі результатів проведеного дослідження та аналізу досвіду розробки й 
впровадження системи NumisMarket сформульовано наступні рекомендації щодо 
подальшого вдосконалення та впровадження системи. 
1. Інтеграція платіжних систем. Для повноцінного функціонування електронної 
комерції рекомендується інтегрувати платіжні системи (LiqPay, WayForPay, Stripe) 
для забезпечення онлайн-оплати замовлень, що дозволить Automatизувати процес 
оплати та зменшити частку оплат при отриманні. 
2. Розширення AI-можливостей. Рекомендується розширити функціональність 
AI-асистента шляхом: додавання можливості порівняння результатів аналізу з 
відомими каталогами (Krause, Sear) для верифікації результатів; впровадження 
механізму зворотного зв'язку користувачів для покращення якості промптів; 
реалізації локального AI-провайдера на основі Ollama для забезпечення 
конфіденційності даних та роботи без доступу до Інтернету. 
3. Оптимізація продуктивності. Рекомендується: впровадити кешування 
результатів запитів до каталогу товарів за допомогою Redis; реалізувати pagination за 
курсором (cursor-based) замість offset-based для каталогу з великою кількістю товарів; 
додати інтерсептор для стиснення відповідей API (gzip brotli) для зменшення обсягу 
переданих даних. 
 
81 
4. Розширення функціональності колекцій. Рекомендується додати можливість 
публічного доступу до колекцій користувачів (з їхньої згоди) з метою створення 
соціальної складової платформи; реалізувати систему категоризації та тегування 
записів колекції; впровадити статистичний аналіз колекції (загальна вартість, 
розподіл за країнами, роками тощо). 
5. Збільшення безпеки. Рекомендується: впровадити rate limiting для захисту від 
DDoS-атак та перебору; додати refresh-токени для безперервної автентифікації без 
повторного входу; реалізувати валідацію вхідних даних на стороні сервера за 
допомогою бібліотеки схем (наприклад, Zod) на додаток до клієнтської валідації; 
додати HTTPS для забезпечення шифрування трафіку між клієнтом та сервером. 
6. Мобільний доступ. Рекомендується розробити прогресивний веб-застосунок 
(PWA) або мобільний додаток для платформ iOS та Android, що дозволить збільшити 
аудиторію та забезпечити зручний доступ до аукціонів у реальному часі з мобільних 
пристроїв. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82 
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ 
1. Mordor Intelligence. Numismatic Coins Market - Size, Share & Growth Analysis, 
2023–2030. URL: https://www.mordorintelligence.com/industry-
reports/numismatic-coins-market (дата звернення: 15.01.2026). 
2. Нумізматика. URL:  
https://uk.wikipedia.org/wiki/%D0%9D%D1%83%D0%BC%D1%96%D0%B7%D
0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0 (дата звернення: 
15.01.2026). 
3. Гершаник Л.О. Оцінка та експертиза колекційних монет / Л.О. Гершаник, І.В. 
Дулінська. К. : УкрНДІ, 2020. 178 с. 
4. PostgreSQL Documentation. PostgreSQL 15 Official Documentation. URL: 
https://www.postgresql.org/docs/15/ (дата звернення: 20.01.2026). 
5. TypeScript. TypeScript: JavaScript That Scales. URL: 
https://www.typescriptlang.org/ (дата звернення: 20.01.2026). 
6. Express.js. Express - Fast, unopinionated, minimalist web framework for Node.js. 
URL: https://expressjs.com/ (дата звернення: 20.01.2026). 
7. Vercel. Next.js – The React Framework for the Web. URL: https://nextjs.org/ (дата 
звернення: 22.01.2026). 
8. Tailwind CSS. Tailwind CSS - Rapidly build modern websites without ever leaving 
your HTML. URL: https://tailwindcss.com/ (дата звернення: 22.01.2026). 
9. Axios. Axios - Promise based HTTP client for the browser and node.js. URL: 
https://axios-http.com/ (дата звернення: 22.01.2026). 
10. date-fns. date-fns - Modern JavaScript date utility library. URL: https://date-fns.org/ 
(дата звернення: 22.01.2026). 
11. Recharts. Recharts - A composable charting library built on React components. URL: 
https://recharts.org/ (дата звернення: 22.01.2026). 
12. Docker. Docker Documentation. URL: https://docs.docker.com/ (дата звернення: 
25.01.2026). 
 
83 
13. OpenAI. GPT-4V System Card. URL: https://openai.com/research/gpt-4v (дата 
звернення: 28.01.2026). 
14. Google. Gemini API Documentation. URL: https://ai.google.dev/docs (дата 
звернення: 28.01.2026). 
15. Ollama. Ollama - Run large language models locally. URL: https://ollama.ai/ (дата 
звернення: 28.01.2026). 
16. Кумар Р. Мультимодальні нейронні мережі для аналізу зображень / Р. Кумар, 
С. Прасад // International Journal of Computer Applications. 2022. Vol. 184, No. 1. 
P. 12-19. 
17. Самер Я. Використання великих мовних моделей в електронній комерції / Я. 
Самер, М. Хасан // Journal of Electronic Commerce Research. 2023. Vol. 24, No. 2. 
P. 145–168. 
18. Захаров Д. С. Розпізнавання монет на зображеннях методами згорткових 
нейромереж / Д. С. Захаров, О. В. Коваленко // Вісник Національного 
технічного університету «ХПІ». 2021. 
19. Браун Т. Zero-shot розпізнавання об'єктів з використанням мультимодальних 
великих мовних моделей / Т. Браун, Б. Маннінг // arXiv preprint arXiv : 
2306.04567. 2023. 
20. eBay. eBay - Electronics, Cars, Fashion, Collectibles & More. URL: 
https://www.ebay.com/ (дата звернення: 10.01.2026). 
21. Fees eBay. eBay Seller Fees. URL: https://www.ebay.com/help/selling/fees (дата 
звернення: 10.01.2026). 
22. VCoins. VCoins - The Ancient Coin Marketplace. URL: https://www.vcoins.com/ 
(дата звернення: 10.01.2026). 
23. MA-Shops. MA-Shops - Coins from trusted dealers. URL: https://www.ma-
shops.com/ (дата звернення: 10.01.2026). 
24. PCGS. Professional Coin Grading Service. URL: https://www.pcgs.com/ (дата 
звернення: 12.01.2026). 
25. NGC. Numismatic Guaranty Corporation. URL: https://www.ngccoin.com/ (дата 
звернення: 12.01.2026). 
 
84 
26. Лowe D.G. Distinctive Image Features from Scale-Invariant Keypoints / D.G. Lowe 
// International Journal of Computer Vision. 004. Vol. 60, No. 2. P. 91-110. 
27. He K. Deep Residual Learning for Image Recognition / K. He, X. Zhang, Sh. Ren, J. 
Sun // Proceedings of the IEEE Conference on Computer Vision and Pattern 
Recognition. 2016. P. 770-778. 
28. Тан М. EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks 
/ М. Тан, Q.V. Le // Proceedings of the 36th International Conference on Machine 
Learning. 2019. P. 6105-6114. 
29. Сенгупта A. Класифікація нумізматичних об'єктів за зображеннями з 
використанням глибинного навчання / A. Сенгупта, В. Кумар // Pattern 
Recognition Letters. 2021. Vol. 145. P. 142-150. 
30. Кісв М. Автоматична атрибуція історичних монет на основі комп'ютерного зору 
/ М. Кісв, Х. Мансур // Journal of Cultural Heritage. 2022. Vol. 53. P. 225-234. 
31. Prisma. Prisma - Next-generation ORM for Node.js & TypeScript. URL: 
https://www.prisma.io/ (дата звернення: 20.01.2026). 
32. Socket.IO. Socket.IO – Real-time bidirectional event-based communication. URL: 
https://socket.io/ (дата звернення: 22.01.2026). 
33. JSON Web Tokens. JWT.IO – JSON Web Tokens Introduction. URL: 
https://jwt.io/introduction (дата звернення: 18.01.2026). 
34. Catawiki. Catawiki - Online auction for special objects. URL: 
https://www.catawiki.com/ (дата звернення: 10.01.2026). 
35. Node.js. Node.js Documentation. URL: https://nodejs.org/en/docs (дата звернення: 
20.01.2026). 
36. React. React - A JavaScript library for building user interfaces. URL: 
https://react.dev/ (дата звернення: 22.01.2026). 
37. bcrypt. bcrypt - A library to help you hash passwords. URL: 
https://github.com/kelektiv/node.bcrypt.js (дата звернення: 18.01.2026). 
38. Multer. Multer - Node.js middleware for handling multipart/form-data. URL: 
https://github.com/expressjs/multer (дата звернення: 25.01.2026). 
 
85 
39. Lucide. Lucide – Beautiful & consistent icon toolkit. URL: https://lucide.dev/ (дата 
звернення: 22.01.2026). 
40. Пасічник В. В. Методи та засоби штучного інтелекту / В. В. Пасічник, В. С. 
Глушко. К. : Видавнича група BHV, 2019. 420 с. 
41. Теслюк О. Б. Проектування інформаційних систем / О. Б. Теслюк, В. М. 
Грушманс. Л. : Новий Світ, 2021. 315 с. 
42. Глушко В.С. Бази даних та інтелектуальний аналіз даних / В.С. Глушко. К. : 
Київський університет, 2020. 286 с. 
43. OLX Україна. OLX - сервіс оголошень України. URL: https://www.olx.ua/ (дата 
звернення: 10.01.2026). 
44. Міжнародна федерація нумізматів. Нумізматичні конвенції та стандарти. URL: 
https://www.inc-cin.org/ (дата звернення: 12.01.2026). 
45. Fowlkes C. A Survey of Internet Auction Systems / C. Fowlkes, D. Dorn // IEEE 
Internet Computing. 020. Vol. 24, No. 3. P. 52-61. 
46. RFC 7519. JSON Web Token (JWT). URL: https://tools.ietf.org/html/rfc7519 (дата 
звернення: 18.01.2026). 
47. Ferraiolo D. Role-Based Access Control / D. Ferraiolo, R. Sandhu, S. Gavrila, D.R. 
Richard // ACM Transactions on Information and System Security. 2001. Vol. 4, No. 
3. P. 224-274. 
48. Provos N. A Future-Adaptable Password Scheme / N. Provos, D. Mazières // 
Proceedings of the FREENIX Track: USENIX Annual Technical Conference. 1999. 
P. 81-91. 
49. Ковальчук А. М. Застосування темної теми в інтерфейсах електронної комерції 
/ А. М. Ковальчук // UI/UX Design Journal. 2023. Vol. 12, No. 2. P. 34-42. 
50. Андріанов В. В. Розгортання веб-застосунків з використанням контейнеризації 
/ В. В. Андріанов // Системи управління, навігації та зв'язку. 2022. Вип. 4(66). 
С. 45–53. 
 
 
 
 
86 
ДОДАТОК А 
 
Затверджую               
Зав. кафедри КНСА, 
______________ Юрій ТРИУС 
  «____»____________2026 р.    
 
 
 
 
 
ІНТЕРНЕТ-МАГАЗИН З ПРОДАЖУ НУМІЗМАТИЧНОЇ ПРОДУКЦІЇ  
Специфікація  
482. ЧДТУ. 62295-01 
 
  
Листів 2 
 
 
 
 
 
 
Розробник                          ____________________                Станіслав ФОМЕНКО 
 
Керівник                             ____________________                Петро ДЯЧЕНКО 
 
 
 
 
 
 
 
 
Черкаси – 2026 
 
87 
482. ЧДТУ. 62295-01 
Позначення Найменування Примітка 
   
   
 Документація  
   
   
 482. ЧДТУ. 62295-01    12 01 Текст програми  
 482. ЧДТУ. 62295-01    12 01 Лістинги ключових  
компонентів клієнтської 
частини веб-застосунку 
NumisMarket 
482. ЧДТУ. 62281-01   34 01 Інструкція користувача  
веб-застосунку 
NumisMarket 
482. ЧДТУ. 62281-01   90 01 Програма і методика  
випробувань 
 
   
   
   
   
   
   
   
   
   
   
   
 
 
88 
ДОДАТОК Б 
 
 
 
 
 
 
 
ІНТЕРНЕТ-МАГАЗИН З ПРОДАЖУ НУМІЗМАТИЧНОЇ ПРОДУКЦІЇ  
 
 
Текст програми 
482. ЧДТУ. 62295-01 12 01 
 
Листів 11 
 
 
 
 
 
 
Розробник                          ____________________                Станіслав ФОМЕНКО  
 
 
 
 
 
 
 
 
 
 
Черкаси 2026 р. 
 
 
89 
Лістинг основних компонентів серверної частини 
Нижче наведено лістинги основних компонентів серверної частини веб-
застосунку NumisMarket, які реалізують ключові бізнес-процеси: автентифікацію, 
управління аукціонами, колекціонування та інтеграцію AI. 
Лістинг Б.1 - Схема бази даних Prisma (фрагмент, основні моделі) 
generator client { 
  provider = "prisma-client-js" 
} 
  
datasource db { 
  provider = "postgresql" 
  url      = env("DATABASE_URL") 
} 
  
enum Role { 
  USER 
  SELLER 
  ADMIN 
} 
  
enum AuctionStatus { 
  PENDING 
  ACTIVE 
  COMPLETED 
  CANCELLED 
} 
  
enum Condition { 
  POOR 
  GOOD 
  VERY_GOOD 
  EXCELLENT 
  MINT 
} 
  
model User { 
  id        String   @id @default(uuid()) 
  email     String   @unique 
  password  String 
  name      String 
  role      Role     @default(USER) 
  avatar    String? 
  isBlocked Boolean  @default(false) 
  createdAt DateTime @default(now()) 
  updatedAt DateTime @updatedAt 
 
90 
  products  Product[] 
  bids      Bid[] 
  favorites Favorite[] 
  orders    Order[] 
  notifications Notification[] 
  sellerApplication SellerApplication? 
  sentMessages     Message[] @relation("SentMessages") 
  receivedMessages Message[] @relation("ReceivedMessages") 
  collectionItems  CollectionItem[] 
} 
  
model Product { 
  id          String    @id @default(uuid()) 
  title       String 
  description String 
  country     String 
  year        Int 
  material    String 
  rarity      String 
  condition   Condition 
  price       Decimal 
  images      String[] 
  sellerId    String 
  seller      User      @relation(fields: [sellerId], references: [id]) 
  categoryId  String 
  category    Category  @relation(fields: [categoryId], references: [id]) 
  isAuction   Boolean   @default(false) 
  auction     Auction? 
  favorites   Favorite[] 
  orderItem   OrderItem? 
  priceHistory PriceHistory[] 
  createdAt   DateTime  @default(now()) 
  updatedAt   DateTime  @updatedAt 
} 
  
model Auction { 
  id           String        @id @default(uuid()) 
  productId    String        @unique 
  product      Product       @relation(fields: [productId], references: [id]) 
  startPrice   Decimal 
  currentPrice Decimal 
  minStep      Decimal       @default(1.0) 
  startTime    DateTime      @default(now()) 
  endTime      DateTime 
  status       AuctionStatus @default(PENDING) 
  bids         Bid[] 
  createdAt    DateTime      @default(now()) 
  updatedAt    DateTime      @updatedAt 
} 
  
 
91 
model Bid { 
  id        String   @id @default(uuid()) 
  amount    Decimal 
  userId    String 
  user      User     @relation(fields: [userId], references: [id]) 
  auctionId String 
  auction   Auction  @relation(fields: [auctionId], references: [id]) 
  createdAt DateTime @default(now()) 
} 
  
model CollectionItem { 
  id          String    @id @default(uuid()) 
  userId      String 
  user        User      @relation(fields: [userId], references: [id], 
                                     onDelete: Cascade) 
  title       String 
  description String? 
  country     String? 
  year        Int? 
  material    String? 
  condition   Condition? 
  rarity      String? 
  images      String[] 
  notes       String? 
  createdAt   DateTime  @default(now()) 
  updatedAt   DateTime  @updatedAt 
} 
 
Лістинг Б.2 - Контролер аукціонів (auction.controller.ts) 
import { Request, Response } from "express"; 
import { prisma } from "../lib/prisma"; 
  
export const getAuctions = async (req: Request, res: Response) => { 
  try { 
    const status = req.query.status 
      ? String(req.query.status) : undefined; 
    const query: any = {}; 
    if (status) { 
      query.status = status; 
    } 
    const auctions = await prisma.auction.findMany({ 
      where: query, 
      include: { 
        product: true, 
        _count: { select: { bids: true } } 
      }, 
      orderBy: { endTime: "asc" } 
    }); 
    res.json(auctions); 
  } catch (error) { 
 
92 
    res.status(500).json({ message: "Server Error", error }); 
  } 
}; 
  
export const getAuctionById = async (req: Request, res: Response) => { 
  try { 
    const id = req.params.id; 
    if (typeof id !== 'string') { 
      return res.status(400).json({ message: "Invalid ID" }); 
    } 
    const auction = await prisma.auction.findUnique({ 
      where: { id }, 
      include: { 
        product: { 
          include: { seller: { select: { name: true, id: true } } } 
        }, 
        bids: { 
          include: { user: { select: { name: true } } }, 
          orderBy: { createdAt: "desc" }, 
          take: 50 
        } 
      } 
    }); 
    if (!auction) { 
      return res.status(404).json({ message: "Auction not found" }); 
    } 
    res.json(auction); 
  } catch (error) { 
    res.status(500).json({ message: "Server Error", error }); 
  } 
}; 
 
Лістинг Б.3 - Контролер колекцій (collection.controller.ts) 
import { Response } from 'express'; 
import { prisma } from '../lib/prisma'; 
import { AuthRequest } from '../middlewares/auth.middleware'; 
  
export const getCollection = async ( 
  req: AuthRequest, res: Response 
) => { 
  try { 
    const items = await prisma.collectionItem.findMany({ 
      where: { userId: req.user.id }, 
      orderBy: { createdAt: 'desc' } 
    }); 
    res.json(items); 
  } catch (error) { 
    console.error(error); 
    res.status(500).json({ message: 'Server error' }); 
  } 
 
93 
}; 
  
export const createCollectionItem = async ( 
  req: AuthRequest, res: Response 
) => { 
  try { 
    const { title, description, country, year, material, 
            condition, rarity, images, notes } = req.body; 
    if (!title || !images || images.length === 0) { 
      return res.status(400).json({ 
        message: 'Title and at least one image are required' 
      }); 
    } 
    const item = await prisma.collectionItem.create({ 
      data: { 
        userId: req.user.id, 
        title, 
        description: description || null, 
        country: country || null, 
        year: year ? parseInt(year) : null, 
        material: material || null, 
        condition: condition || null, 
        rarity: rarity || null, 
        images, 
        notes: notes || null 
      } 
    }); 
    res.status(201).json(item); 
  } catch (error) { 
    console.error(error); 
    res.status(500).json({ message: 'Server error' }); 
  } 
}; 
  
export const updateCollectionItem = async ( 
  req: AuthRequest, res: Response 
) => { 
  try { 
    const { id } = req.params as { id: string }; 
    const existing = await prisma.collectionItem.findFirst({ 
      where: { id, userId: req.user.id } 
    }); 
    if (!existing) { 
      return res.status(404).json({ message: 'Item not found' }); 
    } 
    const { title, description, country, year, material, 
            condition, rarity, images, notes } = req.body; 
    const item = await prisma.collectionItem.update({ 
      where: { id }, 
      data: { 
        ...(title !== undefined && { title }), 
 
94 
        ...(description !== undefined && { description }), 
        ...(country !== undefined && { country }), 
        ...(year !== undefined && { year: year ? parseInt(year) : null }), 
        ...(material !== undefined && { material }), 
        ...(condition !== undefined && { condition }), 
        ...(rarity !== undefined && { rarity }), 
        ...(images !== undefined && { images }), 
        ...(notes !== undefined && { notes }) 
      } 
    }); 
    res.json(item); 
  } catch (error) { 
    console.error(error); 
    res.status(500).json({ message: 'Server error' }); 
  } 
}; 
  
export const deleteCollectionItem = async ( 
  req: AuthRequest, res: Response 
) => { 
  try { 
    const { id } = req.params as { id: string }; 
    const existing = await prisma.collectionItem.findFirst({ 
      where: { id, userId: req.user.id } 
    }); 
    if (!existing) { 
      return res.status(404).json({ message: 'Item not found' }); 
    } 
    await prisma.collectionItem.delete({ where: { id } }); 
    res.json({ message: 'Item deleted' }); 
  } catch (error) { 
    console.error(error); 
    res.status(500).json({ message: 'Server error' }); 
  } 
}; 
 
Лістинг Б.4 - AI-провайдер Gemini (geminiProvider.ts) 
import { GoogleGenerativeAI } from '@google/generative-ai'; 
import { AIProvider, CoinAnalysisResult } from './aiService'; 
import { buildCoinAnalysisPrompt } from '../../prompts/coinAnalysis'; 
  
export class GeminiProvider implements AIProvider { 
  private model; 
  
  constructor() { 
    const apiKey = process.env.GEMINI_API_KEY; 
    if (!apiKey) { 
      throw new Error( 
        'GEMINI_API_KEY is not set in environment variables' 
 
95 
      ); 
    } 
    const genAI = new GoogleGenerativeAI(apiKey); 
    this.model = genAI.getGenerativeModel({ 
      model: 'gemini-3.1-flash-lite' 
    }); 
  } 
  
  async analyzeCoin( 
    images: Buffer[], 
    userHint?: string 
  ): Promise<CoinAnalysisResult> { 
    const imageParts = images.map((img) => ({ 
      inlineData: { 
        data: img.toString('base64'), 
        mimeType: 'image/jpeg' as const, 
      }, 
    })); 
  
    const prompt = buildCoinAnalysisPrompt(userHint); 
  
    const result = await this.model.generateContent([ 
      prompt, 
      ...imageParts, 
    ]); 
  
    const text = result.response.text(); 
    const jsonMatch = text.match(/\{[\s\S]*\}/); 
    if (!jsonMatch) { 
      console.error('Gemini raw response:', text); 
      throw new Error('AI did not return valid JSON'); 
    } 
  
    try { 
      const parsed = JSON.parse( 
        jsonMatch[0] 
      ) as CoinAnalysisResult; 
      return parsed; 
    } catch (parseError) { 
      console.error('JSON parse error. Raw text:', jsonMatch[0]); 
      throw new Error('Failed to parse AI response as JSON'); 
    } 
  } 
} 
 
Лістинг Б.5 - Middleware автентифікації (auth.middleware.ts) 
import { Request, Response, NextFunction } from 'express'; 
 
96 
import jwt from 'jsonwebtoken'; 
import { prisma } from '../lib/prisma'; 
  
export interface AuthRequest extends Request { 
  user?: any; 
  io?: any; 
} 
  
export const protect = async ( 
  req: AuthRequest, 
  res: Response, 
  next: NextFunction 
) => { 
  let token; 
  if ( 
    req.headers.authorization && 
    req.headers.authorization.startsWith('Bearer') 
  ) { 
    try { 
      token = req.headers.authorization.split(' ')[1]; 
      const decoded = jwt.verify( 
        token, 
        process.env.JWT_SECRET || 'secret' 
      ) as jwt.JwtPayload; 
  
      const user = await prisma.user.findUnique({ 
        where: { id: decoded.id }, 
        select: { id: true, email: true, name: true, role: true }, 
      }); 
  
      if (!user) { 
        return res.status(401).json({ message: 'User not found' }); 
      } 
      req.user = user; 
      next(); 
    } catch (error) { 
      console.error(error); 
      res.status(401).json({ 
        message: 'Not authorized, token failed' 
      }); 
    } 
  } 
  if (!token) { 
    res.status(401).json({ 
      message: 'Not authorized, no token' 
    }); 
  } 
}; 
  
 
97 
export const admin = ( 
  req: AuthRequest, res: Response, next: NextFunction 
) => { 
  if (req.user && req.user.role === 'ADMIN') { 
    next(); 
  } else { 
    res.status(403).json({ 
      message: 'Not authorized as an admin' 
    }); 
  } 
}; 
  
export const sellerOrAdmin = ( 
  req: AuthRequest, res: Response, next: NextFunction 
) => { 
  if (req.user && 
      (req.user.role === 'ADMIN' || 
       req.user.role === 'SELLER')) { 
    next(); 
  } else { 
    res.status(403).json({ 
      message: 'Not authorized as a seller or admin' 
    }); 
  } 
}; 
 
Лістинг Б.6 - Головний файл сервера (index.ts) 
import express from 'express'; 
import cors from 'cors'; 
import dotenv from 'dotenv'; 
import { createServer } from 'http'; 
import { Server } from 'socket.io'; 
import { setupAuctionSockets } from './sockets/auctionHandler'; 
import { setupMessageSockets } from './sockets/messageHandler'; 
import authRoutes from './routes/auth.routes'; 
import productRoutes from './routes/product.routes'; 
import auctionRoutes from './routes/auction.routes'; 
import userRoutes from './routes/user.routes'; 
import adminRoutes from './routes/admin.routes'; 
import sellerRoutes from './routes/seller.routes'; 
import orderRoutes from './routes/order.routes'; 
import uploadRoutes from './routes/upload.routes'; 
import aiRoutes from './routes/ai.routes'; 
import categoryRoutes from './routes/category.routes'; 
import messageRoutes from './routes/message.routes'; 
import collectionRoutes from './routes/collection.routes'; 
import path from 'path'; 
  
dotenv.config(); 
 
98 
  
const app = express(); 
const httpServer = createServer(app); 
const io = new Server(httpServer, { 
  cors: { 
    origin: process.env.CLIENT_URL || 'http://localhost:3000', 
    methods: ['GET','POST','PUT','DELETE','OPTIONS'] 
  } 
}); 
setupAuctionSockets(io); 
setupMessageSockets(io); 
  
app.use(cors()); 
app.use(express.json()); 
  
app.use((req: any, res, next) => { 
  req.io = io; 
  next(); 
}); 
  
app.use('/api/auth', authRoutes); 
app.use('/api/auctions', auctionRoutes); 
app.use('/api/products', productRoutes); 
app.use('/api/users', userRoutes); 
app.use('/api/admin', adminRoutes); 
app.use('/api/sellers', sellerRoutes); 
app.use('/api/orders', orderRoutes); 
app.use('/api/upload', uploadRoutes); 
app.use('/api/ai', aiRoutes); 
app.use('/api/categories', categoryRoutes); 
app.use('/api/messages', messageRoutes); 
app.use('/api/collections', collectionRoutes); 
  
app.use('/uploads', 
  express.static(path.join(__dirname, '../uploads'))); 
  
app.get('/api/health', (req, res) => { 
  res.status(200).json({ 
    status: 'ok', 
    message: 'NumisMarket API is running' 
  }); 
}); 
const PORT = process.env.PORT || 5000; 
httpServer.listen(PORT, () => { 
  console.log(`Server is running on port ${PORT}`); 
}); 
 
 
99 
ДОДАТОК В 
 
 
 
 
 
ІНТЕРНЕТ-МАГАЗИН З ПРОДАЖУ НУМІЗМАТИЧНОЇ ПРОДУКЦІЇ  
 
 
 
 
Лістинги ключових компонентів клієнтської частини веб-застосунку NumisMarket 
482. ЧДТУ. 62295-01 12 01 
Листів 7 
 
 
 
 
 
 
Розробник                          ____________________                Станіслав ФОМЕНКО 
 
 
 
 
 
 
 
 
 
 
 
 
 
Черкаси – 2026 
 
100 
Нижче наведено лістинги ключових компонентів клієнтської частини веб-
застосунку NumisMarket, що реалізують взаємодію з користувачем: аукціонна 
кімната з реальним часом, управління колекціями та AI-асистент. 
Лістинг В.1 - Сторінка аукціонної кімнати (auctions/[id]/page.tsx, фрагмент) 
"use client"; 
  
import { useState, useEffect, useRef } from "react"; 
import { useParams } from "next/navigation"; 
import api from "@/services/api"; 
import { io, Socket } from "socket.io-client"; 
  
export default function AuctionRoom() { 
  const { id } = useParams() as { id: string }; 
  const [auction, setAuction] = useState<any>(null); 
  const [loading, setLoading] = useState(true); 
  const [timeLeft, setTimeLeft] = useState(null); 
  const [bidAmount, setBidAmount] = useState(""); 
  const [bids, setBids] = useState<any[]>([]); 
  const socketRef = useRef<Socket | null>(null); 
  
  useEffect(() => { 
    fetchAuction(); 
    setupSocket(); 
    return () => { 
      if (socketRef.current) socketRef.current.disconnect(); 
    }; 
  }, [id]); 
  
  const fetchAuction = async () => { 
    try { 
      const res = await api.get(`/auctions/${id}`); 
      setAuction(res.data); 
      setBids(res.data.bids || []); 
      setBidAmount((Number(res.data.currentPrice) 
                    + Number(res.data.minStep)).toString()); 
    } catch (error) { 
      console.error(error); 
    } finally { 
      setLoading(false); 
    } 
  }; 
  
  const setupSocket = () => { 
    socketRef.current = io("http://localhost:5000"); 
    socketRef.current.on('connect', () => { 
      socketRef.current?.emit('joinAuction', id); 
 
101 
    }); 
    socketRef.current.on('bidUpdated', (data) => { 
      setAuction((prev) => ({ 
        ...prev, 
        currentPrice: data.currentPrice, 
        endTime: data.endTime, 
      })); 
      setBidAmount( 
        (Number(data.currentPrice) 
         + (auction?.minStep ? Number(auction.minStep) : 1) 
        ).toString() 
      ); 
      if (data.newBid) { 
        setBids((prev) => [data.newBid, ...prev]); 
      } 
    }); 
  }; 
  
  useEffect(() => { 
    if (!auction?.endTime) return; 
    const calculateTimeLeft = () => { 
      const end = new Date(auction.endTime).getTime(); 
      const now = new Date().getTime(); 
      const diff = end - now; 
      if (diff <= 0) { 
        setTimeLeft({ d:0, h:0, m:0, s:0 }); 
        return; 
      } 
      setTimeLeft({ 
        d: Math.floor(diff / (1000*60*60*24)), 
        h: Math.floor((diff / (1000*60*60)) % 24), 
        m: Math.floor((diff / 1000 / 60) % 60), 
        s: Math.floor((diff / 1000) % 60) 
      }); 
    }; 
    calculateTimeLeft(); 
    const interval = setInterval(calculateTimeLeft, 1000); 
    return () => clearInterval(interval); 
  }, [auction?.endTime, auction?.status]); 
  
  const placeBid = (e) => { 
    e.preventDefault(); 
    if (!socketRef.current) return; 
    const userId = "placeholder-user"; 
    socketRef.current.emit('placeBid', { 
      auctionId: id, 
      userId, 
      amount: bidAmount 
    }); 
  }; 
  
 
102 
  if (loading) return <div>Завантаження...</div>; 
  if (!auction) return <div>Аукціон не знайдено</div>; 
  
  const isFinished = timeLeft 
    && (timeLeft.d+timeLeft.h+timeLeft.m+timeLeft.s <= 0); 
  
  return ( 
    <div className="max-w-7xl mx-auto px-4 py-8"> 
      <div className="grid grid-cols-1 lg:grid-cols-3 gap-8"> 
        <div className="lg:col-span-2 space-y-8"> 
          <div className="bg-white/5 border border-white/10 rounded-3xl p-8"> 
            <h1 className="text-3xl font-bold mb-2"> 
              {auction.product.title} 
            </h1> 
            <p className="text-gray-400 mb-6"> 
              {auction.product.country}, {auction.product.year} 
            </p> 
            <p className="text-[var(--color-gold-400)] text-4xl font-bold"> 
              ${Number(auction.currentPrice).toFixed(2)} 
            </p> 
            {!isFinished && ( 
              <form onSubmit={placeBid} className="flex gap-4 mt-6"> 
                <input type="number" step={Number(auction.minStep)} 
                  min={Number(auction.currentPrice)+Number(auction.minStep)} 
                  value={bidAmount} 
                  onChange={(e)=>setBidAmount(e.target.value)} 
                  className="bg-zinc-900 border border-white/20 rounded-xl py-3 px-4 text-white" /> 
                <button type="submit" 
                  className="bg-[var(--color-gold-400)] text-zinc-900 font-bold px-8 py-3 rounded-xl"> 
                  Зробити ставку 
                </button> 
              </form> 
            )} 
          </div> 
        </div> 
        <div className="bg-zinc-900 border border-white/10 rounded-3xl p-6"> 
          <h3 className="text-xl font-bold text-white mb-4"> 
            Прямий ефір 
          </h3> 
          {bids.map((bid, i) => ( 
            <div key={bid.id || i} className="p-3 rounded-xl flex justify-between"> 
              <span>{bid.user?.name || "Анонім"}</span> 
              <span>${Number(bid.amount).toFixed(2)}</span> 
            </div> 
          ))} 
        </div> 
      </div> 
    </div> 
  ); 
} 
 
 
103 
Лістинг В.2 - Сторінка управління колекцією (collections/page.tsx, фрагмент) 
"use client"; 
  
import { useState, useEffect, useRef } from "react"; 
import api, { getImageUrl } from "@/services/api"; 
import { Plus, X, Upload, Loader2, Edit3, Trash2, 
         Camera, MapPin, Calendar, Coins } from "lucide-react"; 
  
export default function CollectionsPage() { 
  const [items, setItems] = useState([]); 
  const [loading, setLoading] = useState(true); 
  const [showModal, setShowModal] = useState(false); 
  const [editingItem, setEditingItem] = useState(null); 
  const [form, setForm] = useState({ 
    title: "", description: "", country: "", 
    year: "", material: "", condition: "", 
    rarity: "", notes: "" 
  }); 
  const [images, setImages] = useState([]); 
  const [previews, setPreviews] = useState([]); 
  const [existingImages, setExistingImages] = useState([]); 
  const [uploading, setUploading] = useState(false); 
  const [error, setError] = useState(""); 
  const fileInputRef = useRef(null); 
  
  const fetchItems = async () => { 
    try { 
      const res = await api.get("/collections"); 
      setItems(res.data); 
    } catch (err) { 
      console.error(err); 
    } finally { 
      setLoading(false); 
    } 
  }; 
  
  useEffect(() => { fetchItems(); }, []); 
  
  const uploadImages = async () => { 
    const urls = []; 
    for (const file of images) { 
      const formData = new FormData(); 
      formData.append("image", file); 
      const res = await api.post("/upload", formData); 
      const url = typeof res.data === "string" 
        ? res.data 
        : (res.data?.url || res.data?.imageUrl || ""); 
      if (url) urls.push(url); 
 
104 
    } 
    return urls; 
  }; 
  
  const handleSubmit = async () => { 
    if (!form.title.trim()) { 
      setError("Введіть назву монети"); return; 
    } 
    if (existingImages.length + images.length === 0) { 
      setError("Додайте хоча б одне фото"); return; 
    } 
    setUploading(true); 
    setError(""); 
    try { 
      const newUrls = await uploadImages(); 
      const allImages = [...existingImages, ...newUrls]; 
      const payload = { 
        ...form, 
        year: form.year ? parseInt(form.year) : null, 
        images: allImages, 
      }; 
      if (editingItem) { 
        await api.put(`/collections/${editingItem.id}`, payload); 
      } else { 
        await api.post("/collections", payload); 
      } 
      setShowModal(false); 
      resetForm(); 
      fetchItems(); 
    } catch (err) { 
      setError(err.response?.data?.message || "Помилка збереження"); 
    } finally { 
      setUploading(false); 
    } 
  }; 
  
  const handleDelete = async (id) => { 
    if (!confirm("Видалити цю монету з колекції?")) return; 
    await api.delete(`/collections/${id}`); 
    setItems((prev) => prev.filter((i) => i.id !== id)); 
  }; 
  
  return ( 
    <div> 
      <div className="flex justify-between items-center mb-8"> 
        <h1 className="text-2xl font-bold text-white">Моя колекція</h1> 
        <button onClick={() => { resetForm(); setShowModal(true); }} 
          className="px-5 py-3 rounded-xl bg-[var(--color-gold-400)] 
                     text-black font-semibold"> 
          <Plus className="w-5 h-5 inline" /> Додати монету 
 
105 
        </button> 
      </div> 
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> 
        {items.map((item) => ( 
          <div key={item.id} className="glass-card rounded-xl overflow-hidden"> 
            <div className="h-48 bg-black/50 relative cursor-pointer" 
                 onClick={() => openEditModal(item)}> 
              {item.images.length > 0 && ( 
                <img src={getImageUrl(item.images[0])} 
                     alt={item.title} className="w-full h-full object-cover" /> 
              )} 
              <div className="absolute top-2 right-2 flex gap-1 opacity-0 group-hover:opacity-100"> 
                <button onClick={(e) => { e.stopPropagation(); openEditModal(item); }} 
                  className="p-2 rounded-lg bg-black/70 text-white"> 
                  <Edit3 className="w-4 h-4" /> 
                </button> 
                <button onClick={(e) => { e.stopPropagation(); handleDelete(item.id); }} 
                  className="p-2 rounded-lg bg-black/70 text-white hover:bg-red-500"> 
                  <Trash2 className="w-4 h-4" /> 
                </button> 
              </div> 
            </div> 
            <div className="p-4"> 
              <h3 className="font-bold text-white">{item.title}</h3> 
              <div className="flex gap-2 text-xs mt-2"> 
                {item.country && <span>{item.country}</span>} 
                {item.year && <span>{item.year}</span>} 
                {item.material && <span>{item.material}</span>} 
              </div> 
            </div> 
          </div> 
        ))} 
      </div> 
      {/* Modal for add/edit omitted for brevity */} 
    </div> 
  ); 
} 
 
  
 
106 
ДОДАТОК Г 
 
 
 
 
 
ІНТЕРНЕТ-МАГАЗИН З ПРОДАЖУ НУМІЗМАТИЧНОЇ ПРОДУКЦІЇ  
 
 
 
 
Програма і методика випробувань 
482. ЧДТУ. 62295-01 90 01 
Листів 3 
 
 
 
 
 
 
Розробник                          ____________________                Станіслав ФОМЕНКО 
 
 
 
 
 
 
 
 
 
 
 
 
 
Черкаси – 2026 
 
107 
Специфікація REST API веб-застосунку NumisMarket 
Нижче наведено повний перелік маршрутів REST API серверної частини веб-
застосунку NumisMarket з указанням методу HTTP, шляху, рівня доступу та 
короткого опису функціональності. 
№ Метод Шлях Доступ Опис 
1 POST /api/auth/register Публічний Реєстрація нового 
користувача 
2 POST /api/auth/login Публічний Автентифікація 
користувача (отримання 
JWT) 
3 GET /api/auth/profile Авторизований Отримання профілю 
поточного користувача 
4 PUT /api/auth/profile Авторизований Оновлення профілю 
користувача 
5 GET /api/products Публічний Отримання списку товарів 
з фільтрацією 
6 GET /api/products/:id Публічний Отримання деталей товару 
за ID 
7 POST /api/products SELLER/ADMIN Створення нового товару 
8 PUT /api/products/:id SELLER/ADMIN Оновлення товару 
9 DELETE /api/products/:id SELLER/ADMIN Видалення товару 
10 GET /api/auctions Публічний Отримання списку 
аукціонів 
11 GET /api/auctions/:id Публічний Отримання деталей 
аукціону зі ставками 
12 POST /api/auctions SELLER/ADMIN Створення нового 
аукціону 
13 GET /api/categories Публічний Отримання списку 
категорій 
14 POST /api/categories ADMIN Створення нової категорії 
15 GET /api/users ADMIN Отримання списку 
користувачів 
 
108 
16 PUT /api/users/:id/block ADMIN Блокування/розблокування 
користувача 
17 PUT /api/users/:id/role ADMIN Зміна ролі користувача 
18 GET /api/orders Авторизований Отримання замовлень 
користувача 
19 POST /api/orders Авторизований Створення нового 
замовлення 
20 GET /api/orders/:id Авторизований Отримання деталей 
замовлення 
21 PUT /api/orders/:id/status SELLER/ADMIN Оновлення статусу 
замовлення 
22 GET /api/sellers/applications ADMIN Отримання заявок 
продавців 
23 POST /api/sellers/applications Авторизований Подання заявки на роль 
продавця 
24 PUT /api/sellers/applications/:id ADMIN Схвалення/відхилення 
заявки 
25 POST /api/upload SELLER/ADMIN Завантаження зображення 
на сервер 
26 POST /api/ai/analyze Авторизований AI-аналіз зображення 
монети 
27 GET /api/ai/history Авторизований Історія AI-аналізів 
користувача 
28 GET /api/messages Авторизований Отримання списку бесід 
29 POST /api/messages Авторизований Відправка повідомлення 
30 GET /api/messages/:userId Авторизований Отримання бесіди з 
користувачем 
31 GET /api/collections Авторизований Отримання елементів 
колекції 
32 GET /api/collections/:id Авторизований Отримання елемента 
колекції за ID 
33 POST /api/collections Авторизований Створення елемента 
колекції 
 
109 
34 PUT /api/collections/:id Авторизований Оновлення елемента 
колекції 
35 DELETE /api/collections/:id Авторизований Видалення елемента 
колекції 
36 GET /api/health Публічний Перевірка працездатності 
API 
  
 
110 
ДОДАТОК Д 
 
 
 
 
 
ІНТЕРНЕТ-МАГАЗИН З ПРОДАЖУ НУМІЗМАТИЧНОЇ ПРОДУКЦІЇ  
 
 
 
 
Iнструкцiя користувача веб-застосунку NumisMarket 
482. ЧДТУ. 62295-01 34 01 
Листів 3 
 
 
 
 
 
 
Розробник                          ____________________                Станіслав ФОМЕНКО 
 
 
 
 
 
 
 
 
 
 
 
 
 
Черкаси – 2026 
 
111 
Додаток містить інструкцію для користувача веб-застосунку NumisMarket –
нумізматичного інтернет-магазину з функціями аукціонної торгівлі, управління 
колекціями та AI-асистентом атрибуції монет. 
1. Реєстрація та вхід 
Для початку роботи з-web-застосунком необхідно створити обліковий запис. На 
головній сторінці натисніть кнопку «Зареєструватися». Уведіть адресу електронної 
пошти, ім'я та пароль (мінімум 6 символів). Після реєстрації Ви будете автоматично 
авторизовані. Для входу в подальшому використовуйте кнопку «Увійти» та введіть 
email і пароль. 
2. Перегляд каталогу товарів 
Каталог товарів доступний на сторінці «Каталог» у навігаційному меню. 
Сторінка відображає всі доступні монети у вигляді карток із зображенням, назвою, 
країною, роком та ціною. Доступна фільтрація за категорією, країною, матеріалом, 
станом та діапазоном ціни. Також працює пошук за назвою монети. Натисніть на 
картку для перегляду деталей товару. 
3. Участь в аукціоні 
Для участі в аукціоні перейдіть на сторінку «Аукціони». Виберіть активний 
аукціон і натисніть «Зробити ставку». Уведіть суму ставки (не менше поточної ціни 
+ мінімальний крок). Ставка відправляється через WebSocket у реальному часі. Якщо 
хтось інший зробить ставку, ви побачите оновлення миттєво. За 3 хвилини до 
завершення аукціону активується система анти-снайпінгу: кожна нова ставка 
подовжує час аукціону на 3 хвилини. 
4. AI-асистент атрибуції монет 
Перейдіть на сторінку «AI-асистент» у навігаційному меню. Завантажте 
фотографію монети (до 3 зображень у форматах JPEG, PNG або WebP). За бажанням 
додайте підказку - текстовий опис того, що ви знаєте про монету. Натисніть кнопку 
«Аналізувати». Штучний інтелект (Google Gemini) проаналізує зображення та 
надасть результат: ідентифікацію (назва, країна, рік, номінал, матеріал, номер за 
каталогом), оцінку стану (від POOR до MINT), опис, рідкість та рівень впевненості. 
5. Управління колекцією 
Перейдіть до розділу «Моя колекція» у профілі користувача. Натисніть кнопку 
«Додати монету». Заповніть поля: назва, країна, рік, матеріал, стан, рідкість, опис та 
 
112 
нотатки. Додайте до 5 фотографій монети. Натисніть «Додати до колекції». Для 
редагування натисніть іконку олівця на картці монети, для видалення – іконку 
кошика. 
6. Створення товару продавцем 
Для продажу монет необхідно мати роль «Продавець» (SELLER). Подайте 
заявку на сторінці «Стати продавцем» у профілі. Після схвалення адміністратором 
Вами стане доступною функція «Додати товар». Заповніть форму: назва, опис, країна, 
рік, матеріал, рідкість, стан, ціна, категорія та фотографії. При створенні товару 
відмітьте прапорець «Аукціон», щоб виставити товар на торги з вказанням стартової 
ціни та дати завершення. 
7. Оформлення замовлення 
Для придбання товару за фіксованою ціною додайте його до кошика та 
перейдіть до оформлення замовлення. Уведіть адресу доставки. Підтвердіть 
замовлення. Статус замовлення можна відстежувати в розділі «Мої замовлення» у 
профілі. 
8. Повідомлення 
Веб-застосунок підтримує обмін повідомленнями між користувачами. 
Перейдіть до розділу «Повідомлення» у профілі для перегляду бесід та відправки 
нових повідомлень. Повідомлення доставляються в реальному часі через WebSocket. 
9. Робота адміністратора 
Адміністратор має доступ до панелі управління з функціями: перегляд та 
блокування користувачів, зміна ролей, управління категоріями, розгляд заявок 
продавців та управління замовленнями. Панель доступна за маршрутом /admin для 
користувачів з роллю ADMIN. 
10. Системні вимоги 
Веб-застосунок працює в сучасних веб-браузерах (Chrome 90+, Firefox 88+, Safari 
14+, Edge 90+). Для повноцінної роботи необхідне підключення до Інтернету. 
Серверна частина розгорнута за допомогою Docker та вимагає Docker Compose для 
запуску всіх сервісів (PostgreSQL, backend, frontend).