#!/usr/bin/env python3 """ User route for API v1 — Telegram alert configuration HRT-79: Alertes Telegram configurables (Premium) GET /api/v1/user/telegram-config — Lire la config Telegram de l'utilisateur connecté POST /api/v1/user/telegram-config — Mettre à jour la config Telegram Accès : Premium / Pro uniquement (@jwt_required_middleware + @plan_required) """ import sqlite3 from flask import Blueprint, jsonify, request from api_v1.utils import internal_error, bad_request # Auth: try flask_jwt_extended (app_v1) first, fall back to saas_auth (portal_server) try: from auth import jwt_required_middleware except ImportError: from saas_auth import require_auth as jwt_required_middleware try: from auth import plan_required except ImportError: plan_required = lambda *a, **kw: (lambda f: f) user_bp = Blueprint("v1_user", __name__, url_prefix="/api/v1/user") # DB_PATH est résolu via la même variable d'env que auth_db.py import os _DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db") def _get_db(): conn = sqlite3.connect(_DB_PATH) conn.row_factory = sqlite3.Row return conn # ── GET /api/v1/user/telegram-config ────────────────────────────────────────── @user_bp.route("/telegram-config", methods=["GET"]) @jwt_required_middleware @plan_required("premium", "pro") def get_telegram_config(): """ Retourne la configuration Telegram de l'utilisateur connecté. --- tags: - Utilisateur summary: Lire la config alertes Telegram (premium+) security: - Bearer: [] responses: 200: description: Configuration Telegram courante schema: properties: telegram_chat_id: type: string nullable: true alert_value_bets: type: boolean alert_top1: type: boolean alert_quinte_only: type: boolean 401: description: Token invalide 403: description: Plan insuffisant """ user_id = request.user_id # injecté par jwt_required_middleware conn = _get_db() try: row = conn.execute( """ SELECT telegram_chat_id, alert_value_bets, alert_top1, alert_quinte_only FROM users WHERE id = ? """, (user_id,), ).fetchone() if not row: return jsonify({"error": "Utilisateur introuvable"}), 404 return jsonify( { "telegram_chat_id": row["telegram_chat_id"], "alert_value_bets": bool(row["alert_value_bets"]), "alert_top1": bool(row["alert_top1"]), "alert_quinte_only": bool(row["alert_quinte_only"]), } ), 200 except sqlite3.OperationalError as exc: # Colonnes absentes : migration non appliquée return jsonify( { "telegram_chat_id": None, "alert_value_bets": True, "alert_top1": True, "alert_quinte_only": False, "_warning": "Migration Telegram non appliquée", } ), 200 except Exception as exc: return internal_error(str(exc)) finally: conn.close() # ── POST /api/v1/user/telegram-config ───────────────────────────────────────── @user_bp.route("/telegram-config", methods=["POST"]) @jwt_required_middleware @plan_required("premium", "pro") def update_telegram_config(): """ Met à jour la configuration Telegram de l'utilisateur connecté. --- tags: - Utilisateur summary: Configurer les alertes Telegram (premium+) security: - Bearer: [] parameters: - in: body name: body required: true schema: properties: telegram_chat_id: type: string description: Chat ID Telegram (ou null pour désactiver) alert_value_bets: type: boolean default: true alert_top1: type: boolean default: true alert_quinte_only: type: boolean default: false responses: 200: description: Configuration mise à jour 400: description: Paramètres invalides 401: description: Token invalide 403: description: Plan insuffisant """ user_id = request.user_id # injecté par jwt_required_middleware data = request.get_json(silent=True) if not data: return bad_request("Corps JSON requis") # Validation et extraction des champs telegram_chat_id = data.get("telegram_chat_id") if telegram_chat_id is not None and not isinstance(telegram_chat_id, str): return bad_request("telegram_chat_id doit être une chaîne ou null") if isinstance(telegram_chat_id, str): telegram_chat_id = telegram_chat_id.strip() or None alert_value_bets = data.get("alert_value_bets", True) alert_top1 = data.get("alert_top1", True) alert_quinte_only = data.get("alert_quinte_only", False) if not isinstance(alert_value_bets, bool): return bad_request("alert_value_bets doit être un booléen") if not isinstance(alert_top1, bool): return bad_request("alert_top1 doit être un booléen") if not isinstance(alert_quinte_only, bool): return bad_request("alert_quinte_only doit être un booléen") conn = _get_db() try: conn.execute( """ UPDATE users SET telegram_chat_id = ?, alert_value_bets = ?, alert_top1 = ?, alert_quinte_only = ? WHERE id = ? """, ( telegram_chat_id, int(alert_value_bets), int(alert_top1), int(alert_quinte_only), user_id, ), ) conn.commit() return jsonify( { "status": "ok", "telegram_chat_id": telegram_chat_id, "alert_value_bets": alert_value_bets, "alert_top1": alert_top1, "alert_quinte_only": alert_quinte_only, } ), 200 except sqlite3.OperationalError as exc: return jsonify( { "error": "Migration Telegram non appliquée — contacter le support", "detail": str(exc), } ), 500 except Exception as exc: return internal_error(str(exc)) finally: conn.close()