FCS-dev
Se migrΓ³ la configuraciΓ³n de alertas Telegram desde una variable de entorno global () hacia campos propios del modelo en la base de datos. Cada usuario configura su propio bot token, chat ID y activaciΓ³n de alertas desde el panel web.
6112db7 | # CLAUDE.md | |
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | |
| ## Project Overview | |
| **PolySignal** β a real-time prediction market intelligence dashboard. It fetches market data from Polymarket, enriches it with financial news via Finnhub, runs AI sentiment analysis (ModernFinBERT + Qwen3-8B), and displays signals on an interactive world map. No real trading β pure analysis and virtual simulation. Built for CIFO Barcelona La Violeta Hackathon (May 2026). UI and docs are in **Spanish**, base currency is **Euro (β¬)**. | |
| ## Common Commands | |
| ```bash | |
| # Development (backend + frontend simultaneously) | |
| npm run dev:all | |
| # Backend only (with --watch) | |
| npm run dev | |
| # Frontend only (Vite @ :5173) | |
| npm run dev:frontend | |
| # Production build (frontend) | |
| npm run build:frontend | |
| # Database | |
| npm run db:migrate # Apply Prisma migrations | |
| npm run db:generate # Regenerate Prisma client | |
| npm run db:studio # Open Prisma Studio GUI | |
| # Docker | |
| docker-compose up --build # Full stack on port 7860 | |
| ``` | |
| Node.js **β₯24.0.0** is required (enforced in package.json engines). | |
| First-time setup: | |
| ```bash | |
| npm install | |
| cp .env.example .env # then fill in API keys | |
| npm run db:migrate && npm run db:generate | |
| ``` | |
| ## Architecture | |
| Monorepo with two workspaces: `backend/` (Express 5 + Socket.io) and `frontend/` (Vanilla JS + Vite). | |
| ### Backend (`backend/src/`) | |
| Follows a strict **Controller β Service β Repository β Client** layered pattern. Each domain lives in its own directory: | |
| | Directory | Responsibility | | |
| |-----------|---------------| | |
| | `markets/` | Polymarket Gamma API client + sync job | | |
| | `signals/` | AI pipeline (aiPipeline.js) + signals service | | |
| | `finnhub/` | Finnhub news client + service | | |
| | `positions/` | Virtual position simulator + Kelly Criterion sizing | | |
| | `watchlist/` | User-saved markets | | |
| | `alerts/` | Telegram Bot notification delivery | | |
| | `auth/` | JWT + bcryptjs login | | |
| | `socket/` | Socket.io broadcaster | | |
| | `middlewares/` | Auth, validation, error handling, rate limiting | | |
| | `utils/` | Pino logger, HTTP client, Prisma singleton | | |
| Entry points: `src/index.js` (HTTP server + Socket.io setup) β `src/app.js` (Express middleware + route mounting) β `src/scheduler.js` (cron jobs). | |
| Environment/config validated at startup via **Zod** in `src/config.js` β the app crashes fast if required env vars are missing. | |
| ### Scheduler Jobs | |
| | Job | Frequency | What it does | | |
| |-----|-----------|-------------| | |
| | `syncMarkets` | 30s | Fetches top 100 active Polymarket markets, broadcasts price changes via Socket.io | | |
| | `generateSignals` | 5m | Runs full AI pipeline on top 20 active markets | | |
| | `updatePositionsPnL` | 30s | Recalculates P&L for open virtual positions | | |
| | `processAlerts` | 1m | Checks watchlist thresholds, fires Telegram alerts | | |
| ### AI Signal Pipeline (`signals/aiPipeline.js`) | |
| Three-phase flow with automatic fallbacks: | |
| 1. **News filtering** β Finnhub headlines β ModernFinBERT (HF Space) β keep only scores β₯ 0.65, drop neutral | |
| 2. **Signal generation** β market data + filtered news β Qwen3-8B (HF Space) β `{ signal, confidence, summary, keyRisk }` | |
| 3. **Fallback chain**: HF Space β HF direct inference API β OpenRouter (deepseek-chat) β rule-based (price-trend logic) | |
| ### Frontend (`frontend/src/`) | |
| Single-page app with no framework. Key modules: | |
| | File | Role | | |
| |------|------| | |
| | `app.js` | SPA routing, DOM rendering, Socket.io listeners | | |
| | `api.js` | REST client wrapper with JWT token management | | |
| | `map.js` | Leaflet world map (bubble size = volume, color = signal) | | |
| | `charts.js` | Chart.js sparklines + 7-day price history | | |
| | `simulator.js` | Virtual buy/sell logic | | |
| | `filters.js` | Market filtering by category, country, continent, trend | | |
| Vite proxies `/api` and `/socket.io` to backend (`localhost:7860`) during development. | |
| ### Database (SQLite via Prisma) | |
| Schema at `backend/prisma/schema.prisma`. Key models: | |
| - `Market` β Polymarket data (prices, volume, category, country code) | |
| - `AISignal` β sentiment signals with confidence and risk summary | |
| - `Position` β virtual trades with entry/exit prices and P&L | |
| - `Watchlist` / `Alert` β user market tracking and Telegram history | |
| - `User` β auth + optional Telegram chat ID | |
| ### Real-time Communication | |
| REST API at `/api/v1/*` + WebSocket events via Socket.io: | |
| - `market_update` β price/volume changes | |
| - `ai_signal` β new sentiment signals | |
| - `price_alert` β watchlist threshold triggers | |
| ## Deployment Target | |
| The app is designed to run on **HuggingFace Spaces** (port 7860). The Dockerfile uses `node:22-slim`, installs backend deps, copies the frontend `dist/`, runs Prisma generate, and starts the server. The frontend is served as static files by Express in production. | |
| ## Key Environment Variables | |
| See `.env.example` for the full list. Critical ones: | |
| ``` | |
| HF_SPACE_MODERNFINBERT_URL # HuggingFace Space for FinBERT | |
| HF_SPACE_QWEN_URL # HuggingFace Space for Qwen3-8B | |
| HF_TOKEN # HF inference API key (fallback) | |
| OPENROUTER_API_KEY # LLM fallback if HF is down | |
| FINNHUB_API_KEY # News source | |
| JWT_SECRET # Must be β₯32 characters | |
| PORT=7860 # Required by HF Spaces | |
| DATABASE_URL=file:./backend/prisma/polysignal.db | |
| ``` | |