95 lines
4.1 KiB
Python
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
|