# 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 = { 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')