Skip to content

Repository files navigation

📚 LibCode Library Console

Курсова робота (2 курс) — Java-версія

📖 Огляд

Цей проєкт — система автоматизації бібліотечного фонду, розроблена на мові програмування Java 17 з використанням бази даних PostgreSQL. Система забезпечує ефективне управління бібліотечними ресурсами: книгами, читачами, бібліотеками, бібліотекарями та статистикою відвідувань.

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

Консольний UI побудований на Lanterna — Java-аналозі бібліотеки ftxui, яку використовує оригінальна C++ версія цього проєкту: кольорові кнопки, рамки, прокручувані списки, навігація стрілками/Tab/Enter і повноцінний клік мишею.


🆕 Останні зміни

Пароль і логін БД винесено з коду в конфігурацію (db.properties / змінні середовища) — див. розділ ⚙️ Налаштування підключення до БД.

Раніше Main читав LIBRARY_DB_URL/LIBRARY_DB_USER/LIBRARY_DB_PASSWORD напряму зі змінних середовища зі значеннями за замовчуванням, прописаними прямо в коді. Тепер цим займається окремий клас com.libcode.library.config.DbConfig: він читає ті самі змінні середовища (для Docker — без змін), а якщо їх немає — локальний файл db.properties (шаблон — db.properties.example, сам файл у .gitignore, тож реальний пароль ніколи не потрапляє в репозиторій), і лише як останній fallback — вбудовані значення за замовчуванням.

Звіти (System Statistics / Query Results) більше не дублюються у файл — показуються тільки у власному вікні застосунку.

Раніше ExtendFeatures/PostgresOutput, окрім показу звіту у вікні, ще й записували той самий вміст у output.txt/statistics.txt "про всяк випадок" — жодна частина застосунку ці файли назад не читала, тож це було просто дублювання того, що й так видно на екрані. Метод IDBOutput.writeToFile() перейменовано на display(), файловий запис прибрано, output.txt/statistics.txt більше не створюються.

Звіти (System Statistics / Query Results) показуються у власному вікні застосунку, а не в зовнішньому текстовому редакторі.

Раніше ExtendFeatures/PostgresOutput записували результат у файл і намагалися відкрити його через SystemTextEditor (Notepad на Windows, java.awt.Desktop/системний редактор на Linux). У мінімальному Docker/noVNC-оточенні (Xvfb + fluxbox, без встановленого текстового редактора) це мовчки не спрацьовувало, а fallback друкував текст у справжній stdout процесу — невидимий у вікні noVNC. Тепер обидва місця малюють звіт напряму через новий com.libcode.library.ui.ReportWindow — те саме вікно Lanterna/Swing, що й решта UI, тож воно завжди видиме там, де видимий сам застосунок. Клас SystemTextEditor видалено як більше не потрібний.

Заразом виправлено дві незручності самого ReportWindow:

  • Прокрутка стрілками не працювала, якщо вміст не вміщався на екран: фокус за замовчуванням стояв на кнопці «Close», тож перше натискання стрілки просто перемикало фокус, а не гортало текст; після досягнення нижнього/верхнього краю тексту стрілка знову «з'їдала» фокус замість продовження прокрутки. Тепер фокус одразу на текстовому полі, а setVerticalFocusSwitching(false)/setHorizontalFocusSwitching(false) тримають фокус там незалежно від позиції каретки.
  • Enter не закривав вікно, якщо фокус був не на кнопці (а після виправлення вище — він за замовчуванням саме там): текстове поле в режимі read-only просто «з'їдало» Enter, нічого не роблячи. Тепер EnterEscape) закривають вікно глобально, незалежно від того, який компонент у фокусі (WindowListenerAdapter.onInput + setCloseWindowWithEscape(true)).

🛠 Технології

