10 KiB
10 KiB
Hotel 777 - Система бронирования отеля
Общее описание
Hotel 777 — это веб-приложение для бронирования номеров в гостинице, расположенной на берегу моря в Абхазии (п. Мгудзырхуа, набережная ул. 1). Проект представляет собой полнофункциональную систему управления бронированиями с публичной частью для клиентов и административной панелью.
Технологический стек
- Backend: Node.js + Express 5.x
- База данных: SQLite3
- Аутентификация: JWT (jsonwebtoken) + bcryptjs
- Обработка изображений: Sharp (конвертация в WebP)
- Frontend: Bootstrap 5, Font Awesome, кастомные шрифты (Inter, Playfair Display)
- Контейнеризация: Docker + Docker Compose
Структура проекта
hotell777_260507/
├── server.js # Основной файл сервера (633 строки)
├── package.json # Зависимости проекта
├── Dockerfile # Сборка Docker образа
├── docker-compose.yml # Оркестрация контейнера
├── .env # Переменные окружения (только API_KEY)
├── .gitignore
├── PROJECT_INFO.md # Описание проекта
├── data/
│ └── bookings.db # База данных SQLite
├── public/
│ ├── index.html # Публичная страница
│ ├── admin.html # Админ-панель
│ ├── css/ # Стили (Bootstrap, шрифты, кастомные стили)
│ │ └── files/ # Шрифты Inter и Playfair Display
│ ├── js/
│ │ ├── main.js # Логика публичной части
│ │ └── bootstrap.bundle.min.js
│ ├── img/ # Изображения отеля и номеров
│ │ └── rooms/ # Фотографии номеров
│ └── webfonts/ # Шрифты Font Awesome
└── node_modules/
База данных
Таблицы:
-
bookings — бронирования
- Поля: id, name, phone, adults, children, checkin_date, checkout_date, wishes, status, room_type, comment, base_price, discount_percent, discount_amount, total_price, promocode_id, created_at
- Статусы: 'новая', 'оплачена', 'зарезервирована', 'заселена', 'выехала', 'отменена'
-
rooms — номера отеля
- Типы: 'Эконом' (2500₽/ночь), 'Стандарт' (4000₽/ночь), 'VIP Люкс' (8000₽/ночь)
- Поля: type, name, description, rooms_count, single_beds, double_beds, has_sofa, has_ac, has_wifi, has_shower, max_guests, price_per_guest, image_path, is_active
- Номера по умолчанию: 'Эконом 1' (3 шт, 2 односпальные кровати), 'Стандарт 1' (2 шт, 1 двуспальная + диван), 'VIP Люкс 1' (1 шт, 1 двуспальная + диван, до 4 гостей)
-
promocodes — промокоды
- Поля: code, discount_percent (1-99%), valid_from, valid_to, valid_days, is_active
-
booking_history — история изменений бронирований
- Отслеживает изменения полей: status, room_type, comment, discount_percent
-
users — пользователи системы
- Роли: 'admin', 'user'
- Суперадмин создается при первом запуске (пароль задается через .env)
API Endpoints
Публичные:
GET /— главная страница (index.html)GET /admin— админ-панель (admin.html)GET /api/rooms— список доступных номеровPOST /api/bookings— создание бронированияPOST /api/promocodes/validate— проверка промокода и расчет скидкиGET /api/bookings— получение всех бронирований (требуется API_KEY в заголовке X-API-Key)
Аутентификация:
POST /api/auth/login— вход в систему (login, password)PUT /api/auth/me— обновление профиля (full_name, email)POST /api/auth/change-password— смена пароля (current_password, new_password)
Административные (требуется JWT + роль admin):
GET /api/admin/bookings— список всех бронированийGET /api/admin/bookings/:id/history— история изменений бронированияPATCH /api/admin/bookings/:id— изменение статуса бронированияPATCH /api/admin/bookings/:id/room— изменение типа номераPATCH /api/admin/bookings/:id/comment— добавление комментарияPATCH /api/admin/bookings/:id/discount— изменение скидкиGET /api/admin/rooms— управление номерамиPOST /api/admin/rooms— создание номераPUT /api/admin/rooms/:id— обновление номераDELETE /api/admin/rooms/:id— удаление номераGET /api/admin/promocodes— управление промокодамиPOST /api/admin/promocodes— создание промокодаPUT /api/admin/promocodes/:id— обновление промокодаDELETE /api/admin/promocodes/:id— удаление промокодаGET /api/admin/users— список пользователейPOST /api/admin/users— создание пользователяPUT /api/admin/users/:id— обновление пользователяDELETE /api/admin/users/:id— удаление пользователя
Основные функции
-
Публичная часть:
- Просмотр номеров и цен (цена за ночь)
- Бронирование номера с указанием дат, количества гостей
- Применение промокодов
- Галерея изображений
- Информация о гостинице, развлечениях, отзывах
-
Админ-панель:
- Просмотр всех бронирований
- Изменение статусов бронирований
- Управление номерами (создание, редактирование, удаление)
- Управление промокодами
- Управление пользователями (создание, редактирование, удаление)
- История изменений по каждому бронированию
-
Аутентификация и пользователи:
- Вход по логину и паролю (JWT токен на 24 часа)
- Смена пароля пользователем
- Обновление профиля (имя, email)
- Разграничение прав: admin и user
-
Дополнительно:
- Автоматическая конвертация изображений в WebP (при наличии в папке img)
- Автоматическое создание номеров по умолчанию
- Проверка доступности промокодов по датам
- Расчет стоимости с учетом скидок (calculateBasePrice)
Переменные окружения (.env)
HOTEL777KEY=<секретный_ключ_API>
- PORT=3000 (по умолчанию)
- JWT_SECRET (опционально, по умолчанию 'fallback-secret-change-in-production')
- Пароль администратора задается при первом запуске через регистрацию
Docker развертывание
- Образ:
kalugin66/hotell777_260507 - Порт: 3000 (проброшен через внешний прокси)
- Сеть: applications (внешняя сеть Docker)
- Тома:
/docker/hotell777_260507/data:/app/data - Healthcheck: проверка доступности через wget
Запуск проекта
# Установка зависимостей
npm install
# Запуск в production режиме
npm start
# Запуск в development режиме (с nodemon)
npm run dev
Docker команды
# Сборка и запуск
docker compose up -d --build
# Пересборка без кэша
docker compose build --no-cache && docker compose up -d
# Создание внешней сети (если не существует)
docker network create applications
Git репозиторий
- URL: https://git.dadehard.ru/kalugin66/hotell777_260507.git
- Ветка по умолчанию: main
Автор
- GitHub: kalugin66
Особенности реализации
- Все цены указаны в рублях за номер за ночь
- Количество ночей рассчитывается как разница между датами заезда и выезда
- История изменений сохраняется автоматически при любом изменении бронирования
- Администраторы создаются через API (
POST /api/admin/users) - Автоматическая конвертация изображений в WebP (функция convertImages)
- CORS настроен через заголовки (не требуется отдельный middleware)
- Multer удален (загрузка изображений через админ-панель отключена)