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

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

44 lines
2.0 KiB
TypeScript

import { type Express } from "express";
import { query } from "./db-client";
import { authenticateToken, requirePermission, type AuthenticatedRequest } from "../middleware/auth.middleware";
export function registerOverrideRoutes(app: Express): void {
// GET /api/overrides?type=income|expense
app.get("/api/overrides", authenticateToken, requirePermission('finance.manage'), async (req: AuthenticatedRequest, res) => {
try {
const type = req.query.type as string;
const table = type === "expense" ? "expense_category_overrides" : "income_category_overrides";
const result = await query(`SELECT record_id, category_id, created_at FROM "${table}"`);
res.json({ success: true, overrides: result.rows });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
// POST /api/overrides
app.post("/api/overrides", authenticateToken, requirePermission('finance.manage'), async (req: AuthenticatedRequest, res) => {
try {
const { type, recordId, categoryId } = req.body;
const table = type === "expense" ? "expense_category_overrides" : "income_category_overrides";
await query(
`INSERT INTO "${table}" (record_id, category_id) VALUES ($1, $2) ON CONFLICT (record_id) DO UPDATE SET category_id = EXCLUDED.category_id`,
[recordId, categoryId]
);
res.json({ success: true });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
// DELETE /api/overrides/:type/:recordId
app.delete("/api/overrides/:type/:recordId", authenticateToken, requirePermission('finance.manage'), async (req: AuthenticatedRequest, res) => {
try {
const table = req.params.type === "expense" ? "expense_category_overrides" : "income_category_overrides";
await query(`DELETE FROM "${table}" WHERE record_id = $1`, [req.params.recordId]);
res.json({ success: true });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
}