import type { DashboardSummary, TradeDecision, AlertLevel } from "../../types/DashboardSummary";
-import type { Alert } from "../../types/Alert";
-
import { loadSession } from "../../utils/sessionStorage";
import { loadSettings } from "../../utils/settingsStorage";
-
+import { apiGet } from "./http";
import { getCurrentPrice } from "./priceApi";
-import { getAlertHistory } from "./alertsApi";
function safeDecision(action: any): TradeDecision {
const a = String(action ?? "HOLD").toUpperCase();
return "INFO";
}
+/**
+ * dashboardApi (contrat Stéphane - STRICT)
+ * ---------------------------------------
+ * - GET /api/price/current?pair=BTC/EUR
+ * - GET /api/signal/current?userId=...&pair=BTC/EUR
+ */
export async function getDashboardSummary(): Promise<DashboardSummary> {
const session = await loadSession();
const userId = session?.userId;
const settings = await loadSettings();
const currency: "EUR" | "USD" = settings.currency === "USD" ? "USD" : "EUR";
+ // Dashboard strict : BTC seulement (align web). Adaptable plus tard.
const pair = `BTC/${currency}`;
+ // 1) Prix (service prix)
const price = await getCurrentPrice(pair);
- let decision: TradeDecision = "HOLD";
- let alertLevel: AlertLevel = "INFO";
- let confidence = 0;
- let reason = "Aucune alerte récente.";
- let timestamp = price.timestampMs;
+ // 2) Signal (service stratégies)
+ const sig = await apiGet<any>(
+ `/signal/current?userId=${encodeURIComponent(userId)}&pair=${encodeURIComponent(pair)}`
+ );
- try {
- const events = await getAlertHistory(10);
- const last: Alert | undefined = events[0];
+ const decision = safeDecision(sig?.action ?? sig?.decision);
+ const alertLevel = safeLevel(sig?.alertLevel ?? sig?.level ?? sig?.criticality);
+ const confidence = typeof sig?.confidence === "number" ? sig.confidence : 0;
+ const reason = String(sig?.reason ?? sig?.message ?? "—");
- if (last) {
- decision = safeDecision(last.action);
- alertLevel = safeLevel(last.alertLevel);
- confidence = typeof last.confidence === "number" ? last.confidence : 0;
- reason = String(last.reason ?? last.message ?? "—");
- timestamp = typeof last.timestamp === "number" ? last.timestamp : timestamp;
- }
- } catch {
- // non bloquant
- }
+ const timestamp =
+ typeof sig?.timestamp === "number"
+ ? sig.timestamp
+ : typeof sig?.timestamp_ms === "number"
+ ? sig.timestamp_ms
+ : price.timestampMs;
return {
pair,
import { loadSession } from "../../utils/sessionStorage";
import type { PortfolioState } from "../../models/Portfolio";
-type WalletListItem = { id?: string; walletId?: string; _id?: string };
+/**
+ * walletApi (contrat Stéphane - STRICT)
+ * ------------------------------------
+ * - GET /api/wallets?userId=...
+ * - GET /api/wallets/:id
+ * - GET /api/wallets/:id/events
+ */
+
type WalletListResponse = any;
function pickWalletId(list: any): string | null {
Array.isArray(list) ? list :
Array.isArray(list?.wallets) ? list.wallets :
Array.isArray(list?.items) ? list.items :
+ Array.isArray(list?.data) ? list.data :
null;
if (!arr || arr.length === 0) return null;
- const first = arr[0];
+ const first = arr[0];
return (
(typeof first?.walletId === "string" && first.walletId) ||
(typeof first?.id === "string" && first.id) ||
return [];
}
-export async function getPortfolio(): Promise<PortfolioState> {
+export async function getPrimaryWalletId(): Promise<string | null> {
const session = await loadSession();
const userId = session?.userId;
- if (!userId) throw new Error("Session absente : impossible de charger le portefeuille.");
+ if (!userId) throw new Error("Session absente : impossible de charger les wallets.");
const list = await apiGet<WalletListResponse>(`/wallets?userId=${encodeURIComponent(userId)}`);
- const walletId = pickWalletId(list);
+ return pickWalletId(list);
+}
+export async function getPortfolio(): Promise<PortfolioState> {
+ const walletId = await getPrimaryWalletId();
if (!walletId) return { assets: [], updatedAtMs: Date.now() };
const details = await apiGet<any>(`/wallets/${encodeURIComponent(walletId)}`);
const assets = extractAssets(details);
return { assets, updatedAtMs: Date.now() };
+}
+
+export type WalletEvent = {
+ id?: string;
+ type?: string; // BUY/SELL
+ symbol?: string; // BTC
+ quantity?: number;
+ price?: number;
+ timestamp?: number;
+};
+
+export async function getWalletEvents(limit = 50): Promise<WalletEvent[]> {
+ const walletId = await getPrimaryWalletId();
+ if (!walletId) return [];
+
+ const data = await apiGet<any>(
+ `/wallets/${encodeURIComponent(walletId)}/events?limit=${encodeURIComponent(String(limit))}`
+ );
+
+ if (Array.isArray(data)) return data as WalletEvent[];
+ if (Array.isArray(data?.events)) return data.events as WalletEvent[];
+ if (Array.isArray(data?.items)) return data.items as WalletEvent[];
+ return [];
}
\ No newline at end of file