feat: show persisted investment data and sync state

Consume the provided resource-envelope API snapshot. Preserve financial snapshots during
refresh, observe synchronization without importing, and fence late responses across
account and connection changes.
This commit is contained in:
2026-09-26 21:22:49 +03:00
parent b987fd8e78
commit 4e5f564fa1
81 changed files with 4714 additions and 1420 deletions
+38 -27
View File
@@ -1,4 +1,5 @@
import { HttpResponse, http } from "msw";
import { resource } from "@/test/resource";
const authentication = {
accessToken: "test-token",
@@ -26,40 +27,50 @@ const handlers = [
"*/api/v1/tbank-connection",
() => new HttpResponse(null, { status: 204 }),
),
http.get("*/api/v1/brokerage-accounts", () => HttpResponse.json([])),
http.get("*/api/v1/brokerage-accounts", () =>
HttpResponse.json(resource([])),
),
http.get("*/api/v1/brokerage-accounts/:accountId/portfolio", () =>
HttpResponse.json({
lastSuccessfulAt: "2026-08-14T00:00:00Z",
isStale: false,
totalsByCurrency: [],
positions: [],
structure: { currencies: [], unvaluedCategories: [] },
cashBalances: [],
}),
HttpResponse.json(
resource({
lastSuccessfulAt: "2026-08-14T00:00:00Z",
isStale: false,
totalsByCurrency: [],
positions: [],
structure: { currencies: [], unvaluedCategories: [] },
cashBalances: [],
}),
),
),
http.get("*/api/v1/brokerage-accounts/:accountId/operations", () =>
HttpResponse.json({
accountId: "account-1",
items: [],
nextCursor: null,
hasNext: false,
observedAt: "2026-08-14T00:00:00Z",
}),
HttpResponse.json(
resource({
accountId: "account-1",
items: [],
nextCursor: null,
hasNext: false,
observedAt: "2026-08-14T00:00:00Z",
}),
),
),
http.get("*/api/v1/brokerage-accounts/:accountId/events", () =>
HttpResponse.json({
accountId: "account-1",
calculatedAt: "2026-08-14T00:00:00Z",
events: [],
}),
HttpResponse.json(
resource({
accountId: "account-1",
calculatedAt: "2026-08-14T00:00:00Z",
events: [],
}),
),
),
http.get("*/api/v1/brokerage-accounts/:accountId/income-summary", () =>
HttpResponse.json({
accountId: "account-1",
period: { from: "2026-01-01", to: "2026-08-14" },
totalsByCurrency: [],
calculatedAt: "2026-08-14T00:00:00Z",
}),
HttpResponse.json(
resource({
accountId: "account-1",
period: { from: "2026-01-01", to: "2026-08-14" },
totalsByCurrency: [],
calculatedAt: "2026-08-14T00:00:00Z",
}),
),
),
];
+21
View File
@@ -0,0 +1,21 @@
import type { paths } from "@/shared/api";
type Meta =
paths["/api/v1/brokerage-accounts"]["get"]["responses"][200]["content"]["application/json"]["meta"];
function resource<T>(data: T, meta: Partial<Meta> = {}) {
return {
data,
meta: {
resourceKey: "fixture",
dataRevision: "1",
stateVersion: "1",
availability: data === null ? "missing" : "complete",
freshness: "fresh",
lastSuccessfulAt: "2026-08-14T00:00:00Z",
sync: { id: null, state: "idle", errorCode: null },
...meta,
} satisfies Meta,
};
}
export { resource };