9.6 KiB
9.6 KiB
База знаний проекта DoSoap
Назначение проекта
DoSoap - это веб-приложение для расчета себестоимости продукции ручной работы. Пользователи могут:
- Выбрать калькулятор (мыло, свечи и т.д.)
- Ввести параметры продукта
- Получить автоматический расчет себестоимости
- Отправить результат в Telegram-бота
Архитектура системы
Frontend (Next.js)
Структура:
frontend/
app/ # Next.js App Router
page.tsx # Главная страница с меню
layout.tsx # Общий layout
calculators/ # Модули калькуляторов
soap/ # Калькулятор мыла
config.ts # Конфигурация
calc.ts # Функции расчета
candles/ # Калькулятор свечей
config.ts
calc.ts
components/ # React компоненты
CalculatorEngine.tsx # Универсальный движок
CalculatorMenu.tsx # Меню выбора
lib/ # Утилиты и типы
calculator-types.ts # TypeScript типы
calculator-registry.ts # Реестр калькуляторов
docs/ # Документация
calculator-creation-guide.md
Технологии:
- Next.js 15.3.3 с App Router
- React 19
- TypeScript 5
- Tailwind CSS 4
- Статический экспорт (
output: 'export')
Backend (Express + Telegram)
Файлы:
backend/bot.js- основной файл бэкенда
Функционал:
- Обработка POST запросов от фронтенда
- Интеграция с Telegram Bot API
- Загрузка и отправка фотографий
- Форматирование сообщений для Telegram
API:
POST /api/submit- принимает данные расчета и отправляет в Telegram- Команда
/myid- возвращает chat_id пользователя
Типы данных
FieldConfig
Определяет поле ввода в калькуляторе:
{
id: string; // Уникальный ID
type: 'text' | 'number' | 'file';
label: string; // Название поля
defaultValue?: string;
gridCols?: 1 | 2; // Ширина в grid
required?: boolean;
accept?: string; // Для файлов
groupName?: string; // Группа для группировки
showStepAfter?: string; // ID расчета после группы
}
CalculationStep
Шаг расчета (например, "Себестоимость основы"):
{
id: string;
name: string;
formula: (values: Record<string, number>) => number;
formulaDescription?: string;
}
SubtotalConfig
Подитог (например, "Итого себестоимость"):
{
id: string;
name: string;
formula: (values, steps) => number;
highlight?: boolean; // Выделить визуально
formulaDescription?: string;
}
AdditionalCalculation
Дополнительный расчет (например, "Цена за 100г"):
{
id: string;
name: string;
formula: (values, steps, subtotals, additional?) => number;
formulaDescription?: string;
}
Поток работы калькулятора
- Выбор калькулятора: Пользователь выбирает калькулятор в меню
- Загрузка конфигурации:
CalculatorEngineполучает конфигурацию из реестра - Рендеринг полей: Динамически создаются поля на основе
fieldsиз конфигурации - Ввод данных: Пользователь заполняет поля
- Расчет: При изменении полей автоматически пересчитываются все шаги, подитоги и дополнительные расчеты
- Отправка: Данные отправляются на бэкенд через
/api/submit - Telegram: Бэкенд отправляет форматированное сообщение в Telegram
Группировка полей
Поля можно группировать для правильного расположения блоков расчета:
{
id: 'weight',
groupName: 'base', // Группа "base"
showStepAfter: 'base', // После группы показать расчет "base"
}
{
id: 'price',
groupName: 'base', // Тот же группа
}
// Блок расчета "Себестоимость основы" появится здесь
Форматирование Telegram сообщений
Каждый калькулятор может иметь функцию formatTelegramMessage:
formatTelegramMessage: (values, steps, subtotals, additional) => {
let text = `🧼 <b>Расчёт мыла:</b>\n\n`;
text += `💵 Себестоимость: ${subtotals.total.toFixed(1)} ₽\n`;
return text;
}
Если функция не указана, используется универсальное форматирование.
API интеграция
Определение URL
Фронтенд автоматически определяет URL API:
const isLocalhost = window.location.hostname === 'localhost';
const apiUrl = isLocalhost
? 'http://localhost:3001/api/submit'
: 'https://api-dosoap.duckdns.org/api/submit';
Формат запроса
FormData {
chat_id: string;
calculator_id: string;
calculator_name: string;
telegram_message: string; // Готовое сообщение
photo?: File; // Опциональное фото
// ... остальные поля
}
Добавление нового калькулятора
Шаг 1: Создать модуль
mkdir frontend/calculators/my-calc
touch frontend/calculators/my-calc/config.ts
touch frontend/calculators/my-calc/calc.ts # опционально
Шаг 2: Создать конфигурацию
См. frontend/docs/calculator-creation-guide.md
Шаг 3: Зарегистрировать
В frontend/lib/calculator-registry.ts:
import { myCalcConfig } from '@/calculators/my-calc/config';
registerCalculator(myCalcConfig);
Окружение разработки
Платформы
- Разработка: Windows с PowerShell
- Хостинг: Ubuntu Linux
Особенности разработки на Windows
- PowerShell не поддерживает оператор
&&для цепочки команд - Используйте
;или выполняйте команды отдельно - Пути в Git и конфигах всегда используют
/, даже на Windows - При работе через SSH используйте Linux команды
Локальная разработка (Windows + PowerShell)
# Frontend - один терминал
cd frontend
npm install
npm run dev
# Backend - отдельный терминал
cd backend
node bot.js
Деплой
Сервер
- ОС: Ubuntu Linux
- IP: 192.168.0.19
- Пользователь: dosai
- Путь: ~/projects/DoSoapCalc
- Управление процессами: PM2
Процессы PM2
dosoap-frontend- Next.js приложениеdosoap-backend- Express сервер
Команды деплоя
С локального Windows (PowerShell):
# Отправить изменения
git push origin dev
# Подключиться и обновить сервер (Ubuntu команды через SSH)
ssh dosai@192.168.0.19 "cd ~/projects/DoSoapCalc && git pull origin dev && cd frontend && npm run build && pm2 restart dosoap-frontend dosoap-backend"
Или на сервере напрямую (Ubuntu):
cd ~/projects/DoSoapCalc
git pull origin dev
cd frontend && npm run build
pm2 restart dosoap-frontend dosoap-backend
Обработка ошибок
Расчеты
Все формулы должны проверять:
- Деление на ноль → вернуть 0
- Пустые значения → вернуть 0
- NaN → вернуть 0
Пример:
if (weight <= 0 || price <= 0) return 0;
return (weight / 1000) * price;
API запросы
try {
const res = await fetch(apiUrl, { method: 'POST', body: formData });
if (!res.ok) throw new Error('Server error');
} catch (err) {
alert('Ошибка сети при отправке расчёта');
}
Известные особенности
- Статический экспорт: Next.js собирается в статические файлы, нет серверного рендеринга
- Telegram Bot Token: Хранится в переменных окружения на сервере
- Chat ID: Передается через URL параметр
?chat_id=...или через Telegram бота - Фото: Отправляются через FormData, обрабатываются multer на бэкенде