hotel-backend/
├── config/
│   └── config.js
├── controllers/
│   ├── authController.js
│   ├── guestController.js
│   ├── paymentController.js
│   ├── reservationController.js
│   ├── reviewController.js
│   └── roomController.js
├── middleware/
│   └── authMiddleware.js
├── models/
│   ├── guest.js
│   ├── payment.js
│   ├── reservation.js
│   ├── review.js
│   ├── room.js
│   └── index.js
├── routes/
│   ├── auth.js
│   ├── guests.js
│   ├── payments.js
│   ├── reservations.js
│   ├── reviews.js
│   └── rooms.js
├── package.json
├── .env
└── server.js



config.js:
require('dotenv').config();

module.exports = {
  development: {
    username: process.env.DB_USERNAME ,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME ,
    host: process.env.DB_HOST ,
    port: process.env.DB_PORT,
    dialect: 'mysql2',
  }
};






// controllers/authController.js
const db = require('../models');
const Guest = db.Guests;
const jwt = require('jsonwebtoken');

// Регистрация гостя
exports.register = async (req, res) => {
  try {
    const { name, email, phone_number, password } = req.body;

    // Проверка наличия пользователя
    let guest = await Guest.findOne({ where: { email } });
    if (guest) {
      return res.status(400).json({ message: 'Пользователь с таким email уже существует' });
    }

    guest = await Guest.create({ name, email, phone_number, password });
    res.status(201).json({ message: 'Регистрация успешна' });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Вход гостя
exports.login = async (req, res) => {
  try {
    const { email, password } = req.body;

    const guest = await Guest.findOne({ where: { email } });
    if (!guest) {
      return res.status(400).json({ message: 'Неверный email или пароль' });
    }

    const isMatch = await guest.validPassword(password);
    if (!isMatch) {
      return res.status(400).json({ message: 'Неверный email или пароль' });
    }

    const payload = { id: guest.guest_id, name: guest.name, email: guest.email };
    const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1d' });

    res.json({ token });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};






// controllers/guestController.js
const db = require('../models');
const Guest = db.Guests;

// Получить профиль текущего гостя
exports.getProfile = async (req, res) => {
  try {
    const guest = await Guest.findByPk(req.user.id, {
      attributes: ['guest_id', 'name', 'email', 'phone_number', 'created_at'],
    });
    if (!guest) {
      return res.status(404).json({ message: 'Пользователь не найден' });
    }
    res.json(guest);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Обновить профиль гостя
exports.updateProfile = async (req, res) => {
  try {
    const { name, email, phone_number, password } = req.body;

    const guest = await Guest.findByPk(req.user.id);
    if (!guest) {
      return res.status(404).json({ message: 'Пользователь не найден' });
    }

    if (name) guest.name = name;
    if (email) guest.email = email;
    if (phone_number) guest.phone_number = phone_number;
    if (password) guest.password = password; // Хэшируется автоматически благодаря хуку

    await guest.save();
    res.json({ message: 'Профиль обновлен успешно' });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};





// controllers/paymentController.js
const db = require('../models');
const Payment = db.Payments;
const Reservation = db.Reservations;

// Создать платеж
exports.createPayment = async (req, res) => {
  const { reservation_id, amount, payment_date } = req.body;

  try {
    const reservation = await Reservation.findOne({
      where: { reservation_id, guest_id: req.user.id },
    });

    if (!reservation) {
      return res.status(404).json({ message: 'Бронирование не найдено' });
    }

    const payment = await Payment.create({
      reservation_id,
      amount,
      payment_date,
    });

    res.status(201).json({ message: 'Платеж успешно создан', payment });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Получить все платежи текущего гостя
exports.getUserPayments = async (req, res) => {
  try {
    const reservations = await Reservation.findAll({
      where: { guest_id: req.user.id },
      include: [{ model: Payment }],
    });

    const payments = reservations.flatMap(reservation => reservation.Payments);

    res.json(payments);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};






// controllers/reservationController.js
const db = require('../models');
const Reservation = db.Reservations;
const Room = db.Rooms;

// Создать бронирование
exports.createReservation = async (req, res) => {
  const { room_id, check_in_date, check_out_date } = req.body;

  if (new Date(check_in_date) >= new Date(check_out_date)) {
    return res.status(400).json({ message: 'Дата выезда должна быть позже даты заезда' });
  }

  try {
    const room = await Room.findByPk(room_id);
    if (!room) {
      return res.status(404).json({ message: 'Комната не найдена' });
    }

    if (room.status !== 'доступен') {
      return res.status(400).json({ message: 'Комната недоступна для бронирования' });
    }

    // Создаем бронирование
    const reservation = await Reservation.create({
      guest_id: req.user.id,
      room_id,
      check_in_date,
      check_out_date,
      // total_cost будет рассчитана триггером в базе данных
    });

    // Обновляем статус комнаты
    room.status = 'занят';
    await room.save();

    res.status(201).json({ message: 'Бронирование создано', reservation });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Получить все бронирования текущего гостя
exports.getUserReservations = async (req, res) => {
  try {
    const reservations = await Reservation.findAll({
      where: { guest_id: req.user.id },
      include: [{ model: Room }],
    });
    res.json(reservations);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Отменить бронирование
exports.cancelReservation = async (req, res) => {
  try {
    const reservation = await Reservation.findOne({
      where: { reservation_id: req.params.id, guest_id: req.user.id },
    });

    if (!reservation) {
      return res.status(404).json({ message: 'Бронирование не найдено' });
    }

    const room = await Room.findByPk(reservation.room_id);
    await reservation.destroy();

    // Обновляем статус комнаты
    if (room) {
      room.status = 'доступен';
      await room.save();
    }

    res.json({ message: 'Бронирование отменено' });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};







// controllers/reviewController.js
const db = require('../models');
const Review = db.Reviews;
const Room = db.Rooms;

// Создать отзыв
exports.createReview = async (req, res) => {
  const { room_id, review_text, rating } = req.body;

  if (!rating || rating < 1 || rating > 5) {
    return res.status(400).json({ message: 'Рейтинг должен быть от 1 до 5' });
  }

  try {
    const room = await Room.findByPk(room_id);
    if (!room) {
      return res.status(404).json({ message: 'Комната не найдена' });
    }

    const review = await Review.create({
      guest_id: req.user.id,
      room_id,
      review_text,
      rating,
    });

    res.status(201).json({ message: 'Отзыв создан', review });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Получить все отзывы
exports.getAllReviews = async (req, res) => {
  try {
    const reviews = await Review.findAll({
      include: [
        { model: db.Guests, attributes: ['name'] },
        { model: Room, attributes: ['room_number'] },
      ],
    });
    res.json(reviews);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Получить отзывы по комнате
exports.getReviewsByRoom = async (req, res) => {
  const { room_id } = req.params;

  try {
    const reviews = await Review.findAll({
      where: { room_id },
      include: [{ model: db.Guests, attributes: ['name'] }],
    });
    res.json(reviews);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};







// controllers/roomController.js
const db = require('../models');
const Room = db.Rooms;

// Получить все комнаты
exports.getAllRooms = async (req, res) => {
  try {
    const rooms = await Room.findAll();
    res.json(rooms);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};

// Получить комнату по ID
exports.getRoomById = async (req, res) => {
  try {
    const room = await Room.findByPk(req.params.id);
    if (!room) {
      return res.status(404).json({ message: 'Комната не найдена' });
    }
    res.json(room);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Внутренняя ошибка сервера' });
  }
};







// middleware/authMiddleware.js
const jwt = require('jsonwebtoken');

module.exports = (req, res, next) => {
  // Получить токен из заголовка Authorization
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Ожидаем формат "Bearer TOKEN"

  if (!token) {
    return res.status(401).json({ message: 'Доступ запрещен, токен не предоставлен' });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded; // Добавить информацию о пользователе в запрос
    next();
  } catch (error) {
    console.error(error);
    res.status(403).json({ message: 'Неверный токен' });
  }
};







// models/guest.js
const bcrypt = require('bcryptjs');

module.exports = (sequelize, DataTypes) => {
  const Guest = sequelize.define('Guest', {
    guest_id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    name: {
      type: DataTypes.STRING(100),
      allowNull: false,
    },
    email: {
      type: DataTypes.STRING(100),
      unique: true,
      allowNull: false,
      validate: {
        isEmail: true,
      },
    },
    phone_number: {
      type: DataTypes.STRING(15),
      unique: true,
      allowNull: false,
    },
    password: {
      type: DataTypes.STRING(255),
      allowNull: false,
    },
    created_at: {
      type: DataTypes.DATE,
      defaultValue: DataTypes.NOW,
    },
  }, {
    tableName: 'Guests',
    timestamps: false,
  });

  // Хук для хеширования пароля перед сохранением
  Guest.beforeCreate(async (guest, options) => {
    const salt = await bcrypt.genSalt(10);
    guest.password = await bcrypt.hash(guest.password, salt);
  });

  // Метод для проверки пароля
  Guest.prototype.validPassword = async function(password) {
    return await bcrypt.compare(password, this.password);
  };

  return Guest;
};









// models/index.js
const { Sequelize } = require('sequelize');
const config = require('../config/config').development;

const sequelize = new Sequelize(
  config.database,
  config.username,
  config.password,
  {
    host: config.host,
    dialect: config.dialect,
    logging: false, // Отключить логи SQL запросов
  }
);

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

// Импорт моделей
db.Guests = require('./guest')(sequelize, Sequelize);
db.Rooms = require('./room')(sequelize, Sequelize);
db.Reservations = require('./reservation')(sequelize, Sequelize);
db.Payments = require('./payment')(sequelize, Sequelize);
db.Reviews = require('./review')(sequelize, Sequelize);

// Определение ассоциаций

// Гость имеет много бронирований
db.Guests.hasMany(db.Reservations, { foreignKey: 'guest_id', onDelete: 'CASCADE' });
db.Reservations.belongsTo(db.Guests, { foreignKey: 'guest_id' });

// Комната имеет много бронирований
db.Rooms.hasMany(db.Reservations, { foreignKey: 'room_id', onDelete: 'CASCADE' });
db.Reservations.belongsTo(db.Rooms, { foreignKey: 'room_id' });

// Бронирование имеет много платежей
db.Reservations.hasMany(db.Payments, { foreignKey: 'reservation_id', onDelete: 'CASCADE' });
db.Payments.belongsTo(db.Reservations, { foreignKey: 'reservation_id' });

// Гость оставляет много отзывов
db.Guests.hasMany(db.Reviews, { foreignKey: 'guest_id', onDelete: 'SET NULL' });
db.Reviews.belongsTo(db.Guests, { foreignKey: 'guest_id' });

// Комната имеет много отзывов
db.Rooms.hasMany(db.Reviews, { foreignKey: 'room_id', onDelete: 'SET NULL' });
db.Reviews.belongsTo(db.Rooms, { foreignKey: 'room_id' });

module.exports = db;






// models/payment.js
module.exports = (sequelize, DataTypes) => {
    const Payment = sequelize.define('Payment', {
      payment_id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      reservation_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      amount: {
        type: DataTypes.DECIMAL(10, 2),
        allowNull: false,
      },
      payment_date: {
        type: DataTypes.DATEONLY,
        allowNull: false,
      },
    }, {
      tableName: 'Payments',
      timestamps: false,
    });
  
    return Payment;
  };







// models/reservation.js
module.exports = (sequelize, DataTypes) => {
    const Reservation = sequelize.define('Reservation', {
      reservation_id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      guest_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      room_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      check_in_date: {
        type: DataTypes.DATEONLY,
        allowNull: false,
      },
      check_out_date: {
        type: DataTypes.DATEONLY,
        allowNull: false,
      },
      total_cost: {
        type: DataTypes.DECIMAL(10, 2),
        allowNull: true,
      },
    }, {
      tableName: 'Reservations',
      timestamps: false,
    });
  
    return Reservation;
  };










// models/review.js
module.exports = (sequelize, DataTypes) => {
    const Review = sequelize.define('Review', {
      review_id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      guest_id: {
        type: DataTypes.INTEGER,
        allowNull: true,
      },
      room_id: {
        type: DataTypes.INTEGER,
        allowNull: true,
      },
      review_text: {
        type: DataTypes.TEXT,
        allowNull: false,
      },
      rating: {
        type: DataTypes.TINYINT,
        validate: {
          min: 1,
          max: 5,
        },
      },
      review_date: {
        type: DataTypes.DATE,
        defaultValue: DataTypes.NOW,
      },
    }, {
      tableName: 'Reviews',
      timestamps: false,
    });
  
    return Review;
  };










// models/room.js
module.exports = (sequelize, DataTypes) => {
    const Room = sequelize.define('Room', {
      room_id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      room_number: {
        type: DataTypes.STRING(10),
        unique: true,
        allowNull: false,
      },
      room_type: {
        type: DataTypes.ENUM('стандартный', 'улучшенный', 'люкс'),
        defaultValue: 'стандартный',
      },
      capacity: {
        type: DataTypes.TINYINT,
        allowNull: false,
      },
      price_per_night: {
        type: DataTypes.DECIMAL(10, 2),
        allowNull: false,
      },
      status: {
        type: DataTypes.ENUM('доступен', 'занят'),
        defaultValue: 'доступен',
      },
    }, {
      tableName: 'Rooms',
      timestamps: false,
    });
  
    return Room;
  };











// routes/auth.js
const express = require('express');
const router = express.Router();
const authController = require('../controllers/authController');

// Регистрация
router.post('/register', authController.register);

// Вход
router.post('/login', authController.login);

module.exports = router;









// routes/guests.js
const express = require('express');
const router = express.Router();
const guestController = require('../controllers/guestController');
const authMiddleware = require('../middleware/authMiddleware');

// Получить информацию о текущем госте
router.get('/profile', authMiddleware, guestController.getProfile);

// Обновить информацию гостя
router.put('/profile', authMiddleware, guestController.updateProfile);

module.exports = router;







// routes/payments.js
const express = require('express');
const router = express.Router();
const paymentController = require('../controllers/paymentController');
const authMiddleware = require('../middleware/authMiddleware');

// Создать платеж
router.post('/', authMiddleware, paymentController.createPayment);

// Получить все платежи текущего гостя
router.get('/', authMiddleware, paymentController.getUserPayments);

module.exports = router;









// routes/reservations.js
const express = require('express');
const router = express.Router();
const reservationController = require('../controllers/reservationController');
const authMiddleware = require('../middleware/authMiddleware');

// Создать бронирование
router.post('/', authMiddleware, reservationController.createReservation);

// Получить все бронирования текущего гостя
router.get('/', authMiddleware, reservationController.getUserReservations);

// Отменить бронирование
router.delete('/:id', authMiddleware, reservationController.cancelReservation);

module.exports = router;








// routes/reviews.js
const express = require('express');
const router = express.Router();
const reviewController = require('../controllers/reviewController');
const authMiddleware = require('../middleware/authMiddleware');

// Создать отзыв
router.post('/', authMiddleware, reviewController.createReview);

// Получить все отзывы
router.get('/', reviewController.getAllReviews);

// Получить отзывы по комнате
router.get('/room/:room_id', reviewController.getReviewsByRoom);

module.exports = router;














// routes/rooms.js
const express = require('express');
const router = express.Router();
const roomController = require('../controllers/roomController');
const authMiddleware = require('../middleware/authMiddleware');

// Получить все комнаты
router.get('/', roomController.getAllRooms);

// Получить конкретную комнату
router.get('/:id', roomController.getRoomById);

module.exports = router;










DB_USERNAME=root
DB_PASSWORD=1369sukAnigghaD1ck
DB_NAME=hotel
DB_HOST=localhost
DB_PORT=1369
PORT=8000














// server.js
const express = require('express');
const app = express();
const db = require('./models');
const dotenv = require('dotenv');
dotenv.config();

// Middleware
app.use(express.json());

// Роуты
const authRoutes = require('./routes/auth');
const guestRoutes = require('./routes/guests');
const roomRoutes = require('./routes/rooms');
const reservationRoutes = require('./routes/reservations');
const paymentRoutes = require('./routes/payments');
const reviewRoutes = require('./routes/reviews');

app.use('/api/auth', authRoutes);
app.use('/api/guests', guestRoutes);
app.use('/api/rooms', roomRoutes);
app.use('/api/reservations', reservationRoutes);
app.use('/api/payments', paymentRoutes);
app.use('/api/reviews', reviewRoutes);

// Тестовый маршрут
app.get('/', (req, res) => {
  res.send('API для гостиничного приложения работает');
});

// Синхронизация базы данных и запуск сервера
const PORT = process.env.PORT || 8000;

db.sequelize.sync({ alter: true }) // Используйте { force: true } для сброса БД (разработке)
  .then(() => {
    console.log('База данных синхронизирована');
    app.listen(PORT, () => {
      console.log(`Сервер запущен на порту ${PORT}`);
    });
  })
  .catch(err => {
    console.error('Ошибка синхронизации базы данных:', err);
  });
















База данных mysql:
CREATE DATABASE `hotel`;
USE hotel;

-- Таблица Guests (Гости)
CREATE TABLE Guests (
    guest_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    phone_number VARCHAR(15) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Таблица Rooms (Номера)
CREATE TABLE Rooms (
    room_id INT AUTO_INCREMENT PRIMARY KEY,
    room_number VARCHAR(10) UNIQUE NOT NULL,
    room_type ENUM('стандартный', 'улучшенный', 'люкс') DEFAULT 'стандартный',
    capacity TINYINT NOT NULL,
    price_per_night DECIMAL(10, 2) NOT NULL,
    status ENUM('доступен', 'занят') DEFAULT 'доступен'
);

-- Таблица Reservations (Бронирования)
CREATE TABLE Reservations (
    reservation_id INT AUTO_INCREMENT PRIMARY KEY,
    guest_id INT,
    room_id INT,
    check_in_date DATE NOT NULL,
    check_out_date DATE NOT NULL,
    total_cost DECIMAL(10, 2),
    FOREIGN KEY (guest_id) REFERENCES Guests(guest_id) ON DELETE CASCADE,
    FOREIGN KEY (room_id) REFERENCES Rooms(room_id) ON DELETE CASCADE
);

-- Таблица Payments (Оплаты)
CREATE TABLE Payments (
    payment_id INT AUTO_INCREMENT PRIMARY KEY,
    reservation_id INT,
    amount DECIMAL(10, 2) NOT NULL,
    payment_date DATE NOT NULL,
    FOREIGN KEY (reservation_id) REFERENCES Reservations(reservation_id) ON DELETE CASCADE
);

-- Таблица Reviews (Отзывы)
CREATE TABLE Reviews (
    review_id INT AUTO_INCREMENT PRIMARY KEY,
    guest_id INT,
    room_id INT,
    review_text TEXT NOT NULL,
    rating TINYINT CHECK (rating BETWEEN 1 AND 5),
    review_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (guest_id) REFERENCES Guests(guest_id) ON DELETE SET NULL,
    FOREIGN KEY (room_id) REFERENCES Rooms(room_id) ON DELETE SET NULL
);

-- Триггер для расчета общей стоимости бронирования
DELIMITER //
CREATE TRIGGER calc_total_cost
BEFORE INSERT ON Reservations
FOR EACH ROW
BEGIN
    DECLARE nights INT;
    DECLARE room_price DECIMAL(10, 2);

    SET nights = DATEDIFF(NEW.check_out_date, NEW.check_in_date);
    SELECT price_per_night INTO room_price FROM Rooms WHERE room_id = NEW.room_id;
    
    SET NEW.total_cost = nights * room_price;
END//
DELIMITER ;

-- Триггер для обновления статуса комнаты при бронировании
DELIMITER //
CREATE TRIGGER update_room_status
AFTER INSERT ON Reservations
FOR EACH ROW
BEGIN
    UPDATE Rooms
    SET status = 'занят'
    WHERE room_id = NEW.room_id;
END//
DELIMITER ;

-- Триггер для освобождения комнаты при отмене бронирования
DELIMITER //
CREATE TRIGGER free_room_on_cancel
AFTER DELETE ON Reservations
FOR EACH ROW
BEGIN
    UPDATE Rooms
    SET status = 'доступен'
    WHERE room_id = OLD.room_id;
END//
DELIMITER ;







бэкенд почему то не запускается

npm start

> backend@1.0.0 start
> node server.js

Ошибка синхронизации базы данных: ConnectionError [SequelizeConnectionError]: Server requests authentication using unknown plugin auth_gssapi_client. See TODO: add plugins doco here on how to configure 
or author authentication plugins.
    at ConnectionManager.connect (D:\TRPO\hotel\backend\node_modules\sequelize\lib\dialects\mysql\connection-manager.js:102:17)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ConnectionManager._connect (D:\TRPO\hotel\backend\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:222:24)
    at async D:\TRPO\hotel\backend\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:174:32
    at async ConnectionManager.getConnection (D:\TRPO\hotel\backend\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:197:7)
    at async D:\TRPO\hotel\backend\node_modules\sequelize\lib\sequelize.js:305:26
    at async MySQLQueryInterface.tableExists (D:\TRPO\hotel\backend\node_modules\sequelize\lib\dialects\abstract\query-interface.js:102:17)
    at async Guest.sync (D:\TRPO\hotel\backend\node_modules\sequelize\lib\model.js:939:21)
    at async Sequelize.sync (D:\TRPO\hotel\backend\node_modules\sequelize\lib\sequelize.js:377:9) {  
  parent: Error: Server requests authentication using unknown plugin auth_gssapi_client. See TODO: add plugins doco here on how to configure or author authentication plugins.
      at Object.authSwitchRequest (D:\TRPO\hotel\backend\node_modules\mysql2\lib\commands\auth_switch.js:62:11)
      at ClientHandshake.handshakeResult (D:\TRPO\hotel\backend\node_modules\mysql2\lib\commands\client_handshake.js:194:22)
      at ClientHandshake.execute (D:\TRPO\hotel\backend\node_modules\mysql2\lib\commands\command.js:45:22)
      at Connection.handlePacket (D:\TRPO\hotel\backend\node_modules\mysql2\lib\connection.js:481:34)      at PacketParser.onPacket (D:\TRPO\hotel\backend\node_modules\mysql2\lib\connection.js:97:12)   
      at PacketParser.executeStart (D:\TRPO\hotel\backend\node_modules\mysql2\lib\packet_parser.js:75:16)
      at Socket.<anonymous> (D:\TRPO\hotel\backend\node_modules\mysql2\lib\connection.js:104:25)     
      at Socket.emit (node:events:514:28)
      at addChunk (node:internal/streams/readable:545:12)
      at readableAddChunkPushByteMode (node:internal/streams/readable:495:3) {
    code: 'AUTH_SWITCH_PLUGIN_ERROR',
    fatal: true
  },
  original: Error: Server requests authentication using unknown plugin auth_gssapi_client. See TODO: 
add plugins doco here on how to configure or author authentication plugins.
      at Object.authSwitchRequest (D:\TRPO\hotel\backend\node_modules\mysql2\lib\commands\auth_switch.js:62:11)
      at ClientHandshake.handshakeResult (D:\TRPO\hotel\backend\node_modules\mysql2\lib\commands\client_handshake.js:194:22)
      at ClientHandshake.execute (D:\TRPO\hotel\backend\node_modules\mysql2\lib\commands\command.js:45:22)
      at Connection.handlePacket (D:\TRPO\hotel\backend\node_modules\mysql2\lib\connection.js:481:34)      at PacketParser.onPacket (D:\TRPO\hotel\backend\node_modules\mysql2\lib\connection.js:97:12)   
      at PacketParser.executeStart (D:\TRPO\hotel\backend\node_modules\mysql2\lib\packet_parser.js:75:16)
      at Socket.<anonymous> (D:\TRPO\hotel\backend\node_modules\mysql2\lib\connection.js:104:25)     
      at Socket.emit (node:events:514:28)
      at addChunk (node:internal/streams/readable:545:12)
      at readableAddChunkPushByteMode (node:internal/streams/readable:495:3) {
    code: 'AUTH_SWITCH_PLUGIN_ERROR',
    fatal: true
  }
}