# Руководство по добавлению нового калькулятора Это руководство описывает, как добавить новый калькулятор в систему DoSoapCalc. ## Архитектура Система использует модульную архитектуру с регистрацией калькуляторов: - Каждый калькулятор — отдельный модуль с формулой, схемой полей и шаблоном сообщения - Общие компоненты автоматически генерируют формы и обрабатывают запросы - Динамическая маршрутизация на основе типа калькулятора ## Шаги добавления нового калькулятора ### 1. Создание модуля калькулятора на Backend Создайте файл `backend/calculators/[calculator-name].js` (например, `candle.js`). #### Структура модуля: ```javascript // calculators/[calculator-name].js const fieldSchema = [ { id: 'itemName', name: 'itemName', label: 'Название изделия', type: 'text', required: true }, { id: 'weight', name: 'weight', label: 'Вес, г', type: 'number', required: true }, // ... другие поля ]; function calculate(data) { // Ваша формула расчёта const total = /* вычисления */; return { // промежуточные результаты total: round(total), }; } function formatMessage(data, result) { // Шаблон сообщения для Telegram let text = `...`; return text; } function getRequiredFields() { return fieldSchema.filter((f) => f.required).map((f) => f.name); } function getNumericFields() { return fieldSchema.filter((f) => f.type === 'number').map((f) => f.name); } module.exports = { id: 'calculator-name', // уникальный ID name: 'Название калькулятора', fieldSchema, calculate, formatMessage, getRequiredFields, getNumericFields, }; ``` #### Пример поля: ```javascript { id: 'fieldId', // уникальный ID поля name: 'fieldName', // имя поля (используется в данных) label: 'Название поля', // метка для пользователя type: 'text' | 'number', // тип поля required: true | false, // обязательное ли поле group: 'packaging', // (опционально) группа для группировки полей } ``` ### 2. Регистрация на Backend Откройте `backend/calculators/index.js` и добавьте калькулятор: ```javascript const newCalculator = require('./[calculator-name]'); const calculators = { soap: soapCalculator, '[calculator-name]': newCalculator, // добавьте здесь }; ``` ### 3. Создание модуля калькулятора на Frontend Создайте файл `frontend/lib/calculators/[calculator-name].ts`. #### Структура модуля: ```typescript // lib/calculators/[calculator-name].ts import type { Calculator, CalculatorField, CalculationResult } from '@/types/calculator'; const fieldSchema: CalculatorField[] = [ { id: 'itemName', name: 'itemName', label: 'Название изделия', type: 'text', required: true }, // ... другие поля (синхронно с backend!) ]; function calculate(data: Record): CalculationResult { // Та же формула, что и на backend return { total: round(total), }; } const newCalculator: Calculator = { id: '[calculator-name]', name: 'Название калькулятора', fieldSchema, calculate, getRequiredFields: () => fieldSchema.filter((f) => f.required).map((f) => f.name), getNumericFields: () => fieldSchema.filter((f) => f.type === 'number').map((f) => f.name), }; export default newCalculator; ``` **Важно:** Схема полей и формула должны совпадать с backend! ### 4. Регистрация на Frontend Откройте `frontend/lib/calculators/index.ts` и добавьте: ```typescript import newCalculator from './[calculator-name]'; const calculators: Record = { soap: soapCalculator, '[calculator-name]': newCalculator, // добавьте здесь }; ``` ### 5. Проверка работы 1. Перезапустите backend: `node bot.js` 2. Пересоберите frontend: `npm run build` 3. Откройте в браузере: `/[calculator-name]?chat_id=YOUR_CHAT_ID` ## Примеры ### Простой калькулятор (только базовые поля) См. файлы: - `backend/calculators/candle.js` - пример калькулятора свечей - `frontend/lib/calculators/candle.ts` - frontend версия ### Калькулятор с группированными полями Для группировки полей используйте параметр `group`: ```javascript { id: 'box', name: 'box', label: 'Пакет', type: 'number', group: 'packaging' }, { id: 'ribbon', name: 'ribbon', label: 'Лента', type: 'number', group: 'packaging' }, ``` Поля с одинаковой группой будут автоматически сгруппированы в форме. ## Советы 1. **Синхронизация:** Всегда поддерживайте синхронизацию между backend и frontend схемами 2. **Валидация:** Используйте `required: true` для обязательных полей 3. **Форматирование:** В `formatMessage` используйте HTML для форматирования (поддерживается Telegram) 4. **Округление:** Используйте функцию `round()` для округления результатов ## Структура файлов ``` backend/ ├── calculators/ │ ├── index.js # Регистрация калькуляторов │ ├── soap.js # Пример: калькулятор мыла │ └── [new-calculator].js # Ваш новый калькулятор frontend/ ├── lib/ │ └── calculators/ │ ├── index.ts # Регистрация калькуляторов │ ├── soap.ts # Пример: калькулятор мыла │ └── [new-calculator].ts # Ваш новый калькулятор ``` ## Что дальше? После добавления калькулятора: 1. Протестируйте расчёты вручную 2. Проверьте отправку в Telegram 3. Убедитесь, что валидация работает корректно 4. Добавьте обработку специфичных данных (если нужно)