Реалізація інформаційного та програмного забезпечення ⭐
📝 SQL-скрипт для створення початкового наповнення бази даних
init.sql
CREATE TABLE `User` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(64),
`email` VARCHAR(128),
`password` VARCHAR(64),
`avatar` VARCHAR(128),
`status` VARCHAR(32)
);
CREATE TABLE `Member` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT,
`project_id` INT,
`role_id` INT
);
CREATE TABLE `Ban` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT,
`reason` TEXT,
`untilDate` DATETIME
);
CREATE TABLE `Settings` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT,
`key` VARCHAR(64),
`value` TEXT
);
CREATE TABLE `Role` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(32),
`description` TEXT
);
CREATE TABLE `Permission` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(64)
);
CREATE TABLE `Grant` (
`role_id` INT,
`permission_id` INT,
PRIMARY KEY (`role_id`, `permission_id`)
);
CREATE TABLE `Project` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(64),
`description` TEXT,
`creationDate` DATETIME,
`status` VARCHAR(32)
);
CREATE TABLE `Board` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(64),
`project_id` INT
);
CREATE TABLE `Block` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`project_id` INT,
`reason` TEXT,
`untilDate` DATETIME
);
CREATE TABLE `Task` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(64),
`description` TEXT,
`status` VARCHAR(32),
`startDate` DATE,
`dueDate` DATE,
`board_id` INT
);
CREATE TABLE `TaskComment` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`task_id` INT,
`author_id` INT,
`content` TEXT,
`creationDate` DATETIME
);
CREATE TABLE `Assignee` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`task_id` INT,
`user_id` INT
);
CREATE TABLE `Tag` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(32)
);
CREATE TABLE `TasksTag` (
`task_id` INT,
`tag_id` INT,
PRIMARY KEY (`task_id`, `tag_id`)
);
ALTER TABLE `Member` ADD FOREIGN KEY (`user_id`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Ban` ADD FOREIGN KEY (`user_id`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Settings` ADD FOREIGN KEY (`user_id`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `TaskComment` ADD FOREIGN KEY (`author_id`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Assignee` ADD FOREIGN KEY (`user_id`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Member` ADD FOREIGN KEY (`project_id`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Member` ADD FOREIGN KEY (`role_id`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Grant` ADD FOREIGN KEY (`role_id`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Grant` ADD FOREIGN KEY (`permission_id`) REFERENCES `Permission`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Board` ADD FOREIGN KEY (`project_id`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Block` ADD FOREIGN KEY (`project_id`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Task` ADD FOREIGN KEY (`board_id`) REFERENCES `Board`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `TaskComment` ADD FOREIGN KEY (`task_id`) REFERENCES `Task`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `Assignee` ADD FOREIGN KEY (`task_id`) REFERENCES `Task`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `TasksTag` ADD FOREIGN KEY (`task_id`) REFERENCES `Task`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `TasksTag` ADD FOREIGN KEY (`tag_id`) REFERENCES `Tag`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
seed.sql
BEGIN;
INSERT INTO `Permission` (`name`) VALUES
('CREATE_USER'),
('AUTHORIZE_USER'),
('EDIT_USER'),
('DELETE_USER'),
('CREATE_PROJECT'),
('EDIT_PROJECT'),
('DELETE_PROJECT'),
('ADD_USER_TO_PROJECT'),
('REMOVE_USER_FROM_PROJECT'),
('CREATE_BOARD'),
('DELETE_BOARD'),
('BAN_USER'),
('UNBAN_USER'),
('EDIT_SYSTEM_SETTINGS'),
('CREATE_TASK'),
('EDIT_TASK'),
('DELETE_TASK'),
('CREATE_COMMENT'),
('EDIT_COMMENT'),
('DELETE_COMMENT');
INSERT INTO `Role` (`name`, `description`) VALUES
('USER', 'Basic user access'),
('MANAGER', 'Project and team management'),
('ADMINISTRATOR', 'Full system access');
-- USER (role_id = 1)
INSERT INTO `Grant` (`role_id`, `permission_id`) VALUES
(1, 1), -- CREATE_USER
(1, 2), -- AUTHORIZE_USER
(1, 3), -- EDIT_USER
(1, 5), -- CREATE_PROJECT
(1, 6), -- EDIT_PROJECT
(1, 7); -- DELETE_PROJECT
-- MANAGER (role_id = 2)
INSERT INTO `Grant` (`role_id`, `permission_id`) VALUES
(2, 8), -- ADD_USER_TO_PROJECT
(2, 9), -- REMOVE_USER_FROM_PROJECT
(2, 10), -- CREATE_BOARD
(2, 11), -- DELETE_BOARD
(2, 15), -- CREATE_TASK
(2, 16), -- EDIT_TASK
(2, 17), -- DELETE_TASK
(2, 18), -- CREATE_COMMENT
(2, 19), -- EDIT_COMMENT
(2, 20); -- DELETE_COMMENT
-- ADMINISTRATOR (role_id = 3)
INSERT INTO `Grant` (`role_id`, `permission_id`) VALUES
(3, 4), -- DELETE_USER
(3, 6), -- EDIT_PROJECT
(3, 7), -- DELETE_PROJECT
(3, 8), -- ADD_USER_TO_PROJECT
(3, 9), -- REMOVE_USER_FROM_PROJECT
(3, 12), -- BAN_USER
(3, 13), -- UNBAN_USER
(3, 14); -- EDIT_SYSTEM_SETTINGS
INSERT INTO `User` (`name`, `email`, `password`, `avatar`, `status`) VALUES
('Ivan Shevchenko', 'ivan@example.com', 'hashed_pass_1', 'https://example.com/ivan.jpg', 'ACTIVE'),
('Olha Bondarenko', 'olha@example.com', 'hashed_pass_2', NULL, 'ACTIVE'),
('Taras Petrenko', 'taras@example.com', 'hashed_pass_3', 'https://example.com/taras.jpg', 'ACTIVE');
INSERT INTO `Project` (`name`, `description`, `creationDate`, `status`) VALUES
('Task Manager App', 'A simple task management system', NOW(), 'ACTIVE');
-- Assuming users 1, 2, 3; roles 1 = USER, 2 = MANAGER, 3 = ADMINISTRATOR
INSERT INTO `Member` (`user_id`, `project_id`, `role_id`) VALUES
(1, 1, 3), -- Admin
(2, 1, 2), -- Manager
(3, 1, 1); -- Regular user
INSERT INTO `Board` (`name`, `project_id`) VALUES
('Development', 1),
('Design', 1);
INSERT INTO `Task` (`name`, `description`, `status`, `startDate`, `dueDate`, `board_id`) VALUES
('Design Login Page', 'UI/UX for login', 'OPEN', '2025-05-01', '2025-05-10', 2),
('Implement Auth Logic', 'NodeJS backend', 'IN_PROGRESS', '2025-05-02', '2025-05-12', 1);
INSERT INTO `TaskComment` (`task_id`, `author_id`, `content`, `creationDate`) VALUES
(1, 2, 'Make sure to align with branding', NOW()),
(2, 3, 'Need help with backend routing', NOW());
INSERT INTO `Tag` (`name`) VALUES
('Urgent'),
('UI'),
('Backend');
INSERT INTO `TasksTag` (`task_id`, `tag_id`) VALUES
(1, 1),
(1, 2),
(2, 3);
INSERT INTO `Assignee` (`task_id`, `user_id`) VALUES
(1, 2),
(2, 3);
INSERT INTO `Ban` (`user_id`, `reason`, `untilDate`) VALUES
(3, 'Spamming comments', '2025-06-01 00:00:00');
INSERT INTO `Settings` (`user_id`, `key`, `value`) VALUES
(1, 'dark_mode', 'enabled'),
(2, 'email_notifications', 'true');
COMMIT;
🚀 RESTfull сервіс (JavaScript + Express.js)
.env
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=
DB_NAME=PLIFFDAX
💡 Файл для зберігання конфіденційних налаштувань (логін/пароль до бази даних, імʼя БД, хост тощо). Завдяки цьому твій код не містить паролів у відкритому доступі, і легко змінювати налаштування між різними середовищами (dev/prod).
src/app.js
const express = require('express');
const userRoutes = require('./routes/userRoutes');
const app = express();
app.use(express.json());
app.use('/users', userRoutes);
app.listen(3000, () => {
console.log('Server running on port 3000');
});
💡 Головний файл додатку. Тут відбувається підключення Express, підключення роутів, налаштування парсерів JSON і запуск сервера на певному порту.
src/db.js
const mysql = require('mysql2/promise');
require('dotenv').config();
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
});
module.exports = pool;
💡 Модуль для підключення до бази даних. Імпортує налаштування з
.env
і створює пул зʼєднань із MySQL, який можна використовувати у всіх інших модулях для виконання SQL-запитів.
src/models/userModel.js
const db = require('../db');
exports.create = async (name, email, password, avatar, status) => {
await db.query(
'INSERT INTO User (name, email, password, avatar, status) VALUES (?, ?, ?, ?, ?)',
[name, email, password, avatar || null, status || null]
);
};
exports.findAll = async () => {
const [rows] = await db.query('SELECT id, name, email, avatar, status FROM User');
return rows;
};
exports.findById = async (id) => {
const [rows] = await db.query('SELECT * FROM User WHERE id = ?', [id]);
return rows[0];
};
exports.update = async (id, fields) => {
const set = Object.keys(fields).map(key => `${key} = ?`).join(', ');
const values = [...Object.values(fields), id];
await db.query(`UPDATE User SET ${set} WHERE id = ?`, values);
};
exports.delete = async (id) => {
await db.query('DELETE FROM User WHERE id = ?', [id]);
};
💡 Модель роботи з даними користувачів (User). Тут описуються функції для звернення до БД: додавання, отримання, редагування, видалення користувачів. Вся взаємодія з таблицею
User
відбувається саме тут.
src/controllers/userController.js
const userModel = require('../models/userModel');
exports.create = async (req, res) => {
const { name, email, password, avatar, status } = req.body;
if (!name || !email || !password) {
return res.status(400).json({ error: 'Заповніть всі обовʼязкові поля (name, email, password)' });
}
await userModel.create(name, email, password, avatar, status);
res.status(201).json({ message: 'Користувача додано' });
};
exports.getAll = async (req, res) => {
const users = await userModel.findAll();
res.json(users);
};
exports.edit = async (req, res) => {
const { id } = req.params;
const { name, email, password, avatar, status } = req.body;
const fields = {};
if (name) fields.name = name;
if (email) fields.email = email;
if (password) fields.password = password;
if (avatar) fields.avatar = avatar;
if (status) fields.status = status;
if (!Object.keys(fields).length) {
return res.status(400).json({ error: 'Немає даних для оновлення' });
}
await userModel.update(id, fields);
res.json({ message: 'Користувача оновлено' });
};
exports.delete = async (req, res) => {
const { id } = req.params;
await userModel.delete(id);
res.json({ message: 'Користувача видалено' });
};
exports.getOne = async (req, res) => {
const user = await userModel.findById(req.params.id);
if (!user) return res.status(404).json({ error: 'UserNotFoundException' });
res.json(user);
};
💡 Контролер для обробки HTTP-запитів, повʼязаних із користувачами. Приймає дані з запиту, викликає відповідні функції моделі (
userModel
), обробляє відповіді й формує відповідь для клієнта (наприклад, успіх або помилку).
src/routes/userRoutes.js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
router.post('/', userController.create);
router.get('/', userController.getAll);
router.put('/:id', userController.edit);
router.delete('/:id', userController.delete);
router.get('/:id', userController.getOne);
module.exports = router;
💡 Файл, який описує маршрути (routes) для роботи з користувачами. Тут визначаються URL-адреси для різних дій (
GET
,POST
,PUT
,DELETE
), і кожен маршрут підключає відповідний метод з контролера. Підключається у головномуapp.js
.
☕️ Альтернативна реалізація: RESTful сервіс (Java + Spring Boot)
DB-RESTfull-service-on-Java — це репозиторій із прикладом створення сучасного RESTful API для роботи з базою даних на основі Java та фреймворка Spring Boot.
💡 Проєкт підготовлено для доповіді на тему: «Розроблення RESTful сервісу з доступом до бази даних мовою Java»
👨💻 Автори
- ІО-35 Степанов Олександр Олександрович
- ІО-35 Слюсар Олександр Андрійович
📬 Контакти