868 lines
23 KiB
Markdown
868 lines
23 KiB
Markdown
# 🚀 Ospabhost 8.1
|
||
|
||
Современная платформа хостинга с поддержкой VPS, S3-хранилищ и системой блогов.
|
||
|
||
## 📋 Содержание
|
||
|
||
- [О проекте](#о-проекте)
|
||
- [Возможности](#возможности)
|
||
- [Архитектура](#архитектура)
|
||
- [Технологии](#технологии)
|
||
- [Быстрый старт](#быстрый-старт)
|
||
- [Развёртывание](#развёртывание)
|
||
- [API документация](#api-документация)
|
||
- [Структура проекта](#структура-проекта)
|
||
- [Разработка](#разработка)
|
||
- [Вклад в проект](#вклад-в-проект)
|
||
|
||
---
|
||
|
||
## 🎯 О проекте
|
||
|
||
**Ospabhost 8.1** — полнофункциональная система управления хостингом с интеграцией Proxmox для VPS, MinIO для S3-хранилищ и встроенной CMS для блога.
|
||
|
||
### Ключевые особенности
|
||
|
||
- 🖥️ **VPS Management** - создание и управление виртуальными серверами через Proxmox API
|
||
- 💾 **S3 Storage** - совместимое с AWS S3 объектное хранилище на базе MinIO
|
||
- 📝 **Blog CMS** - встроенная система блогов с Rich Text редактором
|
||
- 🎫 **Ticketing** - система поддержки с авто-назначением операторов
|
||
- 💰 **Billing** - модуль управления балансом и оплатами
|
||
- 🔐 **Auth** - JWT авторизация с ролями (пользователь/оператор/администратор)
|
||
- 📊 **Admin Panel** - полнофункциональная панель администратора
|
||
|
||
---
|
||
|
||
## 🌟 Возможности
|
||
|
||
### Для пользователей
|
||
|
||
- **VPS серверы**
|
||
- Создание серверов с выбором ОС и тарифа
|
||
- Управление (старт/стоп/рестарт/удаление)
|
||
- Смена root-пароля
|
||
- Изменение ресурсов (resize)
|
||
- Создание и восстановление снапшотов
|
||
- Мониторинг статуса и статистики
|
||
|
||
- **S3 хранилища**
|
||
- Создание бакетов с выбором региона и класса хранения
|
||
- Кастомный тариф с оплатой за GB
|
||
- Загрузка/скачивание файлов
|
||
- Управление публичным доступом
|
||
- Версионирование объектов
|
||
- Presigned URL для временного доступа
|
||
- Web-консоль для управления
|
||
|
||
- **Блог**
|
||
- Чтение статей и комментирование
|
||
- Просмотр статей по URL-адресу
|
||
- Счётчик просмотров
|
||
|
||
- **Тикеты**
|
||
- Создание обращений в поддержку
|
||
- Переписка с операторами
|
||
- Загрузка скриншотов
|
||
- Отслеживание статуса
|
||
|
||
- **Баланс**
|
||
- Пополнение через загрузку чека
|
||
- История транзакций
|
||
- Автоматическая проверка чеков администратором
|
||
|
||
### Для операторов
|
||
|
||
- Просмотр и ответ на тикеты
|
||
- Автоматическое назначение новых тикетов
|
||
- Авто-снятие с тикета при закрытии пользователем
|
||
|
||
### Для администраторов
|
||
|
||
- **Управление пользователями**
|
||
- Просмотр всех пользователей
|
||
- Редактирование баланса
|
||
- Назначение роли оператора
|
||
- Блокировка/разблокировка
|
||
|
||
- **Управление тарифами**
|
||
- Редактирование цен на VPS
|
||
- Настройка S3 тарифов
|
||
- Управление кастомным тарифом (цена за GB, трафик, операции)
|
||
|
||
- **Управление блогом**
|
||
- Создание/редактирование статей
|
||
- Rich Text редактор с загрузкой изображений
|
||
- Модерация комментариев
|
||
- Управление статусами (черновик/опубликовано/архив)
|
||
|
||
- **Проверка чеков**
|
||
- Одобрение/отклонение заявок на пополнение
|
||
- Просмотр загруженных чеков
|
||
|
||
- **Тестирование**
|
||
- Отправка push-уведомлений
|
||
- Отправка email-уведомлений
|
||
- Логирование результатов
|
||
|
||
---
|
||
|
||
## 🏗️ Архитектура
|
||
|
||
### Монорепозиторий
|
||
|
||
Проект состоит из двух основных частей:
|
||
|
||
```
|
||
ospabhost/
|
||
├── backend/ # Express + TypeScript + Prisma
|
||
└── frontend/ # React + Vite + TypeScript
|
||
```
|
||
|
||
### Backend модули
|
||
|
||
```
|
||
backend/src/modules/
|
||
├── auth/ # Авторизация и JWT
|
||
├── server/ # VPS управление (Proxmox)
|
||
├── storage/ # S3 хранилища (MinIO)
|
||
├── blog/ # Система блогов
|
||
├── ticket/ # Тикеты поддержки
|
||
├── check/ # Проверка чеков
|
||
├── notification/ # Уведомления
|
||
├── tariff/ # Тарифы
|
||
├── os/ # Операционные системы
|
||
└── admin/ # Админ панель
|
||
```
|
||
|
||
### База данных
|
||
|
||
Используется **MySQL** с ORM **Prisma**:
|
||
|
||
- `User` - пользователи с ролями
|
||
- `Server` - VPS серверы с привязкой к Proxmox
|
||
- `Tariff` - тарифные планы
|
||
- `OS` - операционные системы
|
||
- `StoragePlan` - тарифы S3 (с полями pricePerGb, bandwidthPerGb, requestsPerGb)
|
||
- `StorageBucket` - S3 бакеты пользователей
|
||
- `Post` - статьи блога
|
||
- `Comment` - комментарии к статьям
|
||
- `Ticket` - тикеты поддержки
|
||
- `TicketMessage` - сообщения в тикетах
|
||
- `Check` - чеки для пополнения
|
||
- `Notification` - уведомления пользователей
|
||
|
||
---
|
||
|
||
## 🛠️ Технологии
|
||
|
||
### Backend
|
||
|
||
- **Node.js 18+**
|
||
- **Express.js** - веб-фреймворк
|
||
- **TypeScript** - типизация
|
||
- **Prisma ORM** - работа с БД
|
||
- **MySQL** - база данных
|
||
- **JWT** - авторизация
|
||
- **Multer** - загрузка файлов
|
||
- **Axios** - HTTP клиент для Proxmox API
|
||
- **bcrypt** - хеширование паролей
|
||
- **MinIO SDK** - работа с S3
|
||
|
||
### Frontend
|
||
|
||
- **React 18** - UI библиотека
|
||
- **TypeScript** - типизация
|
||
- **Vite** - сборщик
|
||
- **React Router** - маршрутизация
|
||
- **Tailwind CSS** - стилизация
|
||
- **React Icons** - иконки
|
||
- **React Quill** - Rich Text редактор
|
||
- **Axios** - HTTP клиент
|
||
|
||
### DevOps
|
||
|
||
- **PM2** - процесс-менеджер
|
||
- **Nginx** - веб-сервер и прокси
|
||
- **Git** - контроль версий
|
||
|
||
---
|
||
|
||
## 🚀 Быстрый старт
|
||
|
||
### Требования
|
||
|
||
- Node.js 18+
|
||
- MySQL 8+
|
||
- Proxmox VE (для VPS)
|
||
- MinIO (для S3)
|
||
|
||
### Установка
|
||
|
||
1. **Клонирование репозитория**
|
||
|
||
```bash
|
||
git clone https://github.com/Ospab/ospabhost8.1.git
|
||
cd ospabhost8.1/ospabhost
|
||
```
|
||
|
||
2. **Настройка Backend**
|
||
|
||
```bash
|
||
cd backend
|
||
npm install
|
||
```
|
||
|
||
Создайте `.env`:
|
||
|
||
```env
|
||
DATABASE_URL="mysql://user:password@localhost:3306/ospabhost"
|
||
JWT_SECRET="your-secret-key"
|
||
PORT=5000
|
||
|
||
# Proxmox
|
||
PROXMOX_HOST="your-proxmox-host"
|
||
PROXMOX_USER="root@pam"
|
||
PROXMOX_PASSWORD="your-password"
|
||
PROXMOX_NODE="pve"
|
||
|
||
# MinIO
|
||
MINIO_ENDPOINT="localhost"
|
||
MINIO_PORT=9000
|
||
MINIO_ACCESS_KEY="your-access-key"
|
||
MINIO_SECRET_KEY="your-secret-key"
|
||
MINIO_BUCKET_PREFIX="ospab"
|
||
```
|
||
|
||
Примените миграции:
|
||
|
||
```bash
|
||
npx prisma migrate deploy
|
||
npx prisma generate
|
||
npx prisma db seed
|
||
```
|
||
|
||
Запустите:
|
||
|
||
```bash
|
||
npm run dev # Разработка
|
||
npm run build && npm start # Продакшн
|
||
```
|
||
|
||
3. **Настройка Frontend**
|
||
|
||
```bash
|
||
cd ../frontend
|
||
npm install
|
||
```
|
||
|
||
Создайте `.env`:
|
||
|
||
```env
|
||
VITE_API_URL=http://localhost:5000
|
||
```
|
||
|
||
Запустите:
|
||
|
||
```bash
|
||
npm run dev # Разработка
|
||
npm run build # Сборка для продакшн
|
||
```
|
||
|
||
4. **Доступ**
|
||
|
||
- Frontend: http://localhost:5173
|
||
- Backend API: http://localhost:5000
|
||
- Панель управления: http://localhost:5173/dashboard
|
||
|
||
Первый пользователь автоматически становится администратором.
|
||
|
||
---
|
||
|
||
## 🌐 Развёртывание
|
||
|
||
### На сервере
|
||
|
||
1. **Подготовка окружения**
|
||
|
||
```bash
|
||
# Установка Node.js 18
|
||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||
sudo apt-get install -y nodejs
|
||
|
||
# Установка MySQL
|
||
sudo apt install mysql-server
|
||
|
||
# Установка PM2
|
||
sudo npm install -g pm2
|
||
|
||
# Установка Nginx
|
||
sudo apt install nginx
|
||
```
|
||
|
||
2. **Клонирование и настройка**
|
||
|
||
```bash
|
||
cd /var/www
|
||
git clone https://github.com/Ospab/ospabhost8.1.git ospab-host
|
||
cd ospab-host/ospabhost
|
||
```
|
||
|
||
3. **Backend**
|
||
|
||
```bash
|
||
cd backend
|
||
npm install
|
||
cp .env.example .env
|
||
# Отредактируйте .env
|
||
|
||
npx prisma migrate deploy
|
||
npx prisma generate
|
||
npm run build
|
||
|
||
pm2 start dist/index.js --name ospab-backend
|
||
pm2 save
|
||
pm2 startup
|
||
```
|
||
|
||
4. **Frontend**
|
||
|
||
```bash
|
||
cd ../frontend
|
||
npm install
|
||
cp .env.example .env
|
||
# Отредактируйте .env
|
||
|
||
npm run build
|
||
```
|
||
|
||
5. **Nginx**
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name your-domain.com;
|
||
|
||
# Frontend
|
||
location / {
|
||
root /var/www/ospab-host/ospabhost/frontend/dist;
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
|
||
# Backend API
|
||
location /api {
|
||
proxy_pass http://localhost:5000;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection 'upgrade';
|
||
proxy_set_header Host $host;
|
||
proxy_cache_bypass $http_upgrade;
|
||
}
|
||
|
||
# Uploads (чеки, изображения блога)
|
||
location /uploads {
|
||
alias /var/www/ospab-host/ospabhost/backend/uploads;
|
||
access_log off;
|
||
expires 30d;
|
||
}
|
||
}
|
||
```
|
||
|
||
```bash
|
||
sudo nginx -t
|
||
sudo systemctl reload nginx
|
||
```
|
||
|
||
6. **SSL (Let's Encrypt)**
|
||
|
||
```bash
|
||
sudo apt install certbot python3-certbot-nginx
|
||
sudo certbot --nginx -d your-domain.com
|
||
```
|
||
|
||
### Развёртывание блога
|
||
|
||
См. подробную инструкцию в [BLOG_DEPLOYMENT.md](./BLOG_DEPLOYMENT.md) и быстрый старт в [BLOG_QUICKSTART.md](./BLOG_QUICKSTART.md).
|
||
|
||
---
|
||
|
||
## 📚 API документация
|
||
|
||
### Публичные эндпоинты
|
||
|
||
#### Авторизация
|
||
|
||
```http
|
||
POST /api/auth/register
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"username": "user",
|
||
"email": "user@example.com",
|
||
"password": "password"
|
||
}
|
||
```
|
||
|
||
```http
|
||
POST /api/auth/login
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "password"
|
||
}
|
||
```
|
||
|
||
#### Блог
|
||
|
||
```http
|
||
GET /api/blog/posts
|
||
# Список опубликованных статей
|
||
|
||
GET /api/blog/posts/:url
|
||
# Статья по URL
|
||
|
||
POST /api/blog/posts/:postId/comments
|
||
# Добавить комментарий (требуется авторизация или имя гостя)
|
||
```
|
||
|
||
#### S3 Storage
|
||
|
||
```http
|
||
GET /api/storage/plans
|
||
# Список тарифов
|
||
|
||
POST /api/storage/checkout
|
||
# Создать корзину для оплаты
|
||
```
|
||
|
||
### Защищённые эндпоинты
|
||
|
||
Все запросы требуют заголовок:
|
||
```
|
||
Authorization: Bearer YOUR_JWT_TOKEN
|
||
```
|
||
|
||
#### Серверы (VPS)
|
||
|
||
```http
|
||
GET /api/servers
|
||
# Список серверов пользователя
|
||
|
||
POST /api/servers
|
||
# Создать сервер
|
||
|
||
POST /api/servers/:id/start
|
||
# Запустить сервер
|
||
|
||
POST /api/servers/:id/stop
|
||
# Остановить сервер
|
||
|
||
POST /api/servers/:id/restart
|
||
# Перезагрузить сервер
|
||
|
||
DELETE /api/servers/:id
|
||
# Удалить сервер
|
||
|
||
POST /api/servers/:id/change-password
|
||
# Сменить root пароль
|
||
|
||
PUT /api/servers/:id/resize
|
||
# Изменить ресурсы
|
||
|
||
POST /api/servers/:id/snapshot
|
||
# Создать снапшот
|
||
|
||
GET /api/servers/:id/snapshots
|
||
# Список снапшотов
|
||
|
||
POST /api/servers/:id/rollback
|
||
# Откатиться к снапшоту
|
||
|
||
DELETE /api/servers/:id/snapshots/:snapshotName
|
||
# Удалить снапшот
|
||
```
|
||
|
||
#### S3 Buckets
|
||
|
||
```http
|
||
GET /api/storage/buckets
|
||
# Список бакетов
|
||
|
||
POST /api/storage/buckets
|
||
# Создать бакет
|
||
|
||
GET /api/storage/buckets/:id
|
||
# Информация о бакете
|
||
|
||
DELETE /api/storage/buckets/:id
|
||
# Удалить бакет
|
||
|
||
PUT /api/storage/buckets/:id
|
||
# Обновить настройки
|
||
|
||
GET /api/storage/buckets/:id/objects
|
||
# Список объектов
|
||
|
||
POST /api/storage/buckets/:id/presign
|
||
# Создать presigned URL
|
||
|
||
DELETE /api/storage/buckets/:id/objects
|
||
# Удалить объекты
|
||
|
||
POST /api/storage/buckets/:id/console-credentials
|
||
# Создать учётные данные для web-консоли
|
||
```
|
||
|
||
#### Тикеты
|
||
|
||
```http
|
||
GET /api/tickets
|
||
# Список тикетов
|
||
|
||
POST /api/tickets
|
||
# Создать тикет
|
||
|
||
GET /api/tickets/:id
|
||
# Информация о тикете
|
||
|
||
POST /api/tickets/:id/messages
|
||
# Отправить сообщение
|
||
|
||
PATCH /api/tickets/:id/close
|
||
# Закрыть тикет
|
||
```
|
||
|
||
#### Администратор
|
||
|
||
```http
|
||
GET /api/admin/users
|
||
# Список всех пользователей
|
||
|
||
PUT /api/admin/users/:id
|
||
# Редактировать пользователя
|
||
|
||
GET /api/admin/checks
|
||
# Список всех чеков
|
||
|
||
PUT /api/admin/checks/:id
|
||
# Одобрить/отклонить чек
|
||
|
||
GET /api/blog/admin/posts
|
||
# Все статьи блога
|
||
|
||
POST /api/blog/admin/posts
|
||
# Создать статью
|
||
|
||
PUT /api/blog/admin/posts/:id
|
||
# Обновить статью
|
||
|
||
DELETE /api/blog/admin/posts/:id
|
||
# Удалить статью
|
||
|
||
POST /api/blog/admin/upload-image
|
||
# Загрузить изображение
|
||
|
||
GET /api/blog/admin/comments
|
||
# Все комментарии
|
||
|
||
PATCH /api/blog/admin/comments/:id
|
||
# Модерировать комментарий
|
||
|
||
DELETE /api/blog/admin/comments/:id
|
||
# Удалить комментарий
|
||
|
||
PUT /api/storage/plans/:id
|
||
# Редактировать тариф S3 (включая pricePerGb, bandwidthPerGb, requestsPerGb)
|
||
|
||
POST /api/admin/test/push-notification
|
||
# Тест push-уведомлений
|
||
|
||
POST /api/admin/test/email-notification
|
||
# Тест email-уведомлений
|
||
```
|
||
|
||
---
|
||
|
||
## 📁 Структура проекта
|
||
|
||
```
|
||
ospabhost8.1/
|
||
├── ospabhost/
|
||
│ ├── backend/
|
||
│ │ ├── src/
|
||
│ │ │ ├── modules/
|
||
│ │ │ │ ├── auth/
|
||
│ │ │ │ │ ├── auth.controller.ts
|
||
│ │ │ │ │ ├── auth.routes.ts
|
||
│ │ │ │ │ └── auth.middleware.ts
|
||
│ │ │ │ ├── server/
|
||
│ │ │ │ │ ├── server.controller.ts
|
||
│ │ │ │ │ ├── server.routes.ts
|
||
│ │ │ │ │ └── proxmoxApi.ts
|
||
│ │ │ │ ├── storage/
|
||
│ │ │ │ │ ├── storage.service.ts
|
||
│ │ │ │ │ └── storage.routes.ts
|
||
│ │ │ │ ├── blog/
|
||
│ │ │ │ │ ├── blog.controller.ts
|
||
│ │ │ │ │ ├── blog.routes.ts
|
||
│ │ │ │ │ └── upload.controller.ts
|
||
│ │ │ │ ├── admin/
|
||
│ │ │ │ │ ├── admin.controller.ts
|
||
│ │ │ │ │ └── admin.routes.ts
|
||
│ │ │ │ ├── ticket/
|
||
│ │ │ │ ├── check/
|
||
│ │ │ │ ├── notification/
|
||
│ │ │ │ ├── tariff/
|
||
│ │ │ │ └── os/
|
||
│ │ │ ├── prisma/
|
||
│ │ │ │ └── client.ts
|
||
│ │ │ ├── index.ts
|
||
│ │ │ └── server.ts
|
||
│ │ ├── prisma/
|
||
│ │ │ ├── schema.prisma
|
||
│ │ │ ├── migrations/
|
||
│ │ │ ├── seed.ts
|
||
│ │ │ └── seed_os.ts
|
||
│ │ ├── uploads/
|
||
│ │ │ ├── checks/
|
||
│ │ │ └── blog/
|
||
│ │ ├── package.json
|
||
│ │ └── tsconfig.json
|
||
│ │
|
||
│ └── frontend/
|
||
│ ├── src/
|
||
│ │ ├── pages/
|
||
│ │ │ ├── index.tsx
|
||
│ │ │ ├── login.tsx
|
||
│ │ │ ├── pricing.tsx
|
||
│ │ │ ├── blog.tsx
|
||
│ │ │ ├── blogpost.tsx
|
||
│ │ │ └── dashboard/
|
||
│ │ │ ├── mainpage.tsx
|
||
│ │ │ ├── servers.tsx
|
||
│ │ │ ├── storage.tsx
|
||
│ │ │ ├── tickets.tsx
|
||
│ │ │ ├── balance.tsx
|
||
│ │ │ ├── admin.tsx
|
||
│ │ │ └── blogadmin.tsx
|
||
│ │ ├── components/
|
||
│ │ │ ├── Navbar.tsx
|
||
│ │ │ ├── Footer.tsx
|
||
│ │ │ ├── AdminPricingTab.tsx
|
||
│ │ │ └── AdminTestingTab.tsx
|
||
│ │ ├── context/
|
||
│ │ │ └── authcontext.tsx
|
||
│ │ ├── hooks/
|
||
│ │ │ ├── useAuth.ts
|
||
│ │ │ └── useToast.ts
|
||
│ │ ├── utils/
|
||
│ │ │ └── apiClient.ts
|
||
│ │ ├── config/
|
||
│ │ │ └── api.ts
|
||
│ │ ├── App.tsx
|
||
│ │ └── main.tsx
|
||
│ ├── package.json
|
||
│ ├── vite.config.ts
|
||
│ └── tailwind.config.js
|
||
│
|
||
├── README.md
|
||
├── CONTRIBUTING.md
|
||
├── BLOG_DEPLOYMENT.md
|
||
└── BLOG_QUICKSTART.md
|
||
```
|
||
|
||
---
|
||
|
||
## 💻 Разработка
|
||
|
||
### Установка зависимостей
|
||
|
||
```bash
|
||
# Backend
|
||
cd ospabhost/backend
|
||
npm install
|
||
|
||
# Frontend
|
||
cd ospabhost/frontend
|
||
npm install
|
||
```
|
||
|
||
### Запуск в режиме разработки
|
||
|
||
```bash
|
||
# Backend (порт 5000)
|
||
cd backend
|
||
npm run dev
|
||
|
||
# Frontend (порт 5173)
|
||
cd frontend
|
||
npm run dev
|
||
```
|
||
|
||
### Линтинг и форматирование
|
||
|
||
```bash
|
||
# Frontend
|
||
npm run lint
|
||
```
|
||
|
||
### Работа с БД
|
||
|
||
```bash
|
||
# Создать миграцию
|
||
npx prisma migrate dev --name migration_name
|
||
|
||
# Применить миграции
|
||
npx prisma migrate deploy
|
||
|
||
# Открыть Prisma Studio
|
||
npx prisma studio
|
||
|
||
# Сгенерировать Prisma Client
|
||
npx prisma generate
|
||
|
||
# Заполнить БД начальными данными
|
||
npx prisma db seed
|
||
```
|
||
|
||
### Сборка
|
||
|
||
```bash
|
||
# Backend
|
||
npm run build
|
||
|
||
# Frontend
|
||
npm run build
|
||
npm run preview # Предпросмотр production сборки
|
||
```
|
||
|
||
---
|
||
|
||
## 🐛 Известные проблемы и решения
|
||
|
||
### Backend
|
||
|
||
**Проблема:** "post and comment are not properties of PrismaClient"
|
||
|
||
**Решение:**
|
||
```bash
|
||
cd backend
|
||
npx prisma generate
|
||
npm run build
|
||
pm2 restart ospab-backend
|
||
```
|
||
|
||
**Проблема:** 404 ошибки на `/api/admin/test/*`
|
||
|
||
**Решение:**
|
||
- Проверьте порядок middleware в `admin.routes.ts` (test endpoints должны быть BEFORE requireAdmin)
|
||
- Перезапустите dev-server
|
||
|
||
**Проблема:** Кастомный тариф не возвращает pricePerGb
|
||
|
||
**Решение:**
|
||
- Убедитесь что функция `serializePlan` в `storage.service.ts` включает поля `pricePerGb`, `bandwidthPerGb`, `requestsPerGb`
|
||
- Пересоберите backend: `npm run build`
|
||
|
||
### Frontend
|
||
|
||
**Проблема:** Не отображается вкладка "📝 Блог"
|
||
|
||
**Решение:**
|
||
- Убедитесь что пользователь имеет `isAdmin: true`
|
||
- Пересоберите frontend: `npm run build`
|
||
|
||
**Проблема:** Rich Text редактор не загружается
|
||
|
||
**Решение:**
|
||
```bash
|
||
cd frontend
|
||
npm install react-quill quill --legacy-peer-deps
|
||
npm run build
|
||
```
|
||
|
||
**Проблема:** Не могу изменить цену за GB в кастомном тарифе
|
||
|
||
**Решение:**
|
||
- UI уже реализован в `AdminPricingTab.tsx`
|
||
- Backend должен возвращать эти поля через `serializePlan`
|
||
- Перезапустите оба сервиса
|
||
|
||
### S3 Storage
|
||
|
||
**Проблема:** Изображения не загружаются
|
||
|
||
**Проверьте:**
|
||
1. Права на директорию `backend/uploads/blog` (должно быть `755`)
|
||
2. Nginx раздаёт `/uploads/blog`
|
||
3. В логах backend нет ошибок multer
|
||
|
||
```bash
|
||
# Проверка прав
|
||
ls -la /var/www/ospab-host/ospabhost/backend/uploads/blog
|
||
|
||
# Проверка логов
|
||
pm2 logs ospab-backend --lines 50
|
||
```
|
||
|
||
---
|
||
|
||
## 🤝 Вклад в проект
|
||
|
||
Мы приветствуем вклад в развитие проекта! См. [CONTRIBUTING.md](CONTRIBUTING.md) для деталей.
|
||
|
||
### Процесс
|
||
|
||
1. Форкните репозиторий
|
||
2. Создайте ветку для фичи (`git checkout -b feature/AmazingFeature`)
|
||
3. Закоммитьте изменения (`git commit -m 'feat: add amazing feature'`)
|
||
4. Запушьте в ветку (`git push origin feature/AmazingFeature`)
|
||
5. Откройте Pull Request
|
||
|
||
### Стандарты коммитов
|
||
|
||
Используем [Conventional Commits](https://www.conventionalcommits.org/):
|
||
|
||
```bash
|
||
feat(storage): add custom tariff pricing
|
||
fix(ticket): auto-unassign operator on user close
|
||
docs: update API endpoints in README
|
||
refactor(auth): remove any types from middleware
|
||
```
|
||
|
||
---
|
||
|
||
## 📄 Лицензия
|
||
|
||
Этот проект является частной разработкой. Все права защищены.
|
||
|
||
---
|
||
|
||
## 👥 Команда
|
||
|
||
- **Ospab** - Основатель и главный разработчик
|
||
|
||
---
|
||
|
||
## 📞 Контакты
|
||
|
||
- Website: [ospab.host](https://ospab.host)
|
||
- Email: support@ospab.host
|
||
- Telegram: [@ospab](https://t.me/ospab)
|
||
|
||
---
|
||
|
||
## 🙏 Благодарности
|
||
|
||
- [Proxmox VE](https://www.proxmox.com/) - виртуализация
|
||
- [MinIO](https://min.io/) - S3-совместимое хранилище
|
||
- [Prisma](https://www.prisma.io/) - ORM для Node.js
|
||
- [React](https://react.dev/) - UI библиотека
|
||
- [Tailwind CSS](https://tailwindcss.com/) - CSS фреймворк
|
||
- [Quill](https://quilljs.com/) - Rich Text редактор
|
||
|
||
---
|
||
|
||
**Версия:** 8.1
|
||
**Последнее обновление:** 26 ноября 2025
|