refactor: align frontend ownership boundaries
Close audit gaps across API drift, query policy, UI, and tests.
This commit is contained in:
@@ -12,13 +12,9 @@ import {
|
||||
} from "@/entities/brokerage-event";
|
||||
import { type IncomeSummary, useIncomeSummary } from "@/entities/income";
|
||||
import type { Portfolio } from "@/entities/portfolio";
|
||||
import {
|
||||
formatMoney,
|
||||
formatShare,
|
||||
instrumentLogoUrl,
|
||||
portfolioErrorCode,
|
||||
usePortfolio,
|
||||
} from "@/entities/portfolio";
|
||||
import { formatShare, usePortfolio } from "@/entities/portfolio";
|
||||
import { apiErrorCode } from "@/shared/api";
|
||||
import { formatMoney, instrumentLogoUrl } from "@/shared/lib";
|
||||
|
||||
type PositionSectionKind = "stocks" | "bonds" | "other";
|
||||
type AccountPageReturnTone = "positive" | "negative";
|
||||
@@ -32,7 +28,6 @@ type AccountPagePosition = Portfolio["positions"][number] & {
|
||||
|
||||
type AccountPagePositionSection = {
|
||||
kind: PositionSectionKind;
|
||||
wide: boolean;
|
||||
positions: AccountPagePosition[];
|
||||
};
|
||||
|
||||
@@ -108,7 +103,7 @@ function useAccountPageViewModel(): AccountPageViewModel {
|
||||
if (portfolio.isError)
|
||||
return {
|
||||
state: "error" as const,
|
||||
code: portfolioErrorCode(portfolio.error),
|
||||
code: apiErrorCode(portfolio.error),
|
||||
retry: () => portfolio.refetch(),
|
||||
};
|
||||
return { state: "loading" as const };
|
||||
@@ -188,9 +183,9 @@ function toAccountPagePositionSections(
|
||||
(denominators.get(currency) ?? 0) + Number(position.currentValue.value),
|
||||
);
|
||||
}
|
||||
const stocks = toSection("stocks", true, portfolio, denominators);
|
||||
const bonds = toSection("bonds", true, portfolio, denominators);
|
||||
const other = toSection("other", false, portfolio, denominators);
|
||||
const stocks = toSection("stocks", portfolio, denominators);
|
||||
const bonds = toSection("bonds", portfolio, denominators);
|
||||
const other = toSection("other", portfolio, denominators);
|
||||
return [stocks, bonds, other].filter(
|
||||
(section) => section.positions.length > 0,
|
||||
);
|
||||
@@ -198,28 +193,27 @@ function toAccountPagePositionSections(
|
||||
|
||||
function toSection(
|
||||
kind: PositionSectionKind,
|
||||
wide: boolean,
|
||||
portfolio: Portfolio,
|
||||
denominators: Map<string, number>,
|
||||
): AccountPagePositionSection {
|
||||
return {
|
||||
kind,
|
||||
wide,
|
||||
positions: portfolio.positions
|
||||
.filter((position) => {
|
||||
if (kind === "stocks") return position.type === "STOCK";
|
||||
if (kind === "bonds") return position.type === "BOND";
|
||||
return position.type !== "STOCK" && position.type !== "BOND";
|
||||
})
|
||||
.map((position) => toPosition(position, denominators, wide)),
|
||||
.map((position) => toPosition(position, denominators, kind)),
|
||||
};
|
||||
}
|
||||
|
||||
function toPosition(
|
||||
position: Portfolio["positions"][number],
|
||||
denominators: Map<string, number>,
|
||||
wide: boolean,
|
||||
kind: PositionSectionKind,
|
||||
): AccountPagePosition {
|
||||
const expanded = kind !== "other";
|
||||
const returnValue = position.absoluteReturn
|
||||
? Number(position.absoluteReturn.value)
|
||||
: null;
|
||||
@@ -238,10 +232,10 @@ function toPosition(
|
||||
})
|
||||
: null,
|
||||
returnText: position.absoluteReturn
|
||||
? `${wide && returnValue !== null && returnValue > 0 ? "+" : ""}${formatMoney(position.absoluteReturn)}`
|
||||
? `${expanded && returnValue !== null && returnValue > 0 ? "+" : ""}${formatMoney(position.absoluteReturn)}`
|
||||
: null,
|
||||
returnTone,
|
||||
logoSrc: wide ? instrumentLogoUrl(position.logoName) : null,
|
||||
logoSrc: expanded ? instrumentLogoUrl(position.logoName) : null,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user