""" api/routes/adaptive_meds.py - API endpoints for adaptive medication settings """ import flask import jwt import os import core.postgres as postgres import core.adaptive_meds as adaptive_meds JWT_SECRET = os.getenv("JWT_SECRET") def _get_user_uuid(request): """Extract and validate user UUID from JWT token.""" auth_header = request.headers.get("Authorization", "") if not auth_header.startswith("Bearer "): return None token = auth_header[7:] try: payload = jwt.decode(token, JWT_SECRET, algorithms=["HS256"]) return payload.get("sub") except jwt.ExpiredSignatureError: return None except jwt.InvalidTokenError: return None def register(app): @app.route("/api/adaptive-meds/settings", methods=["GET"]) def get_adaptive_settings(): """Get user's adaptive medication settings.""" user_uuid = _get_user_uuid(flask.request) if not user_uuid: return flask.jsonify({"error": "Unauthorized"}), 401 settings = adaptive_meds.get_adaptive_settings(user_uuid) if not settings: # Return defaults return flask.jsonify( { "adaptive_timing_enabled": False, "adaptive_mode": "shift_all", "presence_tracking_enabled": False, "nagging_enabled": True, "nag_interval_minutes": 15, "max_nag_count": 4, "quiet_hours_start": None, "quiet_hours_end": None, } ), 200 return flask.jsonify( { "adaptive_timing_enabled": settings.get( "adaptive_timing_enabled", False ), "adaptive_mode": settings.get("adaptive_mode", "shift_all"), "presence_tracking_enabled": settings.get( "presence_tracking_enabled", False ), "nagging_enabled": settings.get("nagging_enabled", True), "nag_interval_minutes": settings.get("nag_interval_minutes", 15), "max_nag_count": settings.get("max_nag_count", 4), "quiet_hours_start": settings.get("quiet_hours_start"), "quiet_hours_end": settings.get("quiet_hours_end"), } ), 200 @app.route("/api/adaptive-meds/settings", methods=["PUT"]) def update_adaptive_settings(): """Update user's adaptive medication settings.""" user_uuid = _get_user_uuid(flask.request) if not user_uuid: return flask.jsonify({"error": "Unauthorized"}), 401 data = flask.request.get_json() if not data: return flask.jsonify({"error": "No data provided"}), 400 # Validate required fields if enabling adaptive timing if data.get("adaptive_timing_enabled"): if not data.get("adaptive_mode"): return flask.jsonify( {"error": "adaptive_mode is required when enabling adaptive timing"} ), 400 # Build update data update_data = { "adaptive_timing_enabled": data.get("adaptive_timing_enabled", False), "adaptive_mode": data.get("adaptive_mode", "shift_all"), "presence_tracking_enabled": data.get("presence_tracking_enabled", False), "nagging_enabled": data.get("nagging_enabled", True), "nag_interval_minutes": data.get("nag_interval_minutes", 15), "max_nag_count": data.get("max_nag_count", 4), "quiet_hours_start": data.get("quiet_hours_start"), "quiet_hours_end": data.get("quiet_hours_end"), } # Check if settings exist existing = adaptive_meds.get_adaptive_settings(user_uuid) if existing: postgres.update( "adaptive_med_settings", update_data, {"user_uuid": user_uuid} ) else: update_data["user_uuid"] = user_uuid postgres.insert("adaptive_med_settings", update_data) return flask.jsonify({"success": True}), 200 @app.route("/api/adaptive-meds/presence", methods=["GET"]) def get_presence_status(): """Get user's Discord presence status.""" user_uuid = _get_user_uuid(flask.request) if not user_uuid: return flask.jsonify({"error": "Unauthorized"}), 401 presence = adaptive_meds.get_user_presence(user_uuid) if not presence: return flask.jsonify( {"is_online": False, "last_online_at": None, "typical_wake_time": None} ), 200 typical_wake = adaptive_meds.calculate_typical_wake_time(user_uuid) return flask.jsonify( { "is_online": presence.get("is_currently_online", False), "last_online_at": presence.get("last_online_at").isoformat() if presence.get("last_online_at") else None, "last_offline_at": presence.get("last_offline_at").isoformat() if presence.get("last_offline_at") else None, "typical_wake_time": typical_wake.strftime("%H:%M") if typical_wake else None, } ), 200 @app.route("/api/adaptive-meds/schedule", methods=["GET"]) def get_today_schedule(): """Get today's adaptive medication schedule.""" user_uuid = _get_user_uuid(flask.request) if not user_uuid: return flask.jsonify({"error": "Unauthorized"}), 401 from datetime import date today = date.today() # Get all medications for user meds = postgres.select("medications", {"user_uuid": user_uuid, "active": True}) schedule_data = [] for med in meds: med_id = med.get("id") med_schedules = postgres.select( "medication_schedules", { "user_uuid": user_uuid, "medication_id": med_id, "adjustment_date": today, }, ) for sched in med_schedules: schedule_data.append( { "medication_id": med_id, "medication_name": med.get("name"), "base_time": sched.get("base_time"), "adjusted_time": sched.get("adjusted_time"), "adjustment_minutes": sched.get("adjustment_minutes", 0), "status": sched.get("status", "pending"), "nag_count": sched.get("nag_count", 0), } ) return flask.jsonify(schedule_data), 200