Files
iistwin/server/routes/task-inbox-hidden.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

84 lines
2.9 KiB
TypeScript

import { Router } from 'express';
import { authenticateToken, type AuthenticatedRequest } from '../middleware/auth.middleware';
import { tenantIsolation } from '../middleware/tenant.middleware';
import { pool } from '../db';
const taskInboxHiddenRouter = Router();
// Hide a task from the current user's inbox
// Insert or ignore duplicate
taskInboxHiddenRouter.post('/api/tasks/:id/hide-inbox',
authenticateToken,
tenantIsolation,
async (req: AuthenticatedRequest, res) => {
try {
const taskId = parseInt(req.params.id);
if (isNaN(taskId)) return res.status(400).json({ success: false, error: 'Неверный ID задачи' });
const userId = req.user!.id;
const orgId = req.user!.organizationId;
await pool.query(
`INSERT INTO task_inbox_hidden (task_id, user_id, organization_id)
VALUES ($1, $2, $3)
ON CONFLICT (task_id, user_id) DO NOTHING`,
[taskId, userId, orgId]
);
res.json({ success: true });
} catch (err) {
console.error('[hide-inbox]', err);
res.status(500).json({ success: false, error: 'Ошибка при скрытии задачи' });
}
}
);
// Unhide a task for the current user
taskInboxHiddenRouter.delete('/api/tasks/:id/hide-inbox',
authenticateToken,
tenantIsolation,
async (req: AuthenticatedRequest, res) => {
try {
const taskId = parseInt(req.params.id);
if (isNaN(taskId)) return res.status(400).json({ success: false, error: 'Неверный ID задачи' });
const userId = req.user!.id;
const orgId = req.user!.organizationId;
await pool.query(
`DELETE FROM task_inbox_hidden WHERE task_id = $1 AND user_id = $2 AND organization_id = $3`,
[taskId, userId, orgId]
);
res.json({ success: true });
} catch (err) {
console.error('[unhide-inbox]', err);
res.status(500).json({ success: false, error: 'Ошибка при возврате задачи' });
}
}
);
// Check if a task is hidden for the current user
taskInboxHiddenRouter.get('/api/tasks/:id/hide-inbox',
authenticateToken,
tenantIsolation,
async (req: AuthenticatedRequest, res) => {
try {
const taskId = parseInt(req.params.id);
if (isNaN(taskId)) return res.status(400).json({ success: false, error: 'Неверный ID задачи' });
const userId = req.user!.id;
const orgId = req.user!.organizationId;
const result = await pool.query(
`SELECT 1 FROM task_inbox_hidden WHERE task_id = $1 AND user_id = $2 AND organization_id = $3 LIMIT 1`,
[taskId, userId, orgId]
);
res.json({ success: true, isHidden: result.rows.length > 0 });
} catch (err) {
console.error('[get hide-inbox]', err);
res.status(500).json({ success: false, error: 'Ошибка проверки статуса' });
}
}
);
export default taskInboxHiddenRouter;