refactor: centralize domain values and enforce numeric lint
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { MILLISECONDS_PER_SECOND } from '../../../../common/time';
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
@@ -15,6 +16,7 @@ import { AccountReferenceDto } from '../../account-reference.dto';
|
||||
import { DateOnlyRange, dateOnlyBounds } from '../../investment-calendar';
|
||||
import {
|
||||
BrokerageOperationDto,
|
||||
DEFAULT_OPERATIONS_PAGE_SIZE,
|
||||
BrokerageOperationsPageDto,
|
||||
BrokerageOperationsQueryDto,
|
||||
} from '../presentation/brokerage-operation.dto';
|
||||
@@ -23,6 +25,8 @@ import {
|
||||
operationCategory,
|
||||
} from '../infrastructure/brokerage-operation.mapper';
|
||||
|
||||
const CONTINUATION_TTL_MS = 300_000;
|
||||
|
||||
type OperationStream = {
|
||||
account: AccountReferenceDto;
|
||||
pending: BrokerageOperationDto[];
|
||||
@@ -54,7 +58,7 @@ export class BrokerageOperationsService {
|
||||
AllOperationsContinuation
|
||||
>({
|
||||
max: 100,
|
||||
ttl: 5 * 60_000,
|
||||
ttl: CONTINUATION_TTL_MS,
|
||||
ttlAutopurge: true,
|
||||
});
|
||||
|
||||
@@ -86,7 +90,10 @@ export class BrokerageOperationsService {
|
||||
query.instrumentUid && !query.from
|
||||
? {
|
||||
...range,
|
||||
from: new Date(Number(account.openedDate?.seconds ?? 0) * 1000),
|
||||
from: new Date(
|
||||
Number(account.openedDate?.seconds ?? 0) *
|
||||
MILLISECONDS_PER_SECOND,
|
||||
),
|
||||
}
|
||||
: range,
|
||||
),
|
||||
@@ -108,7 +115,7 @@ export class BrokerageOperationsService {
|
||||
from: query.from ?? null,
|
||||
to: query.to ?? null,
|
||||
categories: [...new Set(query.categories ?? [])].sort(),
|
||||
limit: query.limit ?? 100,
|
||||
limit: query.limit ?? DEFAULT_OPERATIONS_PAGE_SIZE,
|
||||
});
|
||||
const continuation = query.cursor
|
||||
? this.continuations.get(query.cursor)
|
||||
@@ -178,7 +185,7 @@ export class BrokerageOperationsService {
|
||||
): Promise<BrokerageOperationsPageDto> {
|
||||
const items: BrokerageOperationDto[] = [];
|
||||
// Each stream retains unconsumed rows. A page boundary never discards them.
|
||||
while (items.length < (query.limit ?? 100)) {
|
||||
while (items.length < (query.limit ?? DEFAULT_OPERATIONS_PAGE_SIZE)) {
|
||||
for (const stream of streams) {
|
||||
while (!stream.pending.length && !stream.finished) {
|
||||
const page = await this.page(
|
||||
@@ -324,7 +331,9 @@ export class BrokerageOperationsService {
|
||||
accountId,
|
||||
async ({ token, generation, account }) => {
|
||||
const accountOpenedAt = account.openedDate?.seconds
|
||||
? new Date(Number(account.openedDate.seconds) * 1000)
|
||||
? new Date(
|
||||
Number(account.openedDate.seconds) * MILLISECONDS_PER_SECOND,
|
||||
)
|
||||
: undefined;
|
||||
const selected =
|
||||
typeof ranges === 'function' ? ranges(accountOpenedAt) : ranges;
|
||||
@@ -395,7 +404,7 @@ export class BrokerageOperationsService {
|
||||
from: seconds(range.from),
|
||||
to: seconds(range.to, /^\d{4}-\d{2}-\d{2}$/.test(query.to ?? '')),
|
||||
cursor: query.cursor,
|
||||
limit: query.limit ?? 100,
|
||||
limit: query.limit ?? DEFAULT_OPERATIONS_PAGE_SIZE,
|
||||
state: 'OPERATION_STATE_EXECUTED',
|
||||
...(query.instrumentUid ? { instrumentId: query.instrumentUid } : {}),
|
||||
});
|
||||
@@ -480,7 +489,7 @@ function cacheKey(
|
||||
categories,
|
||||
instrumentUid: query.instrumentUid ?? null,
|
||||
cursor: query.cursor ?? null,
|
||||
limit: query.limit ?? 100,
|
||||
limit: query.limit ?? DEFAULT_OPERATIONS_PAGE_SIZE,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -493,7 +502,7 @@ function dateBoundary(value: string | undefined, end: boolean): Date | null {
|
||||
|
||||
function seconds(value: Date, endOfSecond = false) {
|
||||
return {
|
||||
seconds: Math.floor(value.valueOf() / 1000).toString(),
|
||||
seconds: Math.floor(value.valueOf() / MILLISECONDS_PER_SECOND).toString(),
|
||||
...(endOfSecond ? { nanos: 999_999_999 } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user