Files
Synculous-2/api/routes/routine_steps_extended.py

95 lines
4.1 KiB
Python

"""
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/<routine_id>/steps/<step_id>/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/<routine_id>/steps/<step_id>/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/<routine_id>/steps/<step_id>/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