243 lines
8.7 KiB
Markdown
243 lines
8.7 KiB
Markdown
# DoSoapCalc - Сводная информация о проекте
|
||
|
||
## Быстрый обзор
|
||
|
||
DoSoapCalc - система для расчёта себестоимости изделий ручной работы с веб-интерфейсом и интеграцией Telegram-бота. Проект использует модульную архитектуру для легкого добавления новых калькуляторов.
|
||
|
||
## Архитектура
|
||
|
||
### Структура проекта
|
||
|
||
```
|
||
DoSoapCalc/
|
||
├── backend/ # Node.js + Express + Telegram Bot
|
||
│ ├── bot.js # Главный файл - запускает бота и сервер
|
||
│ ├── config/
|
||
│ │ └── env.js # Загрузка переменных окружения (.env)
|
||
│ ├── calculators/ # Модули калькуляторов
|
||
│ │ ├── index.js # Регистрация всех калькуляторов
|
||
│ │ ├── soap.js # Калькулятор мыла
|
||
│ │ └── candle.js # Пример: калькулятор свечей
|
||
│ ├── lib/
|
||
│ │ ├── telegram.js # Отправка сообщений в Telegram
|
||
│ │ └── validator.js # Валидация данных форм
|
||
│ ├── routes/
|
||
│ │ └── api.js # API маршруты (/api/submit/:calculatorType)
|
||
│ └── .env # Переменные окружения (не в Git)
|
||
│
|
||
└── frontend/ # Next.js + React + TypeScript
|
||
├── app/
|
||
│ ├── [calculator]/ # Динамический роут для калькуляторов
|
||
│ │ └── page.tsx # Страница калькулятора
|
||
│ └── page.tsx # Редирект на /soap
|
||
├── components/
|
||
│ ├── DynamicCalculator.tsx # Универсальный компонент формы
|
||
│ └── FormField.tsx # Переиспользуемые поля ввода
|
||
├── lib/
|
||
│ ├── calculators/ # Модули калькуляторов (frontend)
|
||
│ │ ├── index.ts # Регистрация калькуляторов
|
||
│ │ ├── soap.ts # Калькулятор мыла
|
||
│ │ └── candle.ts # Пример: калькулятор свечей
|
||
│ ├── api.ts # Отправка данных на backend
|
||
│ └── config.ts # Конфигурация (API URL)
|
||
└── types/
|
||
└── calculator.ts # TypeScript типы
|
||
```
|
||
|
||
## Технологический стек
|
||
|
||
### Backend:
|
||
- Node.js + Express
|
||
- node-telegram-bot-api (Telegram Bot)
|
||
- multer (загрузка файлов)
|
||
- dotenv (переменные окружения)
|
||
- PM2 (менеджер процессов)
|
||
|
||
### Frontend:
|
||
- Next.js 15 (App Router)
|
||
- React 19
|
||
- TypeScript
|
||
- Tailwind CSS 4
|
||
- Статический экспорт (`output: 'export'`)
|
||
|
||
## Ключевые концепции
|
||
|
||
### Система калькуляторов
|
||
|
||
Каждый калькулятор состоит из двух модулей (backend + frontend):
|
||
|
||
**Backend модуль** (`backend/calculators/[name].js`):
|
||
- `id` - уникальный идентификатор
|
||
- `name` - название для пользователя
|
||
- `fieldSchema` - схема полей формы
|
||
- `calculate(data)` - функция расчёта
|
||
- `formatMessage(data, result)` - форматирование для Telegram
|
||
- `getRequiredFields()` - обязательные поля
|
||
- `getNumericFields()` - числовые поля
|
||
|
||
**Frontend модуль** (`frontend/lib/calculators/[name].ts`):
|
||
- Та же структура, синхронная с backend
|
||
- TypeScript типы
|
||
|
||
### Регистрация калькуляторов
|
||
|
||
**Backend**: `backend/calculators/index.js`
|
||
```javascript
|
||
const calculators = {
|
||
soap: require('./soap'),
|
||
candle: require('./candle'),
|
||
};
|
||
```
|
||
|
||
**Frontend**: `frontend/lib/calculators/index.ts`
|
||
```typescript
|
||
const calculators: Record<string, Calculator> = {
|
||
soap: soapCalculator,
|
||
candle: candleCalculator,
|
||
};
|
||
```
|
||
|
||
### API Endpoints
|
||
|
||
- `POST /api/submit/:calculatorType` - отправка расчёта
|
||
- Параметры: `calculatorType` (soap, candle, etc.)
|
||
- Body: FormData (поля формы + опционально photo)
|
||
- Ответ: 200 OK или ошибка
|
||
|
||
### Telegram Bot
|
||
|
||
- Команда `/menu` - открывает Web App с калькулятором
|
||
- URL формата: `{WEBAPP_BASE_URL}/{calculatorType}?chat_id={chatId}`
|
||
- Отправка результатов через `sendMessage` или `sendPhoto`
|
||
|
||
## Переменные окружения
|
||
|
||
### Backend (.env в `/backend/`):
|
||
|
||
```env
|
||
BOT_TOKEN=your_telegram_bot_token
|
||
WEBAPP_BASE_URL=https://your-domain.com
|
||
API_BASE_URL=https://api.your-domain.com
|
||
HTTP_PORT=3001
|
||
CORS_ORIGINS=https://your-domain.com
|
||
```
|
||
|
||
### Frontend (.env.local в `/frontend/`):
|
||
|
||
```env
|
||
NEXT_PUBLIC_API_BASE_URL=https://api.your-domain.com
|
||
```
|
||
|
||
## Запуск проекта
|
||
|
||
### PM2 (Production)
|
||
|
||
```bash
|
||
# Production режим (через node)
|
||
pm2 start ecosystem.config.js --env production
|
||
|
||
# Development режим (через nodemon с автоперезагрузкой)
|
||
pm2 start ecosystem.config.js --env development
|
||
|
||
# Управление
|
||
pm2 restart ecosystem.config.js
|
||
pm2 stop ecosystem.config.js
|
||
pm2 logs dosoap-backend
|
||
pm2 logs dosoap-frontend
|
||
```
|
||
|
||
### Ручной запуск
|
||
|
||
**Backend:**
|
||
```bash
|
||
cd backend
|
||
npm install
|
||
# Создать .env файл
|
||
node bot.js
|
||
# или с nodemon:
|
||
nodemon bot.js
|
||
```
|
||
|
||
**Frontend:**
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev # Development
|
||
npm run build # Production build
|
||
npm run export # Статический экспорт
|
||
```
|
||
|
||
## Динамические роуты
|
||
|
||
- `/soap` - калькулятор мыла
|
||
- `/candle` - калькулятор свечей
|
||
- `/[calculatorType]` - любой зарегистрированный калькулятор
|
||
|
||
## Добавление нового калькулятора
|
||
|
||
1. Создать `backend/calculators/[name].js` с модулем
|
||
2. Создать `frontend/lib/calculators/[name].ts` (синхронная структура)
|
||
3. Зарегистрировать в `calculators/index.js` (backend) и `calculators/index.ts` (frontend)
|
||
4. Перезапустить процессы
|
||
|
||
Подробное руководство: `CALCULATOR_GUIDE.md`
|
||
|
||
## Файлы конфигурации
|
||
|
||
- `ecosystem.config.js` - PM2 конфигурация
|
||
- `.gitignore` - игнорирует `.env`, но не `.env.example`
|
||
- `next.config.ts` - Next.js конфигурация (static export)
|
||
|
||
## Логи
|
||
|
||
PM2 логи находятся в:
|
||
- Backend: `~/.pm2/logs/dosoap-backend-*.log`
|
||
- Frontend: `~/.pm2/logs/dosoap-frontend-*.log`
|
||
|
||
## Важные детали
|
||
|
||
1. **Синхронизация схем**: Frontend и backend схемы полей должны совпадать
|
||
2. **Рабочая директория**: Backend должен запускаться из `/backend/` для загрузки `.env`
|
||
3. **CORS**: Настроен для конкретных доменов через `CORS_ORIGINS`
|
||
4. **Статический экспорт**: Frontend экспортируется статически (Next.js export)
|
||
5. **Фото**: Поддерживается загрузка фото, отправляется в Telegram как caption
|
||
|
||
## Структура данных калькулятора
|
||
|
||
### Поле схемы:
|
||
```typescript
|
||
{
|
||
id: string; // Уникальный ID
|
||
name: string; // Имя поля в данных
|
||
label: string; // Метка для пользователя
|
||
type: 'text' | 'number';
|
||
required: boolean;
|
||
group?: string; // Группировка полей (опционально)
|
||
}
|
||
```
|
||
|
||
### Результат расчёта:
|
||
```typescript
|
||
{
|
||
[key: string]: number; // Промежуточные значения
|
||
total: number; // Итоговая себестоимость (обязательно)
|
||
}
|
||
```
|
||
|
||
## Команды Telegram бота
|
||
|
||
- `/menu` - открыть калькулятор (по умолчанию мыло)
|
||
|
||
## Порты
|
||
|
||
- Backend: 3001 (HTTP_PORT из .env)
|
||
- Frontend: 3000 (в development), статический экспорт (production)
|
||
|
||
## Безопасность
|
||
|
||
- Токен бота в `.env` (не в Git)
|
||
- CORS настроен для конкретных доменов
|
||
- Валидация обязательных и числовых полей на backend
|
||
- HTML форматирование в Telegram сообщениях (parse_mode: 'HTML')
|
||
|