first commit
This commit is contained in:
160
api/routes/medications.py
Normal file
160
api/routes/medications.py
Normal file
@@ -0,0 +1,160 @@
|
||||
"""
|
||||
Medications API - medication scheduling, logging, and adherence tracking
|
||||
"""
|
||||
|
||||
import os
|
||||
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):
|
||||
"""Extract and verify token. Returns user_uuid or None."""
|
||||
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):
|
||||
|
||||
# ── Medications CRUD ──────────────────────────────────────────
|
||||
|
||||
@app.route("/api/medications", methods=["GET"])
|
||||
def api_listMedications():
|
||||
"""List all medications for the logged-in user."""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
@app.route("/api/medications", methods=["POST"])
|
||||
def api_addMedication():
|
||||
"""Add a medication. Body: {name, dosage, unit, frequency, times: ["08:00","20:00"], notes?}"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/<med_id>", methods=["GET"])
|
||||
def api_getMedication(med_id):
|
||||
"""Get a single medication with its schedule."""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/<med_id>", methods=["PUT"])
|
||||
def api_updateMedication(med_id):
|
||||
"""Update medication details. Body: {name?, dosage?, unit?, frequency?, times?, notes?, active?}"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/<med_id>", methods=["DELETE"])
|
||||
def api_deleteMedication(med_id):
|
||||
"""Delete a medication and its logs."""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
# ── Medication Logging (take / skip / snooze) ─────────────────
|
||||
|
||||
@app.route("/api/medications/<med_id>/take", methods=["POST"])
|
||||
def api_takeMedication(med_id):
|
||||
"""Log that a dose was taken. Body: {scheduled_time?, notes?}"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json() or {}
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/<med_id>/skip", methods=["POST"])
|
||||
def api_skipMedication(med_id):
|
||||
"""Log a skipped dose. Body: {scheduled_time?, reason?}"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json() or {}
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/<med_id>/snooze", methods=["POST"])
|
||||
def api_snoozeMedication(med_id):
|
||||
"""Snooze a reminder. Body: {minutes: 15}"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
|
||||
# ── Medication Log / History ──────────────────────────────────
|
||||
|
||||
@app.route("/api/medications/<med_id>/log", methods=["GET"])
|
||||
def api_getMedLog(med_id):
|
||||
"""Get dose log for a medication. Query: ?days=30"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/today", methods=["GET"])
|
||||
def api_todaysMeds():
|
||||
"""Get today's medication schedule with taken/pending status."""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
# ── Adherence Stats ───────────────────────────────────────────
|
||||
|
||||
@app.route("/api/medications/adherence", methods=["GET"])
|
||||
def api_adherenceStats():
|
||||
"""Get adherence stats across all meds. Query: ?days=30"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/<med_id>/adherence", methods=["GET"])
|
||||
def api_medAdherence(med_id):
|
||||
"""Get adherence stats for a single medication. Query: ?days=30"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
|
||||
# ── Refills ───────────────────────────────────────────────────
|
||||
|
||||
@app.route("/api/medications/<med_id>/refill", methods=["PUT"])
|
||||
def api_setRefill(med_id):
|
||||
"""Set refill info. Body: {quantity_remaining, refill_date?, pharmacy_notes?}"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
|
||||
@app.route("/api/medications/refills-due", methods=["GET"])
|
||||
def api_refillsDue():
|
||||
"""Get medications that need refills soon. Query: ?days_ahead=7"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
Reference in New Issue
Block a user