From 302fdf269ec86cdbb04d80501686ed5e6f9b4fe1 Mon Sep 17 00:00:00 2001 From: fedorovvvv Date: Thu, 7 May 2026 19:48:51 +0400 Subject: [PATCH] fix(score): align scorePoller type with forgeplan score --json wrapper shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `forgeplan score --all --json` returns `{ errors, results: ScoreEntry[] }`, but scorePoller was typed as `ScoreEntry[]` and consumers called `.map(...)` directly on the wrapper, throwing `(... ?? []).map is not a function` at runtime in InsightsRail and ForceView (via HomePage's `scores` derived). Introduce ScoreResponse, retype the poller, read `data.results` in the two call sites. No API contract change — endpoint stays a passthrough. Refs: rule 22 (read-only proxy preserved) --- template/src/entities/score/api/store.ts | 4 ++-- template/src/entities/score/index.ts | 2 +- template/src/entities/score/model/types.ts | 5 +++++ template/src/pages/home/ui/HomePage.svelte | 2 +- template/src/widgets/insights-rail/ui/InsightsRail.svelte | 4 +++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/template/src/entities/score/api/store.ts b/template/src/entities/score/api/store.ts index a0183e9..f30a2e9 100644 --- a/template/src/entities/score/api/store.ts +++ b/template/src/entities/score/api/store.ts @@ -1,4 +1,4 @@ import { createPoller } from '@/shared/api'; -import type { ScoreEntry } from '../model/types'; +import type { ScoreResponse } from '../model/types'; -export const scorePoller = createPoller('/api/score', 30_000); +export const scorePoller = createPoller('/api/score', 30_000); diff --git a/template/src/entities/score/index.ts b/template/src/entities/score/index.ts index 40530bc..708c6f3 100644 --- a/template/src/entities/score/index.ts +++ b/template/src/entities/score/index.ts @@ -1,3 +1,3 @@ -export type { ScoreEntry, ReffTone } from './model/types'; +export type { ScoreEntry, ScoreResponse, ReffTone } from './model/types'; export { reffTone, reffRadius, reffBarColor } from './lib/score'; export { scorePoller } from './api/store'; diff --git a/template/src/entities/score/model/types.ts b/template/src/entities/score/model/types.ts index 9eda631..0bb50b6 100644 --- a/template/src/entities/score/model/types.ts +++ b/template/src/entities/score/model/types.ts @@ -3,4 +3,9 @@ export interface ScoreEntry { r_eff: number; } +export interface ScoreResponse { + errors: string[]; + results: ScoreEntry[]; +} + export type ReffTone = 'good' | 'warn' | 'bad'; diff --git a/template/src/pages/home/ui/HomePage.svelte b/template/src/pages/home/ui/HomePage.svelte index eb88ed5..de3999b 100644 --- a/template/src/pages/home/ui/HomePage.svelte +++ b/template/src/pages/home/ui/HomePage.svelte @@ -77,7 +77,7 @@ ? (snapshotStore.current.edges as typeof liveEdges) : liveEdges ); - const scores = $derived(scorePoller.state.data ?? []); + const scores = $derived(scorePoller.state.data?.results ?? []); const globalError = $derived(listPoller.state.error ?? graphPoller.state.error ?? null); function selectNode(detail: { id: string }) { diff --git a/template/src/widgets/insights-rail/ui/InsightsRail.svelte b/template/src/widgets/insights-rail/ui/InsightsRail.svelte index 728b5a3..4b9c59c 100644 --- a/template/src/widgets/insights-rail/ui/InsightsRail.svelte +++ b/template/src/widgets/insights-rail/ui/InsightsRail.svelte @@ -27,7 +27,9 @@ (listPoller.state.data ?? []).filter((a) => a.status.toLowerCase() === 'draft') ); const scoreById = $derived( - new Map((scorePoller.state.data ?? []).map((s) => [s.id, s.r_eff])) + new Map( + (scorePoller.state.data?.results ?? []).map((s) => [s.id, s.r_eff]) + ) ); const kindById = $derived( new Map((listPoller.state.data ?? []).map((a) => [a.id, a.kind]))