DoSoapCalc/CALCULATOR_GUIDE.md

6.9 KiB
Raw Blame History

Руководство по добавлению нового калькулятора

Это руководство описывает, как добавить новый калькулятор в систему DoSoapCalc.

Архитектура

Система использует модульную архитектуру с регистрацией калькуляторов:

  • Каждый калькулятор — отдельный модуль с формулой, схемой полей и шаблоном сообщения
  • Общие компоненты автоматически генерируют формы и обрабатывают запросы
  • Динамическая маршрутизация на основе типа калькулятора

Шаги добавления нового калькулятора

1. Создание модуля калькулятора на Backend

Создайте файл backend/calculators/[calculator-name].js (например, candle.js).

Структура модуля:

// 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,
};

Пример поля:

{
  id: 'fieldId',           // уникальный ID поля
  name: 'fieldName',        // имя поля (используется в данных)
  label: 'Название поля',     // метка для пользователя
  type: 'text' | 'number',  // тип поля
  required: true | false,    // обязательное ли поле
  group: 'packaging',        // (опционально) группа для группировки полей
}

2. Регистрация на Backend

Откройте backend/calculators/index.js и добавьте калькулятор:

const newCalculator = require('./[calculator-name]');

const calculators = {
  soap: soapCalculator,
  '[calculator-name]': newCalculator, // добавьте здесь
};

3. Создание модуля калькулятора на Frontend

Создайте файл frontend/lib/calculators/[calculator-name].ts.

Структура модуля:

// 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<string, any>): 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 и добавьте:

import newCalculator from './[calculator-name]';

const calculators: Record<string, Calculator> = {
  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:

{ 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. Добавьте обработку специфичных данных (если нужно)