chore: strengthen backend eslint profile

This commit is contained in:
2026-09-28 16:37:01 +03:00
committed by ksv741
parent 53b2794963
commit a970eaaf7a
179 changed files with 4485 additions and 2716 deletions
@@ -1,4 +1,5 @@
import { BadRequestException } from '@nestjs/common';
import type { InvestmentScreenDto } from './tbank-sync.dto';
// Reject fields from other screens before reserving any source work.
@@ -41,68 +42,78 @@ export function normalizeScreen(
});
};
if (!allowed[input.screen]) fail();
for (const key of Object.keys(input))
for (const key of Object.keys(input)) {
if (
key !== 'screen' &&
input[key as keyof InvestmentScreenDto] !== undefined &&
!allowed[input.screen].includes(key)
)
) {
fail();
}
}
const accountId = input.accountId?.trim();
const query = input.query?.trim().toUpperCase();
if (
['account', 'operations', 'income', 'events'].includes(input.screen) &&
['account', 'events', 'income', 'operations'].includes(input.screen) &&
!accountId
)
) {
fail();
if (
['stocks', 'bonds'].includes(input.screen) &&
(!query || query.length < 2)
)
fail();
if (['stock', 'bond'].includes(input.screen) && !input.instrumentUid) fail();
if (input.accountId !== undefined && !accountId) fail();
if (['income', 'events'].includes(input.screen)) {
if (input.screen === 'income' && Boolean(input.from) !== Boolean(input.to))
fail();
for (const value of [input.from, input.to])
if (value && !/^\d{4}-\d{2}-\d{2}$/.test(value)) fail();
}
if (input.from && input.to && new Date(input.from) > new Date(input.to))
if (
['bonds', 'stocks'].includes(input.screen) &&
(!query || query.length < 2)
) {
fail();
}
if (['bond', 'stock'].includes(input.screen) && !input.instrumentUid) fail();
if (input.accountId !== undefined && !accountId) fail();
if (['events', 'income'].includes(input.screen)) {
if (input.screen === 'income' && Boolean(input.from) !== Boolean(input.to)) {
fail();
}
for (const value of [input.from, input.to]) {
if (value && !/^\d{4}-\d{2}-\d{2}$/.test(value)) fail();
}
}
if (input.from && input.to && new Date(input.from) > new Date(input.to)) {
fail();
}
if (
input.screen === 'events' &&
input.to &&
(input.from ?? new Date().toISOString().slice(0, 10)) > input.to
)
) {
fail();
}
if (
input.candleRange &&
new Date(input.candleRange.from) >= new Date(input.candleRange.to)
)
) {
fail();
}
// Fixed field order is part of coalescing, irrespective of JSON input order.
return {
screen: input.screen,
...(accountId ? { accountId } : {}),
...(input.from ? { from: input.from } : {}),
...(input.to ? { to: input.to } : {}),
...(input.instrumentUid
? { instrumentUid: input.instrumentUid.toLowerCase() }
: {}),
...(input.instrumentUid ?
{ instrumentUid: input.instrumentUid.toLowerCase() } :
{}),
...(query ? { query } : {}),
...(input.candlePeriod ? { candlePeriod: input.candlePeriod } : {}),
...(input.candleRange
? {
...(input.candleRange ?
{
candleRange: {
from: new Date(input.candleRange.from).toISOString(),
to: new Date(input.candleRange.to).toISOString(),
},
}
: {}),
...(input.categories
? { categories: [...new Set(input.categories)].sort() }
: {}),
} :
{}),
...(input.categories ?
// eslint-disable-next-line sonarjs/no-alphabetical-sort -- Code-unit ordering is intentional for canonical keys and ISO dates; locale collation would change persisted bindings.
{ categories: [...new Set(input.categories)].sort() } :
{}),
...(input.limit !== undefined ? { limit: input.limit } : {}),
};
}