Files
iistwin/server/routes/bot-subscriptions.routes.ts
Ильяс Султанов 1f5ecb6da4 fix(number-fields): избегаем потери точности длинных чисел
- number-поля теперь рендерятся как text + inputMode=numeric,
  чтобы браузер не округлял значения через input type=number
- пробелы при вставке в number-поля удаляются
- бэкенд нормализует значения number-полей в строку перед сохранением
- добавлен хелпер normalizeFieldValueForStorage

Closes: искажение расчётного счёта и других длинных числовых полей
2026-07-07 21:03:40 +03:00

131 lines
4.8 KiB
TypeScript

import { storage } from "../storage";
import { authenticateToken, requirePermission, type AuthenticatedRequest } from "../middleware/auth.middleware";
import { tenantIsolation } from "../middleware/tenant.middleware";
import { validateRequest } from "../middleware/validation.middleware";
import { createBotSubscriptionSchema } from "@shared/schema";
export function registerBotSubscriptionRoutes(app: import("express").Express): void {
// Delete bot (admin only)
app.delete('/api/bots/:id',
authenticateToken,
requirePermission('bots.manage'),
tenantIsolation,
async (req: AuthenticatedRequest, res) => {
try {
const botId = parseInt(req.params.id);
if (isNaN(botId)) {
return res.status(400).json({ success: false, error: 'Некорректный ID бота' });
}
const bot = await storage.getBot(botId, req.organizationId!);
if (!bot) {
return res.status(404).json({ success: false, error: 'Бот не найден' });
}
await storage.deleteBot(botId, req.organizationId!);
res.json({ success: true, message: 'Бот удален' });
} catch (error) {
console.error('Delete bot error:', error);
res.status(500).json({ success: false, error: 'Ошибка при удалении бота' });
}
}
);
// Get bot subscriptions
app.get('/api/bots/:id/subscriptions',
authenticateToken,
requirePermission('bots.manage'),
tenantIsolation,
async (req: AuthenticatedRequest, res) => {
try {
const botId = parseInt(req.params.id);
if (isNaN(botId)) {
return res.status(400).json({ success: false, error: 'Некорректный ID бота' });
}
const bot = await storage.getBot(botId, req.organizationId!);
if (!bot) {
return res.status(404).json({ success: false, error: 'Бот не найден' });
}
const subscriptions = await storage.getBotSubscriptions(botId, req.organizationId!);
res.json({ success: true, subscriptions });
} catch (error) {
console.error('Get bot subscriptions error:', error);
res.status(500).json({ success: false, error: 'Ошибка при получении подписок бота' });
}
}
);
// Create bot subscription
app.post('/api/bots/:id/subscriptions',
authenticateToken,
requirePermission('bots.manage'),
tenantIsolation,
validateRequest(createBotSubscriptionSchema),
async (req: AuthenticatedRequest, res) => {
try {
const botId = parseInt(req.params.id);
if (isNaN(botId)) {
return res.status(400).json({ success: false, error: 'Некорректный ID бота' });
}
const bot = await storage.getBot(botId, req.organizationId!);
if (!bot) {
return res.status(404).json({ success: false, error: 'Бот не найден' });
}
const { subscriptionType, formId, statusId, transitionId, events, filters } = req.body;
const subscription = await storage.createBotSubscription({
botId,
organizationId: req.organizationId!,
subscriptionType,
formId: formId || null,
statusId: statusId || null,
transitionId: transitionId || null,
events,
filters: filters || null,
isActive: true
});
res.status(201).json({ success: true, message: 'Подписка создана', subscription });
} catch (error) {
console.error('Create bot subscription error:', error);
res.status(500).json({ success: false, error: 'Ошибка при создании подписки' });
}
}
);
// Delete bot subscription
app.delete('/api/bots/:botId/subscriptions/:subscriptionId',
authenticateToken,
requirePermission('bots.manage'),
tenantIsolation,
async (req: AuthenticatedRequest, res) => {
try {
const botId = parseInt(req.params.botId);
const subscriptionId = parseInt(req.params.subscriptionId);
if (isNaN(botId) || isNaN(subscriptionId)) {
return res.status(400).json({ success: false, error: 'Некорректный ID' });
}
const bot = await storage.getBot(botId, req.organizationId!);
if (!bot) {
return res.status(404).json({ success: false, error: 'Бот не найден' });
}
await storage.deleteBotSubscription(subscriptionId, req.organizationId!);
res.json({ success: true, message: 'Подписка удалена' });
} catch (error) {
console.error('Delete bot subscription error:', error);
res.status(500).json({ success: false, error: 'Ошибка при удалении подписки' });
}
}
);
}