First synculous 2 Big-Pickle pass.
This commit is contained in:
@@ -5,6 +5,7 @@ Routines have ordered steps. Users start sessions to walk through them.
|
||||
"""
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import flask
|
||||
import jwt
|
||||
import core.auth as auth
|
||||
@@ -41,7 +42,8 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routines = postgres.select("routines", where={"user_uuid": user_uuid}, order_by="name")
|
||||
return flask.jsonify(routines), 200
|
||||
|
||||
@app.route("/api/routines", methods=["POST"])
|
||||
def api_createRoutine():
|
||||
@@ -50,7 +52,14 @@ def register(app):
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data:
|
||||
return flask.jsonify({"error": "missing body"}), 400
|
||||
if not data.get("name"):
|
||||
return flask.jsonify({"error": "missing required field: name"}), 400
|
||||
data["id"] = str(uuid.uuid4())
|
||||
data["user_uuid"] = user_uuid
|
||||
routine = postgres.insert("routines", data)
|
||||
return flask.jsonify(routine), 201
|
||||
|
||||
@app.route("/api/routines/<routine_id>", methods=["GET"])
|
||||
def api_getRoutine(routine_id):
|
||||
@@ -58,7 +67,15 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": routine_id},
|
||||
order_by="position",
|
||||
)
|
||||
return flask.jsonify({"routine": routine, "steps": steps}), 200
|
||||
|
||||
@app.route("/api/routines/<routine_id>", methods=["PUT"])
|
||||
def api_updateRoutine(routine_id):
|
||||
@@ -67,7 +84,17 @@ def register(app):
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data:
|
||||
return flask.jsonify({"error": "missing body"}), 400
|
||||
existing = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not existing:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
allowed = ["name", "description", "icon"]
|
||||
updates = {k: v for k, v in data.items() if k in allowed}
|
||||
if not updates:
|
||||
return flask.jsonify({"error": "no valid fields to update"}), 400
|
||||
result = postgres.update("routines", updates, {"id": routine_id, "user_uuid": user_uuid})
|
||||
return flask.jsonify(result[0] if result else {}), 200
|
||||
|
||||
@app.route("/api/routines/<routine_id>", methods=["DELETE"])
|
||||
def api_deleteRoutine(routine_id):
|
||||
@@ -75,7 +102,14 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
existing = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not existing:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
postgres.delete("routine_sessions", {"routine_id": routine_id})
|
||||
postgres.delete("routine_steps", {"routine_id": routine_id})
|
||||
postgres.delete("routine_schedules", {"routine_id": routine_id})
|
||||
postgres.delete("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
return flask.jsonify({"deleted": True}), 200
|
||||
|
||||
# ── Steps CRUD ────────────────────────────────────────────────
|
||||
|
||||
@@ -85,7 +119,15 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": routine_id},
|
||||
order_by="position",
|
||||
)
|
||||
return flask.jsonify(steps), 200
|
||||
|
||||
@app.route("/api/routines/<routine_id>/steps", methods=["POST"])
|
||||
def api_addStep(routine_id):
|
||||
@@ -93,8 +135,30 @@ def register(app):
|
||||
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": "not found"}), 404
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data:
|
||||
return flask.jsonify({"error": "missing body"}), 400
|
||||
if not data.get("name"):
|
||||
return flask.jsonify({"error": "missing required field: name"}), 400
|
||||
max_pos = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": routine_id},
|
||||
order_by="position DESC",
|
||||
limit=1,
|
||||
)
|
||||
next_pos = (max_pos[0]["position"] + 1) if max_pos else 1
|
||||
step = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"routine_id": routine_id,
|
||||
"name": data["name"],
|
||||
"duration_minutes": data.get("duration_minutes"),
|
||||
"position": data.get("position", next_pos),
|
||||
}
|
||||
result = postgres.insert("routine_steps", step)
|
||||
return flask.jsonify(result), 201
|
||||
|
||||
@app.route("/api/routines/<routine_id>/steps/<step_id>", methods=["PUT"])
|
||||
def api_updateStep(routine_id, step_id):
|
||||
@@ -102,8 +166,21 @@ def register(app):
|
||||
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": "not found"}), 404
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data:
|
||||
return flask.jsonify({"error": "missing body"}), 400
|
||||
existing = postgres.select_one("routine_steps", {"id": step_id, "routine_id": routine_id})
|
||||
if not existing:
|
||||
return flask.jsonify({"error": "step not found"}), 404
|
||||
allowed = ["name", "duration_minutes", "position"]
|
||||
updates = {k: v for k, v in data.items() if k in allowed}
|
||||
if not updates:
|
||||
return flask.jsonify({"error": "no valid fields to update"}), 400
|
||||
result = postgres.update("routine_steps", updates, {"id": step_id, "routine_id": routine_id})
|
||||
return flask.jsonify(result[0] if result else {}), 200
|
||||
|
||||
@app.route("/api/routines/<routine_id>/steps/<step_id>", methods=["DELETE"])
|
||||
def api_deleteStep(routine_id, step_id):
|
||||
@@ -111,7 +188,14 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
existing = postgres.select_one("routine_steps", {"id": step_id, "routine_id": routine_id})
|
||||
if not existing:
|
||||
return flask.jsonify({"error": "step not found"}), 404
|
||||
postgres.delete("routine_steps", {"id": step_id, "routine_id": routine_id})
|
||||
return flask.jsonify({"deleted": True}), 200
|
||||
|
||||
@app.route("/api/routines/<routine_id>/steps/reorder", methods=["PUT"])
|
||||
def api_reorderSteps(routine_id):
|
||||
@@ -119,8 +203,21 @@ def register(app):
|
||||
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": "not found"}), 404
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data or not data.get("step_ids"):
|
||||
return flask.jsonify({"error": "missing step_ids"}), 400
|
||||
step_ids = data["step_ids"]
|
||||
for i, step_id in enumerate(step_ids):
|
||||
postgres.update("routine_steps", {"position": i + 1}, {"id": step_id, "routine_id": routine_id})
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": routine_id},
|
||||
order_by="position",
|
||||
)
|
||||
return flask.jsonify(steps), 200
|
||||
|
||||
# ── Routine Sessions (active run-through) ─────────────────────
|
||||
|
||||
@@ -130,7 +227,28 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
active = postgres.select_one("routine_sessions", {"user_uuid": user_uuid, "status": "active"})
|
||||
if active:
|
||||
return flask.jsonify({"error": "already have active session", "session_id": active["id"]}), 409
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": routine_id},
|
||||
order_by="position",
|
||||
)
|
||||
if not steps:
|
||||
return flask.jsonify({"error": "no steps in routine"}), 400
|
||||
session = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"routine_id": routine_id,
|
||||
"user_uuid": user_uuid,
|
||||
"status": "active",
|
||||
"current_step_index": 0,
|
||||
}
|
||||
result = postgres.insert("routine_sessions", session)
|
||||
return flask.jsonify({"session": result, "current_step": steps[0]}), 201
|
||||
|
||||
@app.route("/api/sessions/active", methods=["GET"])
|
||||
def api_getActiveSession():
|
||||
@@ -138,7 +256,17 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
session = postgres.select_one("routine_sessions", {"user_uuid": user_uuid, "status": "active"})
|
||||
if not session:
|
||||
return flask.jsonify({"error": "no active session"}), 404
|
||||
routine = postgres.select_one("routines", {"id": session["routine_id"]})
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": session["routine_id"]},
|
||||
order_by="position",
|
||||
)
|
||||
current_step = steps[session["current_step_index"]] if session["current_step_index"] < len(steps) else None
|
||||
return flask.jsonify({"session": session, "routine": routine, "current_step": current_step}), 200
|
||||
|
||||
@app.route("/api/sessions/<session_id>/complete-step", methods=["POST"])
|
||||
def api_completeStep(session_id):
|
||||
@@ -146,8 +274,23 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
session = postgres.select_one("routine_sessions", {"id": session_id, "user_uuid": user_uuid})
|
||||
if not session:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
if session["status"] != "active":
|
||||
return flask.jsonify({"error": "session not active"}), 400
|
||||
data = flask.request.get_json() or {}
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": session["routine_id"]},
|
||||
order_by="position",
|
||||
)
|
||||
next_index = session["current_step_index"] + 1
|
||||
if next_index >= len(steps):
|
||||
postgres.update("routine_sessions", {"status": "completed"}, {"id": session_id})
|
||||
return flask.jsonify({"session": {"status": "completed"}, "next_step": None}), 200
|
||||
postgres.update("routine_sessions", {"current_step_index": next_index}, {"id": session_id})
|
||||
return flask.jsonify({"session": {"current_step_index": next_index}, "next_step": steps[next_index]}), 200
|
||||
|
||||
@app.route("/api/sessions/<session_id>/skip-step", methods=["POST"])
|
||||
def api_skipStep(session_id):
|
||||
@@ -155,8 +298,22 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
session = postgres.select_one("routine_sessions", {"id": session_id, "user_uuid": user_uuid})
|
||||
if not session:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
if session["status"] != "active":
|
||||
return flask.jsonify({"error": "session not active"}), 400
|
||||
steps = postgres.select(
|
||||
"routine_steps",
|
||||
where={"routine_id": session["routine_id"]},
|
||||
order_by="position",
|
||||
)
|
||||
next_index = session["current_step_index"] + 1
|
||||
if next_index >= len(steps):
|
||||
postgres.update("routine_sessions", {"status": "completed"}, {"id": session_id})
|
||||
return flask.jsonify({"session": {"status": "completed"}, "next_step": None}), 200
|
||||
postgres.update("routine_sessions", {"current_step_index": next_index}, {"id": session_id})
|
||||
return flask.jsonify({"session": {"current_step_index": next_index}, "next_step": steps[next_index]}), 200
|
||||
|
||||
@app.route("/api/sessions/<session_id>/cancel", methods=["POST"])
|
||||
def api_cancelSession(session_id):
|
||||
@@ -164,7 +321,11 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
session = postgres.select_one("routine_sessions", {"id": session_id, "user_uuid": user_uuid})
|
||||
if not session:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
postgres.update("routine_sessions", {"status": "cancelled"}, {"id": session_id})
|
||||
return flask.jsonify({"session": {"status": "cancelled"}}), 200
|
||||
|
||||
# ── Routine History / Stats ───────────────────────────────────
|
||||
|
||||
@@ -174,7 +335,17 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
days = flask.request.args.get("days", 7, type=int)
|
||||
sessions = postgres.select(
|
||||
"routine_sessions",
|
||||
where={"routine_id": routine_id},
|
||||
order_by="created_at DESC",
|
||||
limit=days,
|
||||
)
|
||||
return flask.jsonify(sessions), 200
|
||||
|
||||
# ── Routine Scheduling ────────────────────────────────────────
|
||||
|
||||
@@ -184,8 +355,26 @@ def register(app):
|
||||
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": "not found"}), 404
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data:
|
||||
return flask.jsonify({"error": "missing body"}), 400
|
||||
existing = postgres.select_one("routine_schedules", {"routine_id": routine_id})
|
||||
schedule_data = {
|
||||
"routine_id": routine_id,
|
||||
"days": data.get("days", []),
|
||||
"time": data.get("time"),
|
||||
"remind": data.get("remind", True),
|
||||
}
|
||||
if existing:
|
||||
result = postgres.update("routine_schedules", schedule_data, {"routine_id": routine_id})
|
||||
return flask.jsonify(result[0] if result else {}), 200
|
||||
else:
|
||||
schedule_data["id"] = str(uuid.uuid4())
|
||||
result = postgres.insert("routine_schedules", schedule_data)
|
||||
return flask.jsonify(result), 201
|
||||
|
||||
@app.route("/api/routines/<routine_id>/schedule", methods=["GET"])
|
||||
def api_getRoutineSchedule(routine_id):
|
||||
@@ -193,7 +382,13 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
schedule = postgres.select_one("routine_schedules", {"routine_id": routine_id})
|
||||
if not schedule:
|
||||
return flask.jsonify({"error": "no schedule set"}), 404
|
||||
return flask.jsonify(schedule), 200
|
||||
|
||||
@app.route("/api/routines/<routine_id>/schedule", methods=["DELETE"])
|
||||
def api_deleteRoutineSchedule(routine_id):
|
||||
@@ -201,4 +396,8 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
|
||||
if not routine:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
postgres.delete("routine_schedules", {"routine_id": routine_id})
|
||||
return flask.jsonify({"deleted": True}), 200
|
||||
|
||||
Reference in New Issue
Block a user