From: Thibaud Moustier Date: Sun, 1 Mar 2026 17:53:43 +0000 (+0100) Subject: Mobile : Update strategyscreen X-Git-Url: https://git.digitality.be/?a=commitdiff_plain;h=f70b8e97d4993a47a9025dfb37f00ccdb6d2daf5;p=pdw25-26 Mobile : Update strategyscreen --- diff --git a/Wallette/mobile/src/screens/StrategyScreen.tsx b/Wallette/mobile/src/screens/StrategyScreen.tsx index 5c445df..c0583f6 100644 --- a/Wallette/mobile/src/screens/StrategyScreen.tsx +++ b/Wallette/mobile/src/screens/StrategyScreen.tsx @@ -11,14 +11,6 @@ import { fetchStrategies } from "../services/strategyService"; import { selectStrategy } from "../services/api/strategyApi"; -/** - * StrategyScreen - * -------------- - * Maintenant : - * - On garde la liste locale (fetchStrategies) - * - On sync vers serveur : POST /api/strategy/select - * - On met à jour le settings local pour affichage immédiat - */ export default function StrategyScreen() { const [settings, setSettings] = useState(null); const [strategies, setStrategies] = useState([]); @@ -34,7 +26,6 @@ export default function StrategyScreen() { setLoading(true); const [s, list] = await Promise.all([loadSettings(), fetchStrategies()]); if (!active) return; - setSettings(s); setStrategies(list); } finally { @@ -43,7 +34,6 @@ export default function StrategyScreen() { } init(); - return () => { active = false; }; @@ -60,25 +50,31 @@ export default function StrategyScreen() { const isSelected = (key: StrategyKey) => settings.selectedStrategyKey === key; const handleSelect = async (key: StrategyKey) => { + const prev = settings.selectedStrategyKey; + try { setBusy(true); setInfo(null); - // 1) Update local immédiat (UX + dashboard) + // Pair alignée dashboard : BTC + devise settings + const currency = settings.currency === "USD" ? "USD" : "EUR"; + const pair = `BTC/${currency}`; + + // 1) Serveur d’abord (align Stéphane) + await selectStrategy({ pair, mode: key, params: {} }); + + // 2) Puis local (affichage immédiat) const next: UserSettings = { ...settings, selectedStrategyKey: key }; await saveSettings(next); setSettings(next); - // 2) Sync serveur (contrat Stéphane) - // Pair cible : pour l’instant BTC/EUR (comme le dashboard). Si vous passez multi-crypto, on l’adaptera. - await selectStrategy({ - pair: "BTC/EUR", - mode: key, - params: {}, // si un jour tu as des paramètres, tu les mets ici - }); - - setInfo(`Stratégie sélectionnée : ${key} ✅ (sync serveur OK)`); + setInfo(`Stratégie sélectionnée : ${key} ✅`); } catch (e: any) { + // rollback local si besoin + const rollback: UserSettings = { ...settings, selectedStrategyKey: prev }; + await saveSettings(rollback); + setSettings(rollback); + setInfo(`Erreur serveur stratégie : ${e?.message ?? "inconnue"}`); } finally { setBusy(false); @@ -94,9 +90,7 @@ export default function StrategyScreen() { ListHeaderComponent={ Stratégie - - Choisis une stratégie. Elle sera affichée sur le Dashboard. - + Choisis une stratégie. Elle est enregistrée sur le serveur. Actuelle : {settings.selectedStrategyKey} @@ -136,37 +130,11 @@ export default function StrategyScreen() { } const styles = StyleSheet.create({ - safeArea: { - flex: 1, - backgroundColor: ui.screen.backgroundColor, - }, - - boldInline: { - fontWeight: "900", - color: "#0f172a", - }, - - fullButton: { - flexGrow: 0, - flexBasis: "auto", - width: "100%", - marginTop: 12, - }, - - cardSelected: { - borderColor: "#16a34a", - }, - - btnSelected: { - opacity: 0.9, - }, - - btnDisabled: { - opacity: 0.6, - }, - - riskTag: { - fontWeight: "900", - opacity: 0.75, - }, + safeArea: { flex: 1, backgroundColor: ui.screen.backgroundColor }, + boldInline: { fontWeight: "900", color: "#0f172a" }, + fullButton: { flexGrow: 0, flexBasis: "auto", width: "100%", marginTop: 12 }, + cardSelected: { borderColor: "#16a34a" }, + btnSelected: { opacity: 0.9 }, + btnDisabled: { opacity: 0.6 }, + riskTag: { fontWeight: "900", opacity: 0.75 }, }); \ No newline at end of file diff --git a/Wallette/mobile/src/services/api/strategyApi.ts b/Wallette/mobile/src/services/api/strategyApi.ts index 60395ff..d022938 100644 --- a/Wallette/mobile/src/services/api/strategyApi.ts +++ b/Wallette/mobile/src/services/api/strategyApi.ts @@ -3,35 +3,40 @@ import { loadSession } from "../../utils/sessionStorage"; import type { StrategyKey } from "../../types/Strategy"; /** - * strategyApi (API) - * ----------------- - * Contrat (objectif) : + * strategyApi — aligné strategy-service (Stéphane) * POST /api/strategy/select - * Body: - * { - * userId: string, - * pair: "BTC/EUR", - * mode: "RSI_SIMPLE" | "MA_CROSS" | ..., - * params: object - * } + * body: { userId, pairId, mode, params } * - * Réponse possible : - * - { ok:true, data:{ ... } } (géré par http.ts) - * - ou une réponse vide -> on considère que c'est OK si pas d'erreur HTTP + * IMPORTANT: + * - pairId est obligatoire côté serveur. + * - params est mieux en JSON string (stocké DB). */ + +function pairToPairId(pair: string): number { + // Convention du projet : (MarketDataRepo mentionne pairId=1 pour BTC) + const p = pair.trim().toUpperCase(); + if (p.startsWith("BTC/")) return 1; + if (p.startsWith("ETH/")) return 2; + if (p.startsWith("LTC/")) return 3; + throw new Error(`Pair non supportée (pas de pairId) : ${pair}`); +} + export async function selectStrategy(params: { - pair: string; // ex: "BTC/EUR" - mode: StrategyKey; // ex: "RSI_SIMPLE" + pair: string; // ex: "BTC/EUR" + mode: StrategyKey; // ex: "RSI_SIMPLE" params?: Record; }): Promise { const session = await loadSession(); const userId = session?.userId; if (!userId) throw new Error("Session absente : impossible de sélectionner une stratégie."); + const pair = params.pair.trim().toUpperCase(); + const pairId = pairToPairId(pair); + await apiPost(`/strategy/select`, { userId, - pair: params.pair, + pairId, // ✅ requis serveur mode: params.mode, - params: params.params ?? {}, + params: JSON.stringify(params.params ?? {}), // ✅ stockable DB }); } \ No newline at end of file