diff --git a/api_tokens_db.py b/api_tokens_db.py index ee2b732..dc9b774 100644 --- a/api_tokens_db.py +++ b/api_tokens_db.py @@ -13,7 +13,9 @@ logger = logging.getLogger("turf_saas.api_tokens_db") def get_db() -> sqlite3.Connection: - conn = sqlite3.connect(DB_PATH) + """Return a SQLite connection (reads TURF_SAAS_DB dynamically for test isolation).""" + db_path = os.environ.get("TURF_SAAS_DB", DB_PATH) + conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row return conn diff --git a/api_v1/routes/history.py b/api_v1/routes/history.py index 7151f2e..3b9ab15 100644 --- a/api_v1/routes/history.py +++ b/api_v1/routes/history.py @@ -20,7 +20,11 @@ from api_v1.utils import ( get_pagination_params, paginate_query, ) -from saas_auth import require_auth as jwt_required_middleware +# 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 history_bp = Blueprint("v1_history", __name__, url_prefix="/api/v1/history") diff --git a/api_v1/routes/ml_feedback.py b/api_v1/routes/ml_feedback.py index aaa6972..ab0735a 100644 --- a/api_v1/routes/ml_feedback.py +++ b/api_v1/routes/ml_feedback.py @@ -20,7 +20,11 @@ from flask import Blueprint, jsonify, request, g sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) from api_v1.utils import get_db, internal_error, bad_request -from saas_auth import require_auth as jwt_required_middleware +# 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: diff --git a/api_v1/routes/user.py b/api_v1/routes/user.py index 3f3cc45..8fa6fa4 100644 --- a/api_v1/routes/user.py +++ b/api_v1/routes/user.py @@ -13,7 +13,11 @@ import sqlite3 from flask import Blueprint, jsonify, request from api_v1.utils import internal_error, bad_request -from saas_auth import require_auth as jwt_required_middleware +# 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: diff --git a/api_v1/utils.py b/api_v1/utils.py index 6718f19..e6a5f4c 100644 --- a/api_v1/utils.py +++ b/api_v1/utils.py @@ -16,8 +16,9 @@ DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db") def get_db(): - """Return a SQLite connection with Row factory.""" - conn = sqlite3.connect(DB_PATH) + """Return a SQLite connection with Row factory (reads TURF_SAAS_DB dynamically).""" + db_path = os.environ.get("TURF_SAAS_DB", DB_PATH) + conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row return conn diff --git a/auth_db.py b/auth_db.py index 05eb1df..452e347 100644 --- a/auth_db.py +++ b/auth_db.py @@ -8,11 +8,15 @@ HRT-79: migration Telegram columns import sqlite3 import os +# NOTE: DB_PATH kept for backward compat, but get_db() reads env at call time +# so test isolation works correctly when TURF_SAAS_DB is set per-module. DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db") def get_db(): - conn = sqlite3.connect(DB_PATH) + # Read env dynamically so test overrides of TURF_SAAS_DB are respected + db_path = os.environ.get("TURF_SAAS_DB", DB_PATH) + conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row return conn diff --git a/requirements.txt b/requirements.txt index e366177..ecfc8ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,3 +31,6 @@ python-dotenv==1.1.0 # Utilities python-dateutil==2.9.0 + +# Hyperparameter optimization (ML ensemble tuning — HRT-136) +optuna>=4.0.0 diff --git a/tests/test_history.py b/tests/test_history.py index 877282a..a9e5da0 100644 --- a/tests/test_history.py +++ b/tests/test_history.py @@ -52,6 +52,9 @@ def auth_header(token: str) -> dict: @pytest.fixture(scope="module") def app(): + # Enforce this module s temp DB + os.environ["TURF_SAAS_DB"] = _tmp_db.name + os.environ["JWT_SECRET_KEY"] = "test-history-secret-key" application = create_app() application.config["TESTING"] = True application.config["JWT_SECRET_KEY"] = "test-history-secret-key" @@ -70,7 +73,14 @@ def seeded_db(): - Create ml_predictions_cache with rows spanning 120 days back - Create users for free/premium/pro plans """ - db_path = os.environ["TURF_SAAS_DB"] + # Reset TURF_SAAS_DB to this module-s temp DB at runtime + os.environ["TURF_SAAS_DB"] = _tmp_db.name + db_path = _tmp_db.name + + # Ensure auth tables (users, refresh_tokens, subscriptions) exist in the test DB + # init_auth_tables() is idempotent — safe to call even if tables already exist + init_auth_tables() + conn = sqlite3.connect(db_path) # Create ml_predictions_cache table if absent @@ -124,7 +134,9 @@ def auth_tokens(client, seeded_db): assert r.status_code in (201, 409), f"register failed for {plan}: {r.data}" # Set plan via direct DB - db_path = os.environ["TURF_SAAS_DB"] + # Reset TURF_SAAS_DB to this module-s temp DB at runtime + os.environ["TURF_SAAS_DB"] = _tmp_db.name + db_path = _tmp_db.name conn = sqlite3.connect(db_path) for plan, email in plans.items(): conn.execute("UPDATE users SET plan = ? WHERE email = ?", (plan, email)) diff --git a/tests/test_user_tokens.py b/tests/test_user_tokens.py index 8b444ff..07315f8 100644 --- a/tests/test_user_tokens.py +++ b/tests/test_user_tokens.py @@ -36,6 +36,7 @@ os.environ["JWT_SECRET_KEY"] = "test-secret-hrt80" sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from app_v1 import create_app # noqa: E402 +from api_tokens_db import migrate_api_tokens_tables # noqa: E402 TEST_CONFIG = { "TESTING": True, @@ -45,6 +46,10 @@ TEST_CONFIG = { @pytest.fixture(scope="module") def app(): + # Enforce this module s temp DB at fixture runtime + os.environ["TURF_SAAS_DB"] = _tmp_db.name + os.environ["JWT_SECRET_KEY"] = "test-secret-hrt80" + migrate_api_tokens_tables() # ensure tables exist in THIS module s temp DB application = create_app() application.config.update(TEST_CONFIG) yield application