""" viewer_server.py — Application Entrypoint This file was refactored from a 2800-line monolith into a clean entrypoint. All business logic has been moved to the `backend/` package: backend/ ├── __init__.py ← App Factory (create_app) ├── config.py ← All config & environment variables ├── api/ ← Flask Blueprints (routes/controllers) │ ├── auth.py │ ├── books.py │ ├── payment.py │ ├── translate.py │ ├── epub.py │ └── developer.py ├── services/ ← Business logic layer │ ├── auth_service.py │ ├── book_service.py │ ├── payment_service.py │ ├── email_service.py │ ├── epub_service.py │ └── translation.py ├── database/ │ └── db_manager.py ← DB connections, circuit breaker, caches ├── core/ │ ├── security.py ← JWT, bcrypt helpers │ ├── decorators.py ← @jwt_required, @require_api_key_auth │ └── rate_limit.py ← IP rate limiters └── workers/ └── email_worker.py ← Background IMAP/Gmail email polling To run the server: python viewer_server.py Or with gunicorn: gunicorn -w 4 -b 0.0.0.0:5051 "viewer_server:app" """ import logging import sys import traceback from flask import jsonify from backend.core.logger import setup_logger logger = setup_logger("server") from backend import create_app app = create_app() @app.errorhandler(Exception) def handle_exception(e): """Global unhandled exception handler to output clean JSON in production.""" # Log the complete stack trace error_msg = f"Unhandled exception encountered: {str(e)}" stack_trace = traceback.format_exc() logger.error(error_msg) logger.error(stack_trace) # Trigger asynchronous alert email to Admin try: from backend.services.alert_service import send_alert_to_admin subject = f"Lỗi nghiêm trọng (500 Internal Error): {str(e)[:50]}" body = f"Đã xảy ra lỗi chưa xử lý trên server:
Lỗi: {str(e)}

Stack Trace:
{stack_trace.replace(chr(10), '
')}" send_alert_to_admin("critical_error", subject, body) except Exception as alert_err: logger.error(f"Failed to trigger alert email for exception: {alert_err}") # Return JSON response instead of HTML traceback page return jsonify({ "error": "Internal Server Error. Please contact administrator.", "success": False }), 500 @app.route("/api/temp-db-fix", methods=["GET"]) def temp_db_fix(): from flask import request secret = request.args.get("secret") if secret != "super_secret_db_fix_2026": return "Unauthorized", 403 import os import psycopg2 url = os.environ.get("DATABASE_URL") if not url: return "DATABASE_URL environment variable is missing", 500 logs = [] try: conn = psycopg2.connect(url) cursor = conn.cursor() # 1. Clean up user 75 tables_to_clean = [ "refresh_tokens", "bookshelf", "reading_history", "password_reset_tokens", "api_keys", "api_usage", "translation_history", "vocabulary", "user_settings", "usage_tracking", "personal_notifications", "login_history" ] for tbl in tables_to_clean: try: cursor.execute(f"DELETE FROM {tbl} WHERE user_id = 75") logs.append(f"✔ Cleaned {tbl} for user_id = 75") except Exception as e: logs.append(f"ℹ Could not clean {tbl} for user_id = 75: {e}") try: cursor.execute("DELETE FROM users WHERE id = 75") logs.append("✔ Deleted user 75 from users table") except Exception as e: logs.append(f"❌ Failed to delete user 75: {e}") # 2. Link VIP user congkx123789 to Gmail cursor.execute("SELECT id, username, email, vip_status FROM users WHERE username = %s OR id = 100", ("congkx123789",)) vip_user = cursor.fetchone() if vip_user: vip_id = vip_user[0] cursor.execute(""" UPDATE users SET email = %s, google_id = NULL, email_verified = 1 WHERE id = %s """, ("havucong25@gmail.com", vip_id)) logs.append(f"✔ Linked VIP user {vip_user[1]} (ID {vip_id}) to havucong25@gmail.com") else: logs.append("❌ VIP user congkx123789 not found in database") conn.commit() conn.close() return jsonify({"success": True, "logs": logs}) except Exception as e: return jsonify({"success": False, "error": str(e), "logs": logs}) if __name__ == "__main__": logger.info("🚀 Server đang khởi động tại: http://localhost:5051") app.run(host="0.0.0.0", port=5051, debug=False, threaded=True)