Merge dev: Complete template with all improvements
Some checks are pending
CI/CD / lint-and-build (push) Waiting to run
Some checks are pending
CI/CD / lint-and-build (push) Waiting to run
This commit is contained in:
commit
6c26472660
48
.github/workflows/ci.yml
vendored
Normal file
48
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# GitHub Actions CI/CD workflow
|
||||
name: CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
lint-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: ./frontend
|
||||
run: npm ci
|
||||
|
||||
- name: Run ESLint
|
||||
working-directory: ./frontend
|
||||
run: npm run lint
|
||||
|
||||
- name: Check Prettier formatting
|
||||
working-directory: ./frontend
|
||||
run: npm run format:check
|
||||
|
||||
- name: Build frontend
|
||||
working-directory: ./frontend
|
||||
run: npm run build
|
||||
|
||||
- name: Install backend dependencies
|
||||
working-directory: ./backend
|
||||
run: npm ci
|
||||
|
||||
- name: Check backend syntax
|
||||
working-directory: ./backend
|
||||
run: node --check server.js
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@ -47,3 +47,10 @@ next-env.d.ts
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Docker
|
||||
.dockerignore
|
||||
|
||||
|
||||
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@ -0,0 +1,21 @@
|
||||
# Dockerfile для backend (Node.js)
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем package.json и устанавливаем зависимости
|
||||
COPY backend/package*.json ./
|
||||
RUN npm install --production
|
||||
|
||||
# Копируем код приложения
|
||||
COPY backend/ .
|
||||
|
||||
# Создаем папку для логов
|
||||
RUN mkdir -p logs
|
||||
|
||||
# Открываем порт
|
||||
EXPOSE 3001
|
||||
|
||||
# Запускаем приложение
|
||||
CMD ["node", "server.js"]
|
||||
|
||||
30
Dockerfile.frontend
Normal file
30
Dockerfile.frontend
Normal file
@ -0,0 +1,30 @@
|
||||
# Dockerfile для frontend (Next.js статический экспорт)
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем package.json и устанавливаем зависимости
|
||||
COPY frontend/package*.json ./
|
||||
RUN npm install
|
||||
|
||||
# Копируем код и собираем
|
||||
COPY frontend/ .
|
||||
RUN npm run build
|
||||
|
||||
# Production стадия - сервинг статических файлов
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Устанавливаем serve для статических файлов
|
||||
RUN npm install -g serve
|
||||
|
||||
# Копируем собранные файлы
|
||||
COPY --from=builder /app/out ./out
|
||||
|
||||
# Открываем порт
|
||||
EXPOSE 3000
|
||||
|
||||
# Запускаем serve
|
||||
CMD ["serve", "-s", "out", "-p", "3000"]
|
||||
|
||||
100
IMPROVEMENTS.md
100
IMPROVEMENTS.md
@ -1,6 +1,6 @@
|
||||
# Рекомендации по улучшению шаблона
|
||||
|
||||
## Добавленные улучшения
|
||||
## ✅ Реализованные улучшения
|
||||
|
||||
### 1. Prettier для форматирования кода
|
||||
- Конфигурация `.prettierrc`
|
||||
@ -13,77 +13,81 @@ npm run format # Форматировать весь код
|
||||
npm run format:check # Проверить форматирование
|
||||
```
|
||||
|
||||
### 2. Переменные окружения
|
||||
### 2. Переменные окружения (dotenv)
|
||||
- `.env.example` файлы для frontend и backend
|
||||
- Автоматическая загрузка через `dotenv`
|
||||
- Шаблоны для быстрого старта
|
||||
- Документация в файлах
|
||||
|
||||
### 3. Middleware для бэкенда
|
||||
- `logger.js` - логирование всех запросов
|
||||
- `logger.js` - простое логирование всех запросов
|
||||
- `errorHandler.js` - централизованная обработка ошибок
|
||||
- Пример использования в `server.js`
|
||||
- Интегрировано в `server.js`
|
||||
|
||||
### 4. Структура роутов
|
||||
- Пример файла `routes/example.js`
|
||||
### 4. Продвинутое логирование (Winston)
|
||||
- Структурированные логи в файлы
|
||||
- Разные уровни логирования
|
||||
- Логи в `backend/logs/`
|
||||
- Конфигурация в `backend/config/logger.js`
|
||||
|
||||
### 5. Валидация запросов (Express Validator)
|
||||
- Middleware `validate.js` для обработки валидации
|
||||
- Примеры валидации в `routes/example.js`
|
||||
- Валидация body, params, query
|
||||
|
||||
### 6. Rate Limiting (Express Rate Limit)
|
||||
- Два уровня защиты: общий и строгий
|
||||
- Настраиваемые лимиты
|
||||
- Защита от злоупотреблений
|
||||
|
||||
### 7. Структура роутов
|
||||
- Пример файла `routes/example.js` с валидацией
|
||||
- Организация API endpoints по модулям
|
||||
- Готовый шаблон для новых роутов
|
||||
|
||||
### 5. Пример компонента
|
||||
### 8. Пример компонента
|
||||
- `ExampleComponent.tsx` с использованием API
|
||||
- Демонстрация работы с состоянием
|
||||
- Обработка ошибок и загрузки
|
||||
|
||||
## Дополнительные рекомендации
|
||||
### 9. Docker поддержка
|
||||
- `Dockerfile` для backend
|
||||
- `Dockerfile.frontend` для frontend
|
||||
- `docker-compose.yml` для разработки
|
||||
- `.dockerignore` для оптимизации
|
||||
|
||||
### Можно добавить в будущем:
|
||||
### 10. CI/CD (GitHub Actions)
|
||||
- Автоматическая проверка кода
|
||||
- Проверка линтера и форматирования
|
||||
- Проверка сборки
|
||||
- Workflow в `.github/workflows/ci.yml`
|
||||
|
||||
1. **Валидация запросов** (express-validator)
|
||||
```bash
|
||||
npm install express-validator
|
||||
```
|
||||
## 📚 Документация
|
||||
|
||||
2. **Логирование** (winston или pino)
|
||||
```bash
|
||||
npm install winston
|
||||
```
|
||||
### Создана полная документация:
|
||||
- [`docs/USAGE_GUIDE.md`](docs/USAGE_GUIDE.md) - Подробное руководство по всем улучшениям
|
||||
- [`docs/QUICK_START.md`](docs/QUICK_START.md) - Быстрый старт
|
||||
- [`docs/PROJECT_RULES.md`](docs/PROJECT_RULES.md) - Правила разработки
|
||||
- [`docs/KNOWLEDGE_BASE.md`](docs/KNOWLEDGE_BASE.md) - База знаний
|
||||
|
||||
3. **Валидация окружения** (dotenv-safe)
|
||||
```bash
|
||||
npm install dotenv-safe
|
||||
```
|
||||
## 🎯 Использование улучшений
|
||||
|
||||
4. **Rate limiting** (express-rate-limit)
|
||||
```bash
|
||||
npm install express-rate-limit
|
||||
```
|
||||
Все улучшения готовы к использованию. См. [`docs/USAGE_GUIDE.md`](docs/USAGE_GUIDE.md) для подробных инструкций по каждому улучшению.
|
||||
|
||||
5. **TypeScript для бэкенда**
|
||||
## 🔮 Дополнительные возможности (опционально)
|
||||
|
||||
1. **TypeScript для бэкенда**
|
||||
- Переименовать `.js` в `.ts`
|
||||
- Настроить `tsconfig.json` для backend
|
||||
- Добавить типы для Express
|
||||
|
||||
6. **Docker поддержка** (опционально)
|
||||
- `Dockerfile` для frontend и backend
|
||||
- `docker-compose.yml`
|
||||
|
||||
7. **Тестирование** (опционально)
|
||||
2. **Тестирование**
|
||||
- Jest для unit тестов
|
||||
- Testing Library для компонентов
|
||||
|
||||
8. **CI/CD** (GitHub Actions)
|
||||
- Автоматическая проверка кода
|
||||
- Автоматический деплой
|
||||
|
||||
## Текущая структура
|
||||
|
||||
Все основные улучшения уже добавлены:
|
||||
- ✅ Prettier
|
||||
- ✅ Environment variables examples
|
||||
- ✅ Middleware структура
|
||||
- ✅ Примеры роутов
|
||||
- ✅ Пример компонента
|
||||
- ✅ Логирование
|
||||
- ✅ Обработка ошибок
|
||||
|
||||
Шаблон готов к использованию и может быть расширен по мере необходимости.
|
||||
3. **База данных**
|
||||
- Подключение к PostgreSQL/MySQL
|
||||
- ORM (Prisma, Sequelize)
|
||||
|
||||
4. **Аутентификация**
|
||||
- JWT токены
|
||||
- Passport.js стратегии
|
||||
|
||||
13
README.md
13
README.md
@ -152,6 +152,19 @@ npm run format:check # Проверить форматирование
|
||||
- `frontend/.env.example` → `frontend/.env.local`
|
||||
- `backend/.env.example` → `backend/.env`
|
||||
|
||||
### Улучшения шаблона
|
||||
|
||||
Шаблон включает следующие улучшения:
|
||||
- ✅ **Winston** - продвинутое логирование
|
||||
- ✅ **Express Validator** - валидация запросов
|
||||
- ✅ **Express Rate Limit** - защита от злоупотреблений
|
||||
- ✅ **dotenv** - управление переменными окружения
|
||||
- ✅ **Docker** - контейнеризация приложения
|
||||
- ✅ **GitHub Actions** - CI/CD автоматизация
|
||||
|
||||
Подробные инструкции: [`docs/USAGE_GUIDE.md`](docs/USAGE_GUIDE.md)
|
||||
Быстрый старт: [`docs/QUICK_START.md`](docs/QUICK_START.md)
|
||||
|
||||
## 📝 Лицензия
|
||||
|
||||
ISC
|
||||
|
||||
40
backend/config/logger.js
Normal file
40
backend/config/logger.js
Normal file
@ -0,0 +1,40 @@
|
||||
// Конфигурация Winston для логирования
|
||||
|
||||
const winston = require('winston');
|
||||
|
||||
const logFormat = winston.format.combine(
|
||||
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
||||
winston.format.errors({ stack: true }),
|
||||
winston.format.splat(),
|
||||
winston.format.json()
|
||||
);
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: process.env.LOG_LEVEL || 'info',
|
||||
format: logFormat,
|
||||
defaultMeta: { service: 'backend' },
|
||||
transports: [
|
||||
// Запись ошибок в файл
|
||||
new winston.transports.File({
|
||||
filename: 'logs/error.log',
|
||||
level: 'error'
|
||||
}),
|
||||
// Запись всех логов в файл
|
||||
new winston.transports.File({
|
||||
filename: 'logs/combined.log'
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// В режиме разработки также выводить в консоль
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
logger.add(new winston.transports.Console({
|
||||
format: winston.format.combine(
|
||||
winston.format.colorize(),
|
||||
winston.format.simple()
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = logger;
|
||||
|
||||
31
backend/middleware/rateLimiter.js
Normal file
31
backend/middleware/rateLimiter.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Rate limiter для защиты от злоупотреблений
|
||||
|
||||
const rateLimit = require('express-rate-limit');
|
||||
|
||||
// Общий rate limiter
|
||||
const generalLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 минут
|
||||
max: 100, // максимум 100 запросов с одного IP за окно времени
|
||||
message: {
|
||||
success: false,
|
||||
error: 'Too many requests from this IP, please try again later.',
|
||||
},
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false,
|
||||
});
|
||||
|
||||
// Строгий rate limiter для API
|
||||
const strictLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 20, // максимум 20 запросов
|
||||
message: {
|
||||
success: false,
|
||||
error: 'Too many requests, please try again later.',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
generalLimiter,
|
||||
strictLimiter,
|
||||
};
|
||||
|
||||
24
backend/middleware/validate.js
Normal file
24
backend/middleware/validate.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Middleware для валидации запросов с express-validator
|
||||
|
||||
const { validationResult } = require('express-validator');
|
||||
|
||||
const validate = (validations) => {
|
||||
return async (req, res, next) => {
|
||||
// Выполняем все валидации
|
||||
await Promise.all(validations.map(validation => validation.run(req)));
|
||||
|
||||
const errors = validationResult(req);
|
||||
if (errors.isEmpty()) {
|
||||
return next();
|
||||
}
|
||||
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
errors: errors.array(),
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = validate;
|
||||
|
||||
@ -13,7 +13,11 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^5.1.0",
|
||||
"body-parser": "^2.2.0"
|
||||
"body-parser": "^2.2.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"express-validator": "^7.2.0",
|
||||
"express-rate-limit": "^7.4.1",
|
||||
"winston": "^3.15.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
// Пример файла с роутами
|
||||
// Пример файла с роутами с валидацией
|
||||
// Используйте эту структуру для организации API endpoints
|
||||
|
||||
const express = require('express');
|
||||
const { body, param } = require('express-validator');
|
||||
const validate = require('../middleware/validate');
|
||||
const { strictLimiter } = require('../middleware/rateLimiter');
|
||||
const logger = require('../config/logger');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// GET endpoint
|
||||
router.get('/hello', (req, res) => {
|
||||
logger.info('Hello endpoint called');
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Hello from example route!',
|
||||
@ -13,34 +19,70 @@ router.get('/hello', (req, res) => {
|
||||
});
|
||||
|
||||
// POST endpoint с валидацией
|
||||
router.post('/data', (req, res) => {
|
||||
try {
|
||||
const { name, value } = req.body;
|
||||
router.post(
|
||||
'/data',
|
||||
strictLimiter, // Применить строгий rate limiter
|
||||
[
|
||||
body('name')
|
||||
.trim()
|
||||
.notEmpty()
|
||||
.withMessage('Name is required')
|
||||
.isLength({ min: 2, max: 50 })
|
||||
.withMessage('Name must be between 2 and 50 characters'),
|
||||
body('value')
|
||||
.notEmpty()
|
||||
.withMessage('Value is required')
|
||||
.isNumeric()
|
||||
.withMessage('Value must be a number'),
|
||||
],
|
||||
validate, // Middleware для обработки ошибок валидации
|
||||
(req, res) => {
|
||||
try {
|
||||
const { name, value } = req.body;
|
||||
|
||||
// Простая валидация
|
||||
if (!name || !value) {
|
||||
return res.status(400).json({
|
||||
logger.info(`Processing data: name=${name}, value=${value}`);
|
||||
|
||||
// Обработка данных
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
name,
|
||||
value: Number(value),
|
||||
processed: true,
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error('Error processing data:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Name and value are required',
|
||||
error: err.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Обработка данных
|
||||
// GET с параметром и валидацией
|
||||
router.get(
|
||||
'/item/:id',
|
||||
[
|
||||
param('id')
|
||||
.isInt({ min: 1 })
|
||||
.withMessage('ID must be a positive integer'),
|
||||
],
|
||||
validate,
|
||||
(req, res) => {
|
||||
const { id } = req.params;
|
||||
logger.info(`Getting item with id: ${id}`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
name,
|
||||
value,
|
||||
processed: true,
|
||||
id: Number(id),
|
||||
name: 'Example Item',
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: err.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
|
||||
@ -1,13 +1,19 @@
|
||||
// Загрузка переменных окружения
|
||||
require('dotenv').config();
|
||||
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const logger = require('./middleware/logger');
|
||||
const winstonLogger = require('./config/logger');
|
||||
const simpleLogger = require('./middleware/logger'); // Простое логирование для разработки
|
||||
const errorHandler = require('./middleware/errorHandler');
|
||||
const { generalLimiter } = require('./middleware/rateLimiter');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3001;
|
||||
|
||||
// Middleware
|
||||
app.use(logger);
|
||||
app.use(simpleLogger); // Простое логирование запросов
|
||||
app.use(generalLimiter); // Rate limiting
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
@ -42,9 +48,9 @@ app.post('/api/example', (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Подключение роутов (пример)
|
||||
// const exampleRoutes = require('./routes/example');
|
||||
// app.use('/api/example', exampleRoutes);
|
||||
// Подключение роутов
|
||||
const exampleRoutes = require('./routes/example');
|
||||
app.use('/api/example', exampleRoutes);
|
||||
|
||||
// Обработка 404
|
||||
app.use((req, res) => {
|
||||
@ -59,7 +65,8 @@ app.use(errorHandler);
|
||||
|
||||
// Запуск сервера
|
||||
app.listen(PORT, () => {
|
||||
console.log(`🚀 Server is running on http://localhost:${PORT}`);
|
||||
console.log(`📡 Health check: http://localhost:${PORT}/api/health`);
|
||||
winstonLogger.info(`🚀 Server is running on http://localhost:${PORT}`);
|
||||
winstonLogger.info(`📡 Health check: http://localhost:${PORT}/api/health`);
|
||||
winstonLogger.info(`📝 Environment: ${process.env.NODE_ENV || 'development'}`);
|
||||
});
|
||||
|
||||
|
||||
33
docker-compose.yml
Normal file
33
docker-compose.yml
Normal file
@ -0,0 +1,33 @@
|
||||
# Docker Compose конфигурация для разработки
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- PORT=3001
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
- /app/node_modules
|
||||
env_file:
|
||||
- ./backend/.env
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.frontend
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
# Для использования:
|
||||
# docker-compose up -d # Запустить в фоне
|
||||
# docker-compose logs -f # Просмотр логов
|
||||
# docker-compose down # Остановить
|
||||
|
||||
94
docs/QUICK_START.md
Normal file
94
docs/QUICK_START.md
Normal file
@ -0,0 +1,94 @@
|
||||
# Быстрый старт с улучшениями
|
||||
|
||||
## 🚀 Установка всех зависимостей
|
||||
|
||||
```powershell
|
||||
# Frontend
|
||||
cd frontend
|
||||
npm install
|
||||
|
||||
# Backend
|
||||
cd ../backend
|
||||
npm install
|
||||
```
|
||||
|
||||
## ⚙️ Настройка переменных окружения
|
||||
|
||||
```powershell
|
||||
# Frontend
|
||||
cd frontend
|
||||
Copy-Item .env.example .env.local
|
||||
# Отредактируйте .env.local при необходимости
|
||||
|
||||
# Backend
|
||||
cd ../backend
|
||||
Copy-Item .env.example .env
|
||||
# Отредактируйте .env при необходимости
|
||||
```
|
||||
|
||||
## 🏃 Запуск в разработке
|
||||
|
||||
### Обычный способ (без Docker):
|
||||
|
||||
```powershell
|
||||
# Терминал 1 - Backend
|
||||
cd backend
|
||||
node server.js
|
||||
|
||||
# Терминал 2 - Frontend
|
||||
cd frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### С Docker:
|
||||
|
||||
```powershell
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 📝 Форматирование кода
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
npm run format # Форматировать весь код
|
||||
npm run format:check # Проверить форматирование
|
||||
```
|
||||
|
||||
## 🧪 Проверка работы
|
||||
|
||||
1. **Backend**: Откройте http://localhost:3001/api/health
|
||||
2. **Frontend**: Откройте http://localhost:3000
|
||||
3. **Пример API**: Попробуйте POST на http://localhost:3001/api/example/data
|
||||
|
||||
### Тестовый запрос:
|
||||
|
||||
```powershell
|
||||
# PowerShell
|
||||
Invoke-RestMethod -Uri "http://localhost:3001/api/example/data" -Method POST -ContentType "application/json" -Body '{"name":"Test","value":123}'
|
||||
```
|
||||
|
||||
## 📊 Просмотр логов
|
||||
|
||||
Backend логи находятся в `backend/logs/`:
|
||||
- `error.log` - ошибки
|
||||
- `combined.log` - все логи
|
||||
|
||||
В консоли также выводятся логи (в режиме разработки).
|
||||
|
||||
## ✅ Чеклист перед деплоем
|
||||
|
||||
- [ ] Все зависимости установлены
|
||||
- [ ] `.env` файлы настроены
|
||||
- [ ] Линтер проходит без ошибок (`npm run lint`)
|
||||
- [ ] Форматирование проверено (`npm run format:check`)
|
||||
- [ ] Production build собирается (`npm run build`)
|
||||
- [ ] Логи работают корректно
|
||||
- [ ] Rate limiting настроен (если нужно)
|
||||
- [ ] Валидация работает на всех endpoints
|
||||
|
||||
## 🔍 Дополнительная информация
|
||||
|
||||
- Подробное руководство: [`docs/USAGE_GUIDE.md`](USAGE_GUIDE.md)
|
||||
- Правила проекта: [`docs/PROJECT_RULES.md`](PROJECT_RULES.md)
|
||||
- База знаний: [`docs/KNOWLEDGE_BASE.md`](KNOWLEDGE_BASE.md)
|
||||
|
||||
269
docs/USAGE_GUIDE.md
Normal file
269
docs/USAGE_GUIDE.md
Normal file
@ -0,0 +1,269 @@
|
||||
# Руководство по использованию улучшений шаблона
|
||||
|
||||
## 📋 Содержание
|
||||
|
||||
1. [Переменные окружения](#переменные-окружения)
|
||||
2. [Логирование](#логирование)
|
||||
3. [Валидация запросов](#валидация-запросов)
|
||||
4. [Rate Limiting](#rate-limiting)
|
||||
5. [Docker](#docker)
|
||||
6. [CI/CD](#cicd)
|
||||
|
||||
## 🔐 Переменные окружения
|
||||
|
||||
### Установка dotenv
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
npm install
|
||||
```
|
||||
|
||||
### Использование
|
||||
|
||||
1. Скопируйте `.env.example` в `.env`:
|
||||
```powershell
|
||||
Copy-Item backend\.env.example backend\.env
|
||||
```
|
||||
|
||||
2. Заполните значения в `backend/.env`
|
||||
|
||||
3. Переменные автоматически загружаются при старте сервера
|
||||
|
||||
### Доступные переменные
|
||||
|
||||
- `PORT` - порт сервера (по умолчанию 3001)
|
||||
- `NODE_ENV` - окружение (development/production)
|
||||
- `LOG_LEVEL` - уровень логирования (error/warn/info/debug)
|
||||
|
||||
## 📝 Логирование
|
||||
|
||||
### Winston
|
||||
|
||||
Winston настроен для логирования в файлы и консоль.
|
||||
|
||||
### Логи создаются в `backend/logs/`:
|
||||
- `error.log` - только ошибки
|
||||
- `combined.log` - все логи
|
||||
|
||||
### Использование в коде:
|
||||
|
||||
```javascript
|
||||
const logger = require('./config/logger');
|
||||
|
||||
// Разные уровни логирования
|
||||
logger.error('Error message');
|
||||
logger.warn('Warning message');
|
||||
logger.info('Info message');
|
||||
logger.debug('Debug message');
|
||||
|
||||
// С контекстом
|
||||
logger.info('User login', { userId: 123, ip: '192.168.1.1' });
|
||||
```
|
||||
|
||||
### Настройка уровня логирования
|
||||
|
||||
В `.env` файле:
|
||||
```
|
||||
LOG_LEVEL=debug # error, warn, info, debug
|
||||
```
|
||||
|
||||
## ✅ Валидация запросов
|
||||
|
||||
### Express-Validator
|
||||
|
||||
Используется для валидации входящих данных.
|
||||
|
||||
### Пример использования:
|
||||
|
||||
```javascript
|
||||
const { body } = require('express-validator');
|
||||
const validate = require('../middleware/validate');
|
||||
|
||||
router.post(
|
||||
'/endpoint',
|
||||
[
|
||||
body('email')
|
||||
.isEmail()
|
||||
.withMessage('Invalid email'),
|
||||
body('password')
|
||||
.isLength({ min: 8 })
|
||||
.withMessage('Password must be at least 8 characters'),
|
||||
],
|
||||
validate,
|
||||
(req, res) => {
|
||||
// Валидация прошла успешно
|
||||
// req.body содержит проверенные данные
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Доступные валидаторы:
|
||||
|
||||
- `body()` - валидация тела запроса
|
||||
- `param()` - валидация параметров URL
|
||||
- `query()` - валидация query параметров
|
||||
|
||||
### Популярные методы:
|
||||
|
||||
```javascript
|
||||
body('field')
|
||||
.notEmpty() // Не пустое
|
||||
.isEmail() // Email формат
|
||||
.isLength({ min: 5 }) // Минимальная длина
|
||||
.isInt() // Целое число
|
||||
.isFloat() // Число с плавающей точкой
|
||||
.trim() // Убрать пробелы
|
||||
.custom((value) => { // Кастомная валидация
|
||||
// Ваша логика
|
||||
return true;
|
||||
})
|
||||
```
|
||||
|
||||
## 🛡️ Rate Limiting
|
||||
|
||||
### Защита от злоупотреблений
|
||||
|
||||
Два уровня защиты настроены:
|
||||
|
||||
1. **Общий limiter** (`generalLimiter`):
|
||||
- 100 запросов за 15 минут
|
||||
- Применяется ко всем маршрутам
|
||||
|
||||
2. **Строгий limiter** (`strictLimiter`):
|
||||
- 20 запросов за 15 минут
|
||||
- Для важных endpoints
|
||||
|
||||
### Использование:
|
||||
|
||||
```javascript
|
||||
const { strictLimiter } = require('../middleware/rateLimiter');
|
||||
|
||||
router.post('/api/sensitive', strictLimiter, (req, res) => {
|
||||
// Защищенный endpoint
|
||||
});
|
||||
```
|
||||
|
||||
### Настройка:
|
||||
|
||||
В `.env` (опционально):
|
||||
```
|
||||
RATE_LIMIT_WINDOW_MS=900000 # 15 минут в миллисекундах
|
||||
RATE_LIMIT_MAX_REQUESTS=100 # Максимум запросов
|
||||
```
|
||||
|
||||
## 🐳 Docker
|
||||
|
||||
### Установка Docker
|
||||
|
||||
Убедитесь, что Docker установлен на вашей системе.
|
||||
|
||||
### Структура:
|
||||
|
||||
- `Dockerfile` - для backend
|
||||
- `Dockerfile.frontend` - для frontend
|
||||
- `docker-compose.yml` - для разработки
|
||||
|
||||
### Использование Docker Compose:
|
||||
|
||||
```powershell
|
||||
# Запустить все сервисы
|
||||
docker-compose up -d
|
||||
|
||||
# Просмотр логов
|
||||
docker-compose logs -f
|
||||
|
||||
# Остановить
|
||||
docker-compose down
|
||||
|
||||
# Пересобрать
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
### Отдельная сборка:
|
||||
|
||||
```powershell
|
||||
# Backend
|
||||
docker build -t my-app-backend -f Dockerfile .
|
||||
docker run -p 3001:3001 my-app-backend
|
||||
|
||||
# Frontend
|
||||
docker build -t my-app-frontend -f Dockerfile.frontend .
|
||||
docker run -p 3000:3000 my-app-frontend
|
||||
```
|
||||
|
||||
### Переменные окружения в Docker:
|
||||
|
||||
Создайте `.env` файл или используйте `env_file` в `docker-compose.yml`.
|
||||
|
||||
## 🔄 CI/CD
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
Автоматическая проверка кода при push в репозиторий.
|
||||
|
||||
### Что проверяется:
|
||||
|
||||
- ✅ Установка зависимостей
|
||||
- ✅ ESLint проверка
|
||||
- ✅ Prettier форматирование
|
||||
- ✅ Сборка frontend
|
||||
- ✅ Проверка синтаксиса backend
|
||||
|
||||
### Файл: `.github/workflows/ci.yml`
|
||||
|
||||
Workflow автоматически запускается при:
|
||||
- Push в ветки `main` или `dev`
|
||||
- Pull Request в `main`
|
||||
|
||||
### Просмотр результатов:
|
||||
|
||||
В GitHub репозитории: **Actions** → выберите workflow run
|
||||
|
||||
## 🔧 Интеграция всех улучшений
|
||||
|
||||
### Пример полного endpoint:
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const { body } = require('express-validator');
|
||||
const validate = require('../middleware/validate');
|
||||
const { strictLimiter } = require('../middleware/rateLimiter');
|
||||
const logger = require('../config/logger');
|
||||
|
||||
router.post(
|
||||
'/api/users',
|
||||
strictLimiter,
|
||||
[
|
||||
body('name')
|
||||
.trim()
|
||||
.notEmpty()
|
||||
.withMessage('Name is required'),
|
||||
body('email')
|
||||
.isEmail()
|
||||
.withMessage('Invalid email'),
|
||||
],
|
||||
validate,
|
||||
async (req, res) => {
|
||||
try {
|
||||
logger.info('Creating user', { email: req.body.email });
|
||||
|
||||
// Ваша логика
|
||||
const user = { /* ... */ };
|
||||
|
||||
logger.info('User created successfully', { userId: user.id });
|
||||
res.json({ success: true, data: user });
|
||||
} catch (err) {
|
||||
logger.error('Error creating user', { error: err.message });
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## 📚 Дополнительные ресурсы
|
||||
|
||||
- [Express Validator документация](https://express-validator.github.io/docs/)
|
||||
- [Winston документация](https://github.com/winstonjs/winston)
|
||||
- [Express Rate Limit](https://github.com/express-rate-limit/express-rate-limit)
|
||||
- [Docker документация](https://docs.docker.com/)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user