# اصلاح بازار داینامیک، نمودار یکپارچه، و حذف CAD→IRT **تاریخ:** 2026-07-19 **محیط:** staging — https://shahoo.fibitex.com/ **وابستگی:** Shahoo-BFF (ریپوی جدا) --- ## ۱. خلاصه مشکل | # | علامت | علت ریشه‌ای | |---|--------|-------------| | ۱ | لیست بازار ثابت (IRT/USDT) | آرایه‌های hardcode در UI | | ۲ | ارزهای اضافی/کم (مثلاً BNB نیست، LINK هست) | `CURRENCY.TYPE` + `IRTitems`/`USDTitems` ثابت | | ۳ | نمودار USDT = Binance | `TradingViewWidget` به‌جای datafeed داخلی | | ۴ | CAD به‌عنوان quote پشتیبانی نمی‌شود | UI فقط IRT/USDT؛ chart برای CAD `null` | | ۵ | CAD→IRT در BFF (legacy) | `normalizeCurrencyForShahoo` — دیگر لازم نیست؛ IRT روی سرور فعال است | --- ## ۲. وضعیت فعلی staging (baseline) API stats روی staging (2026-07-19): ``` BNB_CAD, BNB_IRT, BNB_USDT, BTC_CAD, BTC_IRT, BTC_USDT, ETH_CAD, ETH_IRT, ETH_USDT, IRT_IRT, USDT_CAD, USDT_IRT ``` - **IRT** و **CAD** هر دو quote مستقل روی Peatio/Dena فعال‌اند. - BFF endpoint `GET /api/1/ohlcvs/tradingView?market=BTC_USDT` داده صرافی برمی‌گرداند ✅ - UI هنوز از hardcode استفاده می‌کند ❌ --- ## ۳. اهداف (Definition of Done) - [x] لیست بازارها و quote currencies (**IRT, USDT, CAD**) از API لود شوند - [x] تب‌های sidebar/header/popover داینامیک باشند - [x] فقط markets فعال Peatio نمایش داده شوند - [x] نمودار **همه** quoteها از `TVChartContainer` + BFF `/ohlcvs/tradingView` - [x] mapping **CAD→IRT** از BFF حذف شود - [ ] QA روی `shahoo.fibitex.com` سبز + redeploy images --- ## ۴. معماری هدف ``` Peatio (Dena) GET /public/markets GET /public/currencies ↓ Shahoo-BFF GET /api/1/markets/catalog ← جدید (public) GET /api/1/ohlcvs/stats ← موجود GET /api/1/ohlcvs/tradingView ← موجود ↓ Shahoo SPA MarketsContext (bootstrap، بدون login) MarketListPanel (تب quote + لیست base) TVChartContainer (IRT | USDT | CAD) ``` --- ## ۵. قرارداد API پیشنهادی — `GET /api/1/markets/catalog` **Auth:** public (بدون token) **منبع BFF:** `denaClient.getMarkets()` + `denaClient.getCurrencies()` ```json { "statusCode": 200, "content": { "quoteCurrencies": ["IRT", "USDT", "CAD"], "marketsByQuote": { "IRT": ["BTC", "ETH", "BNB", "USDT"], "USDT": ["BTC", "ETH", "BNB"], "CAD": ["BTC", "ETH", "BNB", "USDT"] }, "markets": [ { "marketId": "btcirt", "marketKey": "BTC_IRT", "base": "BTC", "quote": "IRT", "symbol": "BTCIRT", "route": "BTC-IRT", "enabled": true, "amountPrecision": 6, "pricePrecision": 2 } ] } } ``` **قوانین mapping BFF:** - فقط markets با `state: enabled` - `marketKey` = `{BASE}_{QUOTE}` (uppercase) - `route` = `{BASE}-{QUOTE}` (مطابق react-router Shahoo) - `symbol` = `{BASE}{QUOTE}` (مطابق TradingView datafeed) - **بدون** تبدیل CAD→IRT --- ## ۶. فازبندی و اولویت ### فاز ۱ — 🔴 فوری | ID | تسک | repo | فایل(ها) | وضعیت | |----|------|------|----------|--------| | **T1.1** | یکپارچه‌سازی نمودار: حذف `TradingViewWidget`؛ `TVChartContainer` برای IRT/USDT/CAD | Shahoo | `MarketChart/index.js` | ✅ | | **T1.2** | حذف CAD→IRT در BFF | Shahoo-BFF | `mapMarket.js`, `userPrefs.js`, `mapTransaction.js`, … | ✅ | **T1.1 جزئیات:** ```js // قبل: USDT → TradingViewWidget (Binance embed) // بعد: همه quoteها → TVChartContainer + Datafeed → /api/1/ohlcvs/tradingView ``` symbol اولیه: `{BASE}{QUOTE}` — مثلاً `BTCUSDT`, `BTCIRT`, `BTCCAD` --- ### فاز ۲ — 🔴 BFF catalog | ID | تسک | repo | فایل(ها) | وضعیت | |----|------|------|----------|--------| | **T2.1** | Endpoint `GET /api/1/markets/catalog` | Shahoo-BFF | `routes/markets.js`, `lib/mapMarketsCatalog.js` | ✅ | | **T2.2** | حذف/جایگزینی `SHAAHO_CURRENCIES` whitelist | Shahoo-BFF | `mapMarket.js`, `mapConstants.js` | ✅ | --- ### فاز ۳ — 🔴 Shahoo UI داینامیک | ID | تسک | repo | فایل(ها) | وضعیت | |----|------|------|----------|--------| | **T3.1** | `MarketsContext` + `useMarkets` + fetch bootstrap | Shahoo | `context/marketsContext.js`, `api/markets.js`, `Layout/App` | ✅ | | **T3.2** | کامپوننت مشترک `MarketListPanel` | Shahoo | `MarketListPanel/` | ✅ | | **T3.3** | refactor سه فایل تکراری → `MarketListPanel` | Shahoo | `MarketSelectCurrency`, `MarketSelectTab`, `MarketDropDown` | ✅ | | **T3.4** | `CURRENCY.TYPE` → fallback | Shahoo | `core/utils/getCurrencyMeta.js` | ✅ | **فایل‌های hardcode برای حذف/جایگزینی:** ``` src/features/Market/MainComponents/MarketSelectCurrency/index.js → IRTitems, USDTitems src/features/Market/MainComponents/MarketHeader/.../MarketSelectTab/index.js src/features/PopOverComponents/Market/MarketDropDown/index.js ``` --- ### فاز ۴ — 🟡 سطوح ثانویه | ID | تسک | repo | فایل(ها) | وضعیت | |----|------|------|----------|--------| | **T4.1** | `SwitchCurrency` — تب quote داینامیک | Shahoo | `SwitchCurrency/index.js` | ✅ | | **T4.2** | Landing — لیست از catalog | Shahoo | `Landing/pages/index.js` | ✅ | | **T4.3** | TradingView datafeed — symbols داینامیک | Shahoo | `datafeeds/datafeed.js` | ✅ | | **T4.4** | `MarketChart` — symbol از catalog | Shahoo | `MarketChart/index.js` | ✅ | | **T4.5** | WatchList — quote از destMarket | Shahoo | `WatchList/index.js` | ✅ | | **T4.6** | Route guard — redirect به market معتبر | Shahoo | `Market/pages/index.js` | ✅ | --- ### فاز ۵ — 🟢 QA + Deploy | ID | تسک | وضعیت | |----|------|--------| | **T5.1** | تب IRT/USDT/CAD فقط markets واقعی Peatio | ⬜ | | **T5.2** | BNB در لیست؛ LINK/LTC بدون market نباشند | ⬜ | | **T5.3** | نمودار BTC-USDT / BTC-IRT / BTC-CAD — داده صرافی | ⬜ | | **T5.4** | Wallet: balance IRT و CAD جدا | ⬜ | | **T5.5** | Order book + place order روی BNB-USDT | ⬜ | | **T5.6** | Rebuild `custom/shahoo:1` + `custom/shahoo-bff:1` + redeploy staging | ⬜ | --- ## ۷. مسیر بحرانی (Critical Path) ``` T1.2 → T2.1 → T3.1 → T3.2 → T3.3 ↑ T1.1 (موازی — می‌توان همزمان با T1.2 شروع کرد) ↓ T4.* → T5.* ``` **ترتیب پیشنهادی اجرا:** 1. T1.1 + T1.2 (نمودار + پاکسازی BFF) 2. T2.1 + T2.2 (catalog API) 3. T3.1 → T3.3 (UI داینامیک) 4. T4.* (polish) 5. T5.* (QA staging) **تخمین:** ۴–۵ روز کاری --- ## ۸. تست دستی (staging) ```bash # statMap — کلیدهای IRT/USDT/CAD curl -s https://shahoo.fibitex.com/api/1/ohlcvs/stats | jq '.content.statMap | keys' # catalog (بعد از T2.1) curl -s https://shahoo.fibitex.com/api/1/markets/catalog | jq . # نمودار USDT از صرافی (بعد از T1.1) curl -s "https://shahoo.fibitex.com/api/1/ohlcvs/tradingView?market=BTC_USDT&resolution=240&from=1700000000&to=1800000000" | jq '.content | length' ``` **چک UI:** - [ ] `/market/BNB-IRT` — لیست + قیمت + نمودار - [ ] `/market/BTC-USDT` — نمودار Fibitex (نه Binance watermark) - [ ] `/market/BTC-CAD` — صفحه باز شود (بعد از T1.1/T3) --- ## ۹. خارج از scope (این سند) - حذف کامل `CURRENCY.TYPE` (فقط به fallback تبدیل می‌شود) - فیچرهای ایران (Jibit/Vandar/IRT Pay) **Real-time (Rango WebSocket):** برنامه جدا — [02-rango-websocket-plan.md](./02-rango-websocket-plan.md) شروع توصیه‌شده: **بعد از T3.1 MarketsContext** (marketId برای subscribe). --- ## ۱۰. Todo checklist (کپی برای commit/PR) ``` فاز ۱ [x] T1.1 MarketChart → TVChartContainer برای همه quote [x] T1.2 BFF: حذف CAD→IRT فاز ۲ [x] T2.1 BFF: GET /api/1/markets/catalog [x] T2.2 BFF: SHAAHO_CURRENCIES → dynamic فاز ۳ [x] T3.1 MarketsContext + useMarkets + api/markets.js [x] T3.2 MarketListPanel (کامپوننت مشترک) [x] T3.3 refactor MarketSelectCurrency / MarketSelectTab / MarketDropDown [x] T3.4 CURRENCY.TYPE fallback + getCurrencyMeta فاز ۴ [x] T4.1 SwitchCurrency داینامیک [x] T4.2 Landing از catalog [x] T4.3 datafeed symbols داینامیک [x] T4.4 MarketChart symbol از context [x] T4.5 WatchList quote selector [x] T4.6 Route guard market معتبر فاز ۵ [ ] T5 QA staging + redeploy ``` **مرحله بعد (real-time):** [02-rango-websocket-plan.md](./02-rango-websocket-plan.md) --- ## ۱۱. commit message convention ``` T1.1: unify market chart on TVChartContainer for all quotes T2.1: add GET /api/1/markets/catalog from Dena public API T3.2: replace hardcoded IRTitems/USDTitems with MarketListPanel ```