refactor: replace ignored numeric literals with constants

This commit is contained in:
2026-09-28 16:37:01 +03:00
committed by ksv741
parent a970eaaf7a
commit b78c215ff1
60 changed files with 510 additions and 283 deletions
@@ -1,3 +1,10 @@
export const FIRST_PAGE = 1;
export const MIN_ENTITY_VERSION = 1;
export const MIN_CATEGORY_NAME_LENGTH = 1;
export const MIN_CARD_NAME_LENGTH = 1;
export const MAX_CARD_NAME_LENGTH = 100;
export const MAX_CATEGORY_NAME_LENGTH = 80;
export const MAX_OPERATION_DESCRIPTION_LENGTH = 500;
@@ -1,4 +1,6 @@
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../common/time';
import { BankOperationKind } from './bank-operation-kind';
import { ZERO_KOPECKS } from './rub-money';
export function moscowToday(now = new Date()): string {
return new Intl.DateTimeFormat('en-CA', {
@@ -10,11 +12,11 @@ export function moscowToday(now = new Date()): string {
}
export function isCalendarDate(value: string): boolean {
if (value.length !== 10 || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
if (value.length !== ISO_DATE_LENGTH || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
if (value.startsWith('0000')) return false;
const date = new Date(`${value}T00:00:00.000Z`);
return (
!Number.isNaN(date.getTime()) && date.toISOString().slice(0, 10) === value
!Number.isNaN(date.getTime()) && date.toISOString().slice(ISO_DATE_START, ISO_DATE_LENGTH) === value
);
}
@@ -63,8 +65,8 @@ export function bankSummary(
kind: string;
}>,
) {
let expenses = 0n;
let refunds = 0n;
let expenses = ZERO_KOPECKS;
let refunds = ZERO_KOPECKS;
const categories = new Map<
string,
{ categoryId: string; expenses: bigint; net: bigint; refunds: bigint }
@@ -81,19 +83,19 @@ export function bankSummary(
const expense =
operation.kind === BankOperationKind.Expense ?
operation.amountKopecks :
0n;
ZERO_KOPECKS;
const refund =
operation.kind === BankOperationKind.Refund ?
operation.amountKopecks :
0n;
ZERO_KOPECKS;
expenses += expense;
refunds += refund;
if (operation.categoryId !== null) {
const category = categories.get(operation.categoryId) ?? {
categoryId: operation.categoryId,
expenses: 0n,
refunds: 0n,
net: 0n,
expenses: ZERO_KOPECKS,
refunds: ZERO_KOPECKS,
net: ZERO_KOPECKS,
};
category.expenses += expense;
category.refunds += refund;
@@ -1,6 +1,10 @@
import type { Money } from '../../../../common/money.types';
import { decimalFromString, formatDecimal } from '../../../../common/decimal';
import { DECIMAL_RADIX, decimalFromString, formatDecimal } from '../../../../common/decimal';
export const ZERO_KOPECKS = 0n;
const RUB_DECIMAL_PLACES = 2;
const MIN_KOPECKS = -9_223_372_036_854_775_808n;
const MAX_KOPECKS = 9_223_372_036_854_775_807n;
@@ -14,14 +18,14 @@ export function parseRubMoney(money: Money, positive = false): bigint {
throw new TypeError('Expected RUB money with a decimal string');
}
const amount = decimalFromString(money.value);
if (amount.scale > 2) {
if (amount.scale > RUB_DECIMAL_PLACES) {
throw new RangeError('RUB money supports at most two decimal places');
}
const kopecks = amount.value * 10n ** BigInt(2 - amount.scale);
const kopecks = amount.value * DECIMAL_RADIX ** BigInt(RUB_DECIMAL_PLACES - amount.scale);
if (kopecks < MIN_KOPECKS || kopecks > MAX_KOPECKS) {
throw new RangeError('RUB money is outside the signed 64-bit range');
}
if (positive && kopecks <= 0n) {
if (positive && kopecks <= ZERO_KOPECKS) {
throw new RangeError('Operation amount must be positive');
}
return kopecks;
@@ -30,6 +34,6 @@ export function parseRubMoney(money: Money, positive = false): bigint {
export function rubMoney(kopecks: bigint): Money {
return {
currency: 'RUB',
value: formatDecimal({ value: kopecks, scale: 2 }),
value: formatDecimal({ value: kopecks, scale: RUB_DECIMAL_PLACES }),
};
}