Назва Призначення
Java 17 Основна мова програмування
🐘 PostgreSQL Система управління базами даних
📦 Maven 3.8+ Збірка проєкту, залежності, тести, пакування
💻 IntelliJ IDEA Середовище розробки
🔄 Git Система керування версіями
🔗 PostgreSQL JDBC Драйвер для роботи з PostgreSQL — jdbc.postgresql.org
Lanterna Бібліотека для консольного UI — github.com/mabe02/lanterna
🧪 JUnit 5 + Mockito Модульне тестування
📦 jpackage Збірка нативного .exe (входить до JDK, з версії 14)

🐳 Запуск у Docker (найшвидший спосіб)

Не потрібно встановлювати ні PostgreSQL, ні JDK, ні Maven вручну — достатньо Docker. Застосунок має графічний (не текстовий) інтерфейс на Lanterna/Swing, тому контейнер піднімає віртуальний дисплей і віддає вікно програми в браузер через noVNC — працює однаково на Windows, macOS та Linux.

# Linux / macOS
./run.sh

# Windows
run.bat

Скрипт сам збере образи, підніме застосунок разом з БД (уже заповненою тестовими даними з data/library.sql) і відкриє http://localhost:6080/vnc.html у браузері — там і буде вікно програми.

Без скрипта — те саме вручну:

docker compose up --build

і відкрити http://localhost:6080/vnc.html вручну.

Детальніше про змінні середовища, скидання БД, розповсюдження образу без збірки на цільовій машині тощо — див. DOCKER.md.


🗄 Встановлення PostgreSQL

  1. Завантаж PostgreSQL з офіційного сайту: 👉 postgresql.org/download

  2. Під час встановлення запам'ятай пароль користувача postgres — він знадобиться далі.

  3. Переконайся, що bin-папка PostgreSQL (наприклад, C:\Program Files\PostgreSQL\16\bin) додана до системної змінної Path, щоб команди psql, createdb, pg_restore були доступні з будь-якої консолі.


🗃 Створення / відновлення бази даних

Є два способи підготувати базу: Варіант А створює порожню схему з нуля, Варіант Б відновлює з готового дампу.

Варіант А — чиста схема

createdb -U postgres library
psql -U postgres -d library -f schema.sql

Мінімальний набір таблиць (schema.sql), на якому побудовані всі запити проєкту:

CREATE TABLE users (
    id       SERIAL PRIMARY KEY,
    role     TEXT NOT NULL,
    login    TEXT NOT NULL UNIQUE,
    password TEXT NOT NULL
);

CREATE TABLE libraries (
    id       SERIAL PRIMARY KEY,
    name     TEXT NOT NULL,
    location TEXT
);

CREATE TABLE librarians (
    id   SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE work_schedule (
    id         SERIAL PRIMARY KEY,
    worker_id  INTEGER REFERENCES librarians(id),
    library_id INTEGER REFERENCES libraries(id),
    start_day  TEXT,
    end_day    TEXT,
    start_time TEXT,
    end_time   TEXT
);

CREATE TABLE authors (
    id   SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE books (
    id    SERIAL PRIMARY KEY,
    title TEXT NOT NULL
);

CREATE TABLE book_details (
    book_id   INTEGER PRIMARY KEY REFERENCES books(id),
    genre     TEXT,
    publisher TEXT,
    year      INTEGER,
    isbn      TEXT
);

CREATE TABLE book_authors (
    book_id   INTEGER REFERENCES books(id),
    author_id INTEGER REFERENCES authors(id),
    PRIMARY KEY (book_id, author_id)
);

CREATE TABLE categories (
    id            SERIAL PRIMARY KEY,
    category_type TEXT NOT NULL
);

CREATE TABLE readers (
    id      SERIAL PRIMARY KEY,
    name    TEXT NOT NULL,
    address TEXT,
    phone   TEXT
);

CREATE TABLE category_details (
    reader_id         INTEGER PRIMARY KEY REFERENCES readers(id),
    category_id       INTEGER REFERENCES categories(id),
    institution_name  TEXT,
    major             TEXT,
    school_number     TEXT,
    kindergarten_name TEXT,
    research_field    TEXT
);

CREATE TABLE visits (
    id         SERIAL PRIMARY KEY,
    reader_id  INTEGER REFERENCES readers(id),
    book_id    INTEGER REFERENCES books(id),
    library_id INTEGER REFERENCES libraries(id),
    visit_time TIMESTAMP NOT NULL DEFAULT now()
);

-- Обліковий запис адміністратора для першого входу:
INSERT INTO users (role, login, password) VALUES ('admin', 'admin', 'admin');

-- Хоча б одна бібліотека, щоб можна було зареєструвати бібліотекаря:
INSERT INTO libraries (name, location) VALUES ('Central Library', 'Main St 1');

Варіант Б — відновлення з дампу

# 1. Створити базу даних
createdb -U postgres library

# 2. Перейти до папки з дампом (вкажи свій шлях)
cd "D:\Download\libcode-java\database"

# 3a. Відновлення з текстового SQL-дампу
psql -U postgres -d "library" -f "library.sql"

# 3b. Відновлення з бінарного дампу (pg_dump --format=custom)
pg_restore -U postgres -d "library" -c "library.dump"

При виконанні команд система може запитати пароль користувача postgres. Після відновлення переконайся, що в users є хоча б один рядок з role = 'admin', а в libraries — хоча б один запис.


⚙️ Налаштування підключення до БД

На відміну від попередньої версії, пароль не зашивається в код: усе підключення до БД читає клас com.libcode.library.config.DbConfig, який шукає значення у трьох місцях за таким пріоритетом (перше знайдене — і використовується):

  1. Змінні середовища LIBRARY_DB_URL / LIBRARY_DB_USER / LIBRARY_DB_PASSWORD — саме їх встановлюють Dockerfile/docker-compose.yml, тож контейнерний запуск працює без жодних змін.
  2. Файл db.properties у робочій директорії застосунку (ключі db.url, db.user, db.password) — зручний спосіб налаштувати підключення локально, без запуску Docker і без експорту змінних середовища щоразу заново.
  3. Вбудовані значення за замовчуванням (ті самі, що й раніше) — використовуються, лише якщо не задано ні змінних середовища, ні db.properties.

Варіант 1 — файл db.properties (рекомендовано для локального запуску)

cp db.properties.example db.properties

і відредагувати значення під свою БД:

db.url=jdbc:postgresql://localhost:5432/library
db.user=postgres
db.password=твій_пароль

db.properties додано до .gitignore — реальний пароль ніколи не потрапить у git; у репозиторії лежить лише шаблон db.properties.example.

Варіант 2 — змінні середовища (як і раніше; пріоритетні над db.properties)

# PowerShell
$env:LIBRARY_DB_URL = "jdbc:postgresql://localhost:5432/library"
$env:LIBRARY_DB_USER = "postgres"
$env:LIBRARY_DB_PASSWORD = "твій_пароль"
# bash / zsh
export LIBRARY_DB_URL="jdbc:postgresql://localhost:5432/library"
export LIBRARY_DB_USER="postgres"
export LIBRARY_DB_PASSWORD="твій_пароль"

Якщо не задано ні змінних середовища, ні db.properties — застосунок підключається за вбудованими значеннями за замовчуванням (jdbc:postgresql://localhost:5432/library, postgres / admin1).


🚀 Збірка та запуск

Проєкт збирається Maven — жодних додаткових пакетних менеджерів (на кшталт vcpkg) не потрібно, усі залежності (Lanterna, PostgreSQL JDBC, JUnit, Mockito) підтягуються автоматично з Maven Central.

1. Клонування репозиторію

git clone https://github.com/VSCRM/Library.git
cd Library

2. Збірка виконуваного .jar

mvn clean package
java -jar target/library-console.jar

mvn package компілює код, прогонить весь набір тестів і (через maven-shade-plugin) створює єдиний самодостатній library-console.jar з уже вбудованим драйвером PostgreSQL — окремо налаштовувати classpath не потрібно.

3. Запуск тестів окремо

mvn test

Набір тестів (JUnit 5 + Mockito) перевіряє кожен клас через його публічний контракт — реальна база даних для запуску тестів не потрібна: усі виклики java.sql.* підмінені моками.

4. Збірка нативного .exe (Windows)

Окремий Maven-профіль exe одразу після пакування запускає jpackage, тож один командний рядок дає одразу і .jar, і .exe:

mvn clean package -Pexe

Результат — target\LibCodeLibraryConsole\LibCodeLibraryConsole.exe, який можна запускати напряму: цільова машина не потребує встановленої Java. Профіль вимагає повний JDK (не лише JRE) з jpackage на PATH — саме тому це окремий opt-in профіль, а не частина стандартної збірки: звичайний mvn package так само коректно працює на будь-якій платформі/CI.

ℹ️ .exe збирається без консольного вікна: увесь реальний інтерфейс застосунку малюється у власному Swing-вікні Lanterna (див. LanternaScreens), тож окрема консоль Windows не потрібна.

Ручний виклик jpackage (якщо потрібно кастомізувати прапорці):

mvn clean package
jpackage --input target --main-jar library-console.jar --main-class com.libcode.library.Main --name LibCodeLibraryConsole --type app-image --dest target

Замість --type app-image можна вказати --type msi або --type exe (потребує WiX Toolset) для отримання одного файла-інсталятора замість папки.

❓ Чому після mvn package немає простого .exe?

Це очікувано, а не пропущений крок: Java компілюється в байткод, а не в машинний код конкретної ОС/CPU, тож .jar виконується без змін на Windows/macOS/Linux, поки на машині є JVM. Саме тому стандартний спосіб поширення Java-застосунку — це .jar + java -jar .... Якщо потрібен саме нативний подвійним-кліком запускний файл для користувачів без Java — для цього і є jpackage (профіль exe вище).


🏗 Архітектура

Проєкт побудований на пошаровій архітектурі (UI → координація → бізнес-логіка → доступ до БД) і використовує наступні патерни проєктування:

Патерн Клас(и) Призначення
Singleton logging.Logger Єдина точка запису подій з таймстампом у log.txt
Proxy auth.AuthorizationProxyauth.Authorization Обмеження часу входу (07:00–16:00) перед делегуванням реальній перевірці
Abstract Factory interfaces.IDBFactory / db.PostgresFactory Створення пари пов'язаних об'єктів доступу до БД (з'єднання + вивід)
Facade ApplicationCoordinator.java Координація взаємодії між компонентами
Factory Method interfaces.IMenuCreator / menu.MenuCreator Динамічне створення AdminMenu або LibrarianMenu залежно від ролі
Decorator ui.ConsoleUtilsDecorator Стилізація консольного виведення без зміни базової реалізації
Adapter db.ResultAdapter Конвертація java.sql.ResultSet у формат IDBOutput

SOLID застосовано послідовно у всьому проєкті: кожен клас відповідає за одну задачу (SRP), нові ролі/меню/джерела даних додаються реалізацією інтерфейсу без зміни наявного коду (OCP), вузькі рольові інтерфейси (IBaseOperations, IAddOperations) замість одного великого (ISP), а всі залежності передаються через конструктор (DIP) — саме це і робить можливим тестування без реальної БД.


🗂 Структура проєкту

Повний перелік усіх файлів проєкту (кожна папка — за алфавітом: спершу підпапки, потім файли):

libcode-java/
├── data/                                          # DB — дампи бази даних, для відновлення
│   ├── library.dump
│   └── library.sql
├── docker/
│   └── entrypoint.sh                              # запуск Xvfb + fluxbox + x11vnc + noVNC + застосунку
├── src/
│   ├── main/java/com/libcode/library/
│   │   ├── app/                                   # Facade — координація застосунку
│   │   │   └── ApplicationCoordinator.java
│   │   ├── auth/                                  # Авторизація + Proxy обмеження часу
│   │   │   ├── Authorization.java
│   │   │   └── AuthorizationProxy.java
│   │   ├── config/                                # Налаштування підключення до БД
│   │   │   ├── DbConfig.java                      # пріоритет: env vars → db.properties → дефолти
│   │   │   └── DbCredentials.java
│   │   ├── db/                                    # Abstract Factory + Adapter для PostgreSQL
│   │   │   ├── PostgresConnection.java
│   │   │   ├── PostgresFactory.java
│   │   │   ├── PostgresOutput.java
│   │   │   └── ResultAdapter.java
│   │   ├── features/                              # Бізнес-логіка бібліотекаря/адміністратора
│   │   │   ├── ExtendFeatures.java
│   │   │   └── MainFeatures.java
│   │   ├── interfaces/                            # Усі контракти (I*.java)
│   │   │   ├── IAddOperations.java
│   │   │   ├── IApplicationCoordinator.java
│   │   │   ├── IAuthorization.java
│   │   │   ├── IBaseOperations.java
│   │   │   ├── IConsoleUtils.java
│   │   │   ├── IDBConnect.java
│   │   │   ├── IDBFactory.java
│   │   │   ├── IDBOutput.java
│   │   │   ├── IMenu.java
│   │   │   ├── IMenuCreator.java
│   │   │   ├── IUserContext.java
│   │   │   └── UserContextFactory.java
│   │   ├── logging/                               # Singleton — журналювання подій
│   │   │   └── Logger.java
│   │   ├── menu/                                  # Factory Method — меню за роллю
│   │   │   ├── AdminMenu.java
│   │   │   ├── LibrarianMenu.java
│   │   │   └── MenuCreator.java
│   │   ├── model/                                 # Дані, що передаються між шарами
│   │   │   ├── LoginCredentials.java
│   │   │   └── UserContext.java
│   │   ├── ui/                                    # Lanterna-інтерфейс + Decorator стилізації
│   │   │   ├── AnsiColors.java
│   │   │   ├── ConsoleTheme.java
│   │   │   ├── ConsoleUtils.java
│   │   │   ├── ConsoleUtilsDecorator.java
│   │   │   ├── EndOfInputException.java
│   │   │   ├── LanternaScreens.java               # спільне вікно + підтримка кліку/наведення мишею
│   │   │   ├── MarqueeListItemRenderer.java
│   │   │   ├── MarqueeTicker.java
│   │   │   └── ReportWindow.java                  # звіти/статистика — власне вікно замість зовнішнього редактора
│   │   ├── util/                                  # Спільні допоміжні класи
│   │   │   ├── ConsoleInputReader.java
│   │   │   ├── DropdownSelector.java
│   │   │   └── SqlTransactions.java
│   │   └── Main.java                              # точка входу (composition root)
│   └── test/java/com/libcode/library/
│       ├── app/
│       │   └── ApplicationCoordinatorTest.java
│       ├── auth/
│       │   ├── AuthorizationProxyTest.java
│       │   └── AuthorizationTest.java
│       ├── config/
│       │   └── DbConfigTest.java
│       ├── db/
│       │   ├── PostgresConnectionTest.java
│       │   ├── PostgresFactoryTest.java
│       │   ├── PostgresOutputTest.java
│       │   └── ResultAdapterTest.java
│       ├── features/
│       │   ├── ExtendFeaturesTest.java
│       │   ├── LanternaKeystrokes.java            # спільні хелпери для симуляції клавіш у тестах
│       │   └── MainFeaturesTest.java
│       ├── logging/
│       │   └── LoggerTest.java
│       ├── menu/
│       │   ├── AdminMenuTest.java
│       │   ├── LibrarianMenuTest.java
│       │   └── MenuCreatorTest.java
│       ├── model/
│       │   └── UserContextTest.java
│       ├── ui/
│       │   ├── ConsoleUtilsDecoratorTest.java
│       │   ├── ConsoleUtilsTest.java
│       │   ├── LanternaScreensTest.java           # математика піксель→комірка (клік/наведення мишею)
│       │   ├── MouseHoverSelectionTest.java       # виділення рухається за наведенням миші, як стрілками
│       │   └── ReportWindowTest.java              # фокус/скрол/Enter-Escape для вікна звітів
│       └── util/
│           └── ConsoleInputReaderTest.java
├── .dockerignore
├── .env.example                                   # шаблон змінних для docker-compose (LIBRARY_DB_*)
├── .gitignore
├── db.properties.example                          # шаблон локального db.properties (db.url/db.user/db.password)
├── docker-compose.yml                             # app + PostgreSQL, посів з data/library.sql
├── Dockerfile                                     # мультистейдж-збірка (Maven) + рантайм з noVNC
├── DOCKER.md                                      # інструкції з запуску в Docker
├── LICENSE
├── pom.xml
├── README.md
├── run.bat                                        # запуск у Docker + автовідкриття браузера (Windows)
└── run.sh                                         # запуск у Docker + автовідкриття браузера (Linux/macOS)

(target/, .idea/ та інші згенеровані/IDE-папки навмисно виключені, як і рантайм-файли log.txt/db.properties — див. .gitignore.)


📝 Функціонал

👤 Бібліотекар

  • Information about books — перелік усіх книг (назва, автор, жанр, видавництво, рік, ISBN) через JOIN таблиць book_details, book_authors, authors
  • Information about readers — перелік читачів та їхньої категорії (JOIN з category_details, categories)
  • Information about visits — історія відвідувань (JOIN visits, readers, libraries, books)
  • Most popular books — рейтинг книг за кількістю видач (GROUP BY + COUNT + ORDER BY)
  • Add book — додавання книги; автор створюється автоматично, якщо ще не існує; жанр/видавництво/рік/ISBN — необов'язкові
  • Add reader — додавання читача з категорією (школяр, студент, дошкільник, науковець), кожна з власним набором полів
  • Add visit — реєстрація видачі книги через випадаючі списки наявних читачів, бібліотек і книг
  • Exit — вихід із системи

🔧 Адміністратор

  • Information about libraries — перелік усіх бібліотек фонду
  • Information about librarians — перелік бібліотекарів з прив'язкою до бібліотеки та графіком роботи
  • Add user — створення облікового запису (логін, пароль, роль); для бібліотекаря додатково — ПІБ, бібліотека, графік роботи
  • System statistics — статистика по всіх таблицях + хвіст log.txt
  • Log out — вихід із системи

🖱 Консольний інтерфейс (Lanterna)

Увесь UI малюється в окремому Swing-вікні (аналог ftxui з C++ версії): кольорові рамки, кнопки, прокручувані списки. Вибір пункту меню чи кнопки роботить трьома рівноцінними способами:

  • стрілками ↑ / ↓ + Enter;
  • клавішею Tab для переходу між полями;
  • мишею — реалізовано власним мостом між реальними AWT-подіями миші та внутрішнім механізмом синтетичного вводу Lanterna (LanternaScreens.installMouseSupport), оскільки стандартний Swing-бекенд Lanterna сам по собі ні кліки, ні рух миші не генерує. Сірий фон поточного пункту тепер рухається за курсором під час наведення (mouseMovedMouseActionType.MOVE), а не тільки після кліку — так само, як він рухається стрілками; клік (mousePressed/mouseReleased) додатково одразу підтверджує вибір, як Enter.

Прокрутка колесом миші (наприклад, у ReportWindow) також підтримується, хоча Lanterna нативно її не має: LanternaScreens.injectWheelScroll транслює обертання колеса у повторні натискання стрілок (LanternaScreens.wheelScrollKeyPresses, покрито LanternaScreensTest) — звичайне колесо гортає вертикально (/), а Shift + колесо — горизонтально (/), за тим самим принципом, що й у браузерах та IDE.

⚙️ Системні можливості

  • Авторизація з розмежуванням прав доступу — роль (admin/librarian) визначається запитом до БД, і система формує відповідне меню
  • Обмеження часу доступу (Proxy) — вхід дозволений лише з 07:00 до 16:00; поза цим вікном спроба входу відхиляється й фіксується в журналі
  • JOIN-запити до БД — усі звітні розділи будуються на JOIN кількох пов'язаних таблиць
  • Автоматичне відображення результатів — вивід будь-якого звітного запиту одразу показується у власному вікні застосунку (ReportWindow, поверх Lanterna/Swing) — без залежності від зовнішнього текстового редактора, що особливо важливо в мінімальному Docker/noVNC-оточенні, де такого редактора просто немає; окремий файл на диску для цього більше не створюється (див. 🆕 Останні зміни)
  • Журналювання дій системи — усі ключові події фіксуються з таймстампом у log.txt через Singleton Logger
  • Транзакційні багатокрокові вставки — додавання книги/читача/бібліотекаря виконується в одній транзакції з відкатом при помилці
  • Розширюваність на інші СУБД — доступ до БД абстраговано через Abstract Factory (IDBFactory, IDBConnect, IDBOutput)

🧪 Тести

mvn test

Покриття: Logger (Singleton, потокобезпека), AuthorizationProxy (межі вікна 07:00–16:00), PostgresConnection (переходи стану з'єднання), ResultAdapter/PostgresOutput (конвертація, вирівняний показ звіту в ReportWindow через ін'єктований reportViewer), DbConfig (пріоритет змінних середовища над db.properties над вбудованими значеннями за замовчуванням), MenuCreator/AdminMenu/LibrarianMenu (маршрутизація за роллю), ApplicationCoordinator (повний цикл вхід → меню → вихід), MainFeatures/ExtendFeatures (SQL, транзакції, дропдауни, валідація вводу, показ статистики), ConsoleUtils (навігація стрілками/Tab/мишею через DefaultVirtualTerminal), ReportWindow (фокус стартує на тексті, а не на кнопці — прокрутка стрілками працює одразу; Enter/Escape закривають вікно незалежно від того, який компонент у фокусі; коректний fallback на консоль, якщо термінал узагалі не піднявся — ReportWindowTest), LanternaScreens (чиста математика перетворення піксель→комірка, що лежить в основі кліку й наведення мишею — LanternaScreensTest), а також окремий MouseHoverSelectionTest, що підтверджує на рівні самого Lanterna: подія наведення (MouseActionType.MOVE) переводить фокус і рухає виділення на пункт під курсором так само, як стрілки.


👤 Ролі користувачів

Роль Доступ
admin Бібліотеки, бібліотекарі, реєстрація користувачів, системна статистика
librarian Книги, читачі, відвідування, найпопулярніші книги, додавання нових записів

Вхід дозволений лише з 07:00 до 16:00 — навмисне обмеження (AuthorizationProxy), а не помилка застосунку.


👨‍💻 Автор

VSCRM

📜 Ліцензія

Цей проєкт ліцензовано під MIT License. Детальніше дивіться у файлі LICENSE.

About

Console-based library management system in Java 17 + PostgreSQL, with a mouse-and-keyboard-driven TUI built on Lanterna. Role-based access (admin/librarian), JOIN reporting, transactional inserts, logging, and JUnit 5/Mockito test coverage. Ships as both a runnable jar and a standalone Windows .exe (jpackage).

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages