""" Routine Steps Extended API - instructions, step types, and media for steps """ import os import uuid import flask import jwt import core.auth as auth import core.postgres as postgres def _get_user_uuid(token): try: payload = jwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"]) return payload.get("sub") except (jwt.ExpiredSignatureError, jwt.InvalidTokenError): return None def _auth(request): header = request.headers.get("Authorization", "") if not header.startswith("Bearer "): return None token = header[7:] user_uuid = _get_user_uuid(token) if not user_uuid or not auth.verifyLoginToken(token, userUUID=user_uuid): return None return user_uuid def register(app): @app.route("/api/routines//steps//instructions", methods=["PUT"]) def api_updateStepInstructions(routine_id, step_id): """Update step instructions. Body: {instructions: string}""" user_uuid = _auth(flask.request) if not user_uuid: return flask.jsonify({"error": "unauthorized"}), 401 routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid}) if not routine: return flask.jsonify({"error": "routine not found"}), 404 step = postgres.select_one("routine_steps", {"id": step_id, "routine_id": routine_id}) if not step: return flask.jsonify({"error": "step not found"}), 404 data = flask.request.get_json() if not data: return flask.jsonify({"error": "missing body"}), 400 instructions = data.get("instructions") if instructions is None: return flask.jsonify({"error": "missing instructions"}), 400 result = postgres.update("routine_steps", {"instructions": instructions}, {"id": step_id}) return flask.jsonify(result[0] if result else {}), 200 @app.route("/api/routines//steps//type", methods=["PUT"]) def api_updateStepType(routine_id, step_id): """Update step type. Body: {step_type: 'generic'|'timer'|'checklist'|'meditation'|'exercise'}""" user_uuid = _auth(flask.request) if not user_uuid: return flask.jsonify({"error": "unauthorized"}), 401 routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid}) if not routine: return flask.jsonify({"error": "routine not found"}), 404 step = postgres.select_one("routine_steps", {"id": step_id, "routine_id": routine_id}) if not step: return flask.jsonify({"error": "step not found"}), 404 data = flask.request.get_json() if not data: return flask.jsonify({"error": "missing body"}), 400 step_type = data.get("step_type") allowed_types = ["generic", "timer", "checklist", "meditation", "exercise"] if step_type not in allowed_types: return flask.jsonify({"error": f"invalid step_type. allowed: {allowed_types}"}), 400 result = postgres.update("routine_steps", {"step_type": step_type}, {"id": step_id}) return flask.jsonify(result[0] if result else {}), 200 @app.route("/api/routines//steps//media", methods=["PUT"]) def api_updateStepMedia(routine_id, step_id): """Update step media URL. Body: {media_url: string}""" user_uuid = _auth(flask.request) if not user_uuid: return flask.jsonify({"error": "unauthorized"}), 401 routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid}) if not routine: return flask.jsonify({"error": "routine not found"}), 404 step = postgres.select_one("routine_steps", {"id": step_id, "routine_id": routine_id}) if not step: return flask.jsonify({"error": "step not found"}), 404 data = flask.request.get_json() if not data: return flask.jsonify({"error": "missing body"}), 400 media_url = data.get("media_url") result = postgres.update("routine_steps", {"media_url": media_url}, {"id": step_id}) return flask.jsonify(result[0] if result else {}), 200