╔══════════════════════════════════════════════════════════════╗ ║ BET FRIEND — PROYECTO ║ ║ Plataforma Inteligente de Apuestas para Frane ║ ╚══════════════════════════════════════════════════════════════╝ 📅 Creado: Julio 2026 🔗 Subdominio: betfriend.wahandri.com (Basic Auth) 🖥️ Puerto interno: 8090 📂 Ruta: /opt/server/apps/apuestas-radar/ ================================================================================ 1. VISIÓN GENERAL DEL PROYECTO ================================================================================ Construir una plataforma web privada para Frane, un apostador profesional de Bet365 UK que ya ES RENTABLE (200€–5000€/mes). La web no intenta "adivinar resultados" ni sustituir su criterio. Es un EXOESQUELETO que: a) Automatica la búsqueda de oportunidades de valor (escáner pre-partido) b) Usa IA (DeepSeek) para analizar combinadas con contexto real c) Monitoriza partidos en vivo y alerta sobre Cash Out / Freeze óptimos d) Guarda histórico de apuestas para medir rendimiento El objetivo: que Frane deje de pasar horas buscando partidos y pueda tomar decisiones en 5 minutos mirando el dashboard. ================================================================================ 2. INFRAESTRUCTURA DEL SERVIDOR ================================================================================ HARDWARE • Mini PC: Minisforum UM880 Plus • CPU: AMD Ryzen 7 8845HS (8C/16T) • RAM: 32 GB • SSD: 1 TB • SO: Linux Mint 24 RED Internet → Cloudflare Tunnel (cloudflared) → localhost:80 → Caddy → servicios DNS wildcard: *.wahandri.com → Cloudflare UFW: solo 22, 80, 443 fail2ban en SSH y Caddy SSH solo con claves DOCKER (network_mode: host todos) • cloudflared — tunnel • caddy — reverse proxy (:80/:443) • mariadb — base de datos (127.0.0.1:3306) • api — FastAPI central (:8000) • +20 contenedores más (asistente, nova-ws, etc.) CREDENCIALES CLAVE (del .env) • DB: serverdb / serveruser / server_user_2024_seguro • API Key servidor: 0ce8a0e1-96a4-43b9-a8a4-21e505ec0042 • DeepSeek: sk-a6f55623be254e0d995fc80e2f9b861f • Basic Auth Caddy: wahandri / pass hasheada en Caddyfile ESTRUCTURA /opt/server/ ├── docker-compose.yml ← AÑADIR servicio apuestas-radar ├── Caddyfile ← AÑADIR ruteo betfriend.wahandri.com ├── cloudflared/config.yml ← NO TOCAR (wildcard ya cubre) ├── .env ← AÑADIR ODDS_API_KEY ├── apps/apuestas-radar/ ← NUEVO PROYECTO └── compartida/ ← Aquí está este .txt CÓMO AÑADIR UN NUEVO SUBDOMINIO (recordatorio): 1. /opt/server/Caddyfile — meter ruteo en sección :80 y :443 2. docker exec caddy caddy reload --config /etc/caddy/Caddyfile (cloudflared no se toca, el wildcard *.wahandri.com ya cubre) ================================================================================ 3. PERFIL DE FRANE — CÓMO APUESTA (MUY IMPORTANTE) ================================================================================ 3.1. Tipo de Apostador • Estratega de CONTEXTO, no de fórmulas matemáticas fijas • Usa "Bet Builders" de Bet365 UK: combina múltiples mercados del MISMO partido • No intenta adivinar quién gana, busca INEFICIENCIAS en las cuotas • Especialista en trading deportivo: Cash Out / Freeze en el momento óptimo 3.2. Su Estrategia Principal: "Dos Bloques" • BLOQUE ANCLA (Probable): evento muy probable con cuota baja (1.15–1.40) Ej: "Gana Brasil en casa" • BLOQUE MULTIPLICADOR (Factible): evento factible pero con cuota inflada (1.80–2.50+) Ej: "Más tarjetas para Noruega" • La combinada total tiene cuota alta porque la casa de apuestas infravalora la probabilidad del multiplicador 3.3. También Hace: • Longshots: apuestas de cuota MUY alta (40+, 80+, incluso 6000+) con stakes pequeños (1–5€) • Coberturas: cuando una apuesta va bien, mete la contraria para asegurar beneficio • Apuestas de resultados exóticos: "Win to nil", "Ganar ambos tiempos", "Diferencia X goles" • Mercados de jugadores: "Mbappé 3+ tiros a puerta", "Lamine Yamal asiste" 3.4. Factores Clave que Analiza (y que nuestro sistema debe considerar) • Motivación: ¿El equipo se juega algo o ya está eliminado? • Alineaciones: Espera a ver lineups confirmados antes de apostar • Estilo de juego: Físicos vs técnicos, ofensivos vs defensivos • Calidad de plantilla: "Suiza tiene un equipazo", "Los japos son muy físicos" • Condición local: Localía, viajes, anfitrión • Historial: Resultados recientes, cara a cara • Valor de cuota: Detectar cuándo Bet365 está pagando más de lo que debería 3.5. Cómo Gestiona el Dinero • Stakes pequeños: 1–30€ por apuesta combinada • A veces ofrece a amigos para meter más capital y dividir ganancias • Usa bonos y boosts cuando están disponibles • Congela (Cash Out) cuando el escenario favorable se cumple temprano 3.6. Fuentes que Usa • ChatGPT para análisis y validación de ideas • Tipsters como Badmanbetting • Grupo de WhatsApp para discutir apuestas • Observación directa de partidos 3.7. Ejemplo de Razonamiento Real (textual del grupo) "Pensando que, ambos van a atacar y se van a meter mano, d ahí los corners y las tarjetas, el 2-1, no es q me dé mucha confianza, pero en el 1-1, o así ya irían dando algo, siempre y cuando lo demás entre" 3.8. Errores que Reconoce • "Me equivoqué en poner Under 4 corners" • "Brasil nos cago" (apostó en contra) • A veces Bet365 no le deja combinar lo que quiere (límites del Bet Builder) ================================================================================ 4. QUÉ VAMOS A CONSTRUIR — BET FRIEND ================================================================================ 4.1. Stack Tecnológico • Backend: FastAPI (puerto 8090) • Frontend: HTML + CSS + JS vanilla con TailwindCSS (via CDN) • Base de datos: MariaDB (existente, serverdb) • IA: DeepSeek API (pipeline de análisis contextual) • Datos en vivo: Scraping con Playwright headless (Flashscore/SofaScore) • Cuotas: The Odds API (plan gratuito, 500 req/mes) • Tareas programadas: APScheduler • Anti-detección: Playwright Stealth 4.2. Directorio del Proyecto /opt/server/apps/apuestas-radar/ ├── backend/ │ ├── main.py # FastAPI :8090 (endpoints REST + WS) │ ├── models.py # SQLAlchemy (5 tablas) │ ├── config.py # Variables de entorno │ ├── odds_fetcher.py # The Odds API → MariaDB │ ├── live_scraper.py # Playwright → Flashscore (en vivo) │ ├── analyzer.py # DeepSeek pipeline │ └── scheduler.py # APScheduler ├── frontend/ │ ├── index.html # SPA (TailwindCSS) │ └── app.js # Lógica frontend ├── Dockerfile └── requirements.txt 4.3. Endpoints REST GET /api/health → Health check GET /api/opportunities → Oportunidades del día (cuotas con posible valor) GET /api/matches → Lista partidos disponibles con cuotas GET /api/matches/{id} → Detalle partido + histórico POST /api/analyze → match_id + combo → análisis DeepSeek POST /api/bets → Registrar apuesta (activa live tracking) GET /api/bets → Lista apuestas activas/históricas GET /api/stats → Estadísticas de rendimiento 4.4. WebSocket WS /ws/live — El servidor envía eventos en vivo de los partidos seguidos Formato: { type, bet_id, match, event, message, severity } severity: "green" (Cash Out óptimo), "red" (peligro), "yellow" (info) 4.5. Tablas MariaDB (models.py) Match: id, league, home_team, away_team, match_date, status, home_score, away_score, home_motivation, away_motivation, created_at OddsSnapshot: id, match_id, market, bookmaker, price, timestamp Bet: id, match_id, combo_json, total_odds, stake, status, pnl, entry_reason, created_at, closed_at LiveEvent: id, match_id, event_type, team, minute, detail, timestamp Alert: id, bet_id, type, message, profitability_pct, severity, created_at 4.6. Frontend — 3 Paneles PANEL 1: "Hoy" Tabla con oportunidades del día (liga, partido, cuota, confianza) Ordenado por "valor" estimado. Frane hace clic → Panel 2. PANEL 2: "Analizador" Selectores de mercados (checkboxes) con cuotas actualizadas en vivo Botón "Analizar con IA" → llamada POST /api/analyze → respuesta DeepSeek Botón "¡La meto!" → registra apuesta y activa live tracking PANEL 3: "Directo" Tarjetas de partidos activos con timeline de eventos Barra de estado: 🟢 Cash Out / 🔴 Peligro / 🟡 Normal Alerta destacada con efecto visual Diseño responsive (Frane consulta desde el móvil también). 4.7. Flujo Completo del Sistema 1. MADRUGADA (scheduler): odds_fetcher obtiene cuotas de The Odds API (UK, bet365, 2-4 requests). Guarda en MariaDB. 2. MAÑANA: Frane abre dashboard, ve "Oportunidades del día" 3. ANÁLISIS: Selecciona partido, define su Bet Builder, pide análisis a IA 4. DeepSeek recibe contexto estructurado (últimos partidos, cuotas, motivación) y devuelve recomendación razonada 5. APUESTA: Frane mete la apuesta en Bet365 y la registra en la web 6. LIVE: El sistema activa Playwright para scrapear ese partido en Flashscore 7. ALERTAS: Si ocurre evento favorable (ej: underdog marca primero), WebSocket envía alerta verde "Cash Out óptimo ahora" 8. CIERRE: Frane congela en Bet365, registra resultado en la web 9. HISTÓRICO: El sistema acumula datos para medir rendimiento ================================================================================ 5. DECISIONES TOMADAS ================================================================================ ✔ Subdominio: betfriend.wahandri.com ✔ Frontend: HTML+JS+TailwindCSS (SPA, sin frameworks) ✔ Datos en vivo: Scraping Flashscore/SofaScore con Playwright (gratis e ilimitado) ✔ MVP: Escáner pre-partido + Monitor en vivo con WebSocket ✔ Autenticación: Basic Auth de Caddy (usuario wahandri, ya configurado) ✔ The Odds API: Plan gratuito (500 req/mes), solo mercados principales H2H/Spreads/Totals ✔ NO se toca cloudflared/config.yml (wildcard ya cubre *.wahandri.com) ✔ BD usa pymysql (como el resto de apps del servidor) ================================================================================ 6. PREGUNTAS PENDIENTES PARA FRANE (Session 1) ================================================================================ Estas preguntas son para la primera vez que hables con Frane para definir los filtros y reglas del sistema: 1. Mercados: ¿Qué mercados específicos de Bet365 usas más en tus Bet Builders? (Goles, córners, tarjetas, jugadores, resultado exacto, etc.) 2. Liga preferida: ¿Hay alguna liga/competición donde tengas más confianza o mejor histórico? 3. El disparador del Cash Out: Cuando metes una apuesta de "marcar primero y congelar", ¿cómo seleccionas esos partidos? ¿Qué señales te hacen pensar que el underdog puede marcar primero? 4. Filtros fijos: Dame 2-3 reglas fijas que uses para filtrar partidos (ej: "solo equipos con 3+ derrotas seguidas", "solo cuotas > 1.80 y < 3.00") 5. Tamaño de stake: ¿Cómo decides cuánto apostar a cada combinada? (¿% fijo de la banca, según confianza, según cuota?) 6. Alertas en directo: Además de un gol en contra/a favor, ¿qué otros eventos te harían querer congelar una apuesta? (expulsión, lesión del killer, penalti en contra, etc.) 7. Longshots: ¿Qué tipo de longshots (cuotas 40+) te suelen funcionar? ¿Hay algún patrón? ================================================================================ 7. PROMEPT MAESTRO PARA OPENCODE ================================================================================ Cuando quieras empezar a construir, usa este prompt con opencode: --------------------------------------------------------------- Eres un Ingeniero de Software Senior. Crea el proyecto "BetFriend" en /opt/server/apps/apuestas-radar/ siguiendo las especificaciones del archivo /opt/server/compartida/BET_FRIEND_PROYECTO.txt. Paso 1: Lee ese archivo completamente para entender el contexto. Paso 2: Crea la estructura de directorios y todos los archivos base. Paso 3: Implementa en este orden: 1. models.py (5 tablas SQLAlchemy) 2. config.py (variables de entorno) 3. main.py (FastAPI base: health, CORS, lifespan, WS skeleton) 4. frontend/index.html (SPA con TailwindCSS, 3 paneles) 5. frontend/app.js (fetch API + WebSocket con reconexión) 6. odds_fetcher.py (The Odds API consumer) 7. analyzer.py (DeepSeek pipeline) 8. live_scraper.py (Playwright para Flashscore) 9. scheduler.py (APScheduler) 10. Dockerfile y requirements.txt Reglas: - Código sin comentarios - Modular (no todo en main.py) - Manejo de errores en todas las llamadas externas - No exponer API keys - WebSocket con reconexión automática - Usar pymysql para DB - Frontend: TailwindCSS via CDN, JS vanilla Empieza con los archivos base (1-5) y cuando termines muestra el resultado. --------------------------------------------------------------- ================================================================================ 8. RECURSOS / APIS ================================================================================ THE ODDS API • Plan gratuito: 500 requests/mes • Endpoint: https://api.the-odds-api.com/v4/sports/upcoming/odds/ • Parámetros: regions=uk, markets=h2h,spreads,totals, bookmakers=bet365 • Registro: https://the-odds-api.com (gratis, API key por email) DEEPSEEK API • API Key: sk-a6f55623be254e0d995fc80e2f9b861f • Modelo: deepseek-chat • Endpoint: https://api.deepseek.com/v1/chat/completions • Formato: OpenAI-compatible PLAYWRIGHT + STEALTH • playwright install chromium • playwright-stealth (npm o Python) para evitar detección • Web a scrapear: Flashscore.com o Sofascore.com (partidos en vivo) ================================================================================ 9. RECORDATORIO: CONFIGURACIÓN DE CADDY ================================================================================ Añadir esto en /opt/server/Caddyfile (secciones :80 y :443): @betfriend host betfriend.wahandri.com handle @betfriend { basic_auth { wahandri $2a$14$zBT/ZklADBnqt3.jn96i1ekbbCn1.OIxZ31BuOoJCt0mMSpkRpmAK } reverse_proxy localhost:8090 } Después: docker exec caddy caddy reload --config /etc/caddy/Caddyfile ================================================================================ 10. DOCKER-COMPOSE (añadir al existente) ================================================================================ apuestas-radar: build: ./apps/apuestas-radar container_name: apuestas-radar environment: - MARIADB_HOST=127.0.0.1 - MARIADB_PORT=3306 - MARIADB_USER=${MARIADB_USER} - MARIADB_PASSWORD=${MARIADB_PASSWORD} - MARIADB_DATABASE=${MARIADB_DATABASE} - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY} - ODDS_API_KEY=${ODDS_API_KEY} volumes: - ./apps/apuestas-radar:/app - /tmp:/tmp ports: - "8090:8090" network_mode: host restart: always ================================================================================ 11. .env — AÑADIR ================================================================================ # BetFriend ODDS_API_KEY=tu_api_key_de_the_odds_api ================================================================================ FIN DEL DOCUMENTO ================================================================================