First synculous 2 Big-Pickle pass.
This commit is contained in:
@@ -3,6 +3,7 @@ Medications API - medication scheduling, logging, and adherence tracking
|
||||
"""
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import flask
|
||||
import jwt
|
||||
import core.auth as auth
|
||||
@@ -39,7 +40,8 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
meds = postgres.select("medications", where={"user_uuid": user_uuid}, order_by="name")
|
||||
return flask.jsonify(meds), 200
|
||||
|
||||
@app.route("/api/medications", methods=["POST"])
|
||||
def api_addMedication():
|
||||
@@ -48,7 +50,18 @@ 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
|
||||
required = ["name", "dosage", "unit", "frequency"]
|
||||
missing = [f for f in required if not data.get(f)]
|
||||
if missing:
|
||||
return flask.jsonify({"error": f"missing required fields: {', '.join(missing)}"}), 400
|
||||
data["id"] = str(uuid.uuid4())
|
||||
data["user_uuid"] = user_uuid
|
||||
data["times"] = data.get("times", [])
|
||||
data["active"] = True
|
||||
med = postgres.insert("medications", data)
|
||||
return flask.jsonify(med), 201
|
||||
|
||||
@app.route("/api/medications/<med_id>", methods=["GET"])
|
||||
def api_getMedication(med_id):
|
||||
@@ -56,7 +69,10 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
return flask.jsonify(med), 200
|
||||
|
||||
@app.route("/api/medications/<med_id>", methods=["PUT"])
|
||||
def api_updateMedication(med_id):
|
||||
@@ -65,7 +81,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("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not existing:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
allowed = ["name", "dosage", "unit", "frequency", "times", "notes", "active"]
|
||||
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("medications", updates, {"id": med_id, "user_uuid": user_uuid})
|
||||
return flask.jsonify(result[0] if result else {}), 200
|
||||
|
||||
@app.route("/api/medications/<med_id>", methods=["DELETE"])
|
||||
def api_deleteMedication(med_id):
|
||||
@@ -73,7 +99,12 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
existing = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not existing:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
postgres.delete("med_logs", {"medication_id": med_id})
|
||||
postgres.delete("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
return flask.jsonify({"deleted": True}), 200
|
||||
|
||||
# ── Medication Logging (take / skip / snooze) ─────────────────
|
||||
|
||||
@@ -83,8 +114,20 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
data = flask.request.get_json() or {}
|
||||
pass
|
||||
log_entry = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"medication_id": med_id,
|
||||
"user_uuid": user_uuid,
|
||||
"action": "taken",
|
||||
"scheduled_time": data.get("scheduled_time"),
|
||||
"notes": data.get("notes"),
|
||||
}
|
||||
log = postgres.insert("med_logs", log_entry)
|
||||
return flask.jsonify(log), 201
|
||||
|
||||
@app.route("/api/medications/<med_id>/skip", methods=["POST"])
|
||||
def api_skipMedication(med_id):
|
||||
@@ -92,8 +135,20 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
data = flask.request.get_json() or {}
|
||||
pass
|
||||
log_entry = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"medication_id": med_id,
|
||||
"user_uuid": user_uuid,
|
||||
"action": "skipped",
|
||||
"scheduled_time": data.get("scheduled_time"),
|
||||
"notes": data.get("reason"),
|
||||
}
|
||||
log = postgres.insert("med_logs", log_entry)
|
||||
return flask.jsonify(log), 201
|
||||
|
||||
@app.route("/api/medications/<med_id>/snooze", methods=["POST"])
|
||||
def api_snoozeMedication(med_id):
|
||||
@@ -101,8 +156,12 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
data = flask.request.get_json() or {}
|
||||
minutes = data.get("minutes", 15)
|
||||
return flask.jsonify({"snoozed_until_minutes": minutes}), 200
|
||||
|
||||
# ── Medication Log / History ──────────────────────────────────
|
||||
|
||||
@@ -112,7 +171,17 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
days = flask.request.args.get("days", 30, type=int)
|
||||
logs = postgres.select(
|
||||
"med_logs",
|
||||
where={"medication_id": med_id},
|
||||
order_by="created_at DESC",
|
||||
limit=days * 10,
|
||||
)
|
||||
return flask.jsonify(logs), 200
|
||||
|
||||
@app.route("/api/medications/today", methods=["GET"])
|
||||
def api_todaysMeds():
|
||||
@@ -120,7 +189,26 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
meds = postgres.select("medications", where={"user_uuid": user_uuid, "active": True})
|
||||
from datetime import datetime
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
result = []
|
||||
for med in meds:
|
||||
times = med.get("times", [])
|
||||
taken_times = [
|
||||
log["scheduled_time"]
|
||||
for log in postgres.select(
|
||||
"med_logs",
|
||||
where={"medication_id": med["id"], "action": "taken"},
|
||||
)
|
||||
if log.get("scheduled_time", "").startswith(today)
|
||||
]
|
||||
result.append({
|
||||
"medication": med,
|
||||
"scheduled_times": times,
|
||||
"taken_times": taken_times,
|
||||
})
|
||||
return flask.jsonify(result), 200
|
||||
|
||||
# ── Adherence Stats ───────────────────────────────────────────
|
||||
|
||||
@@ -130,7 +218,27 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
days = flask.request.args.get("days", 30, type=int)
|
||||
meds = postgres.select("medications", where={"user_uuid": user_uuid, "active": True})
|
||||
result = []
|
||||
for med in meds:
|
||||
logs = postgres.select(
|
||||
"med_logs",
|
||||
where={"medication_id": med["id"]},
|
||||
limit=days * 10,
|
||||
)
|
||||
taken = sum(1 for log in logs if log.get("action") == "taken")
|
||||
skipped = sum(1 for log in logs if log.get("action") == "skipped")
|
||||
total = taken + skipped
|
||||
adherence = (taken / total * 100) if total > 0 else 0
|
||||
result.append({
|
||||
"medication_id": med["id"],
|
||||
"name": med["name"],
|
||||
"taken": taken,
|
||||
"skipped": skipped,
|
||||
"adherence_percent": round(adherence, 1),
|
||||
})
|
||||
return flask.jsonify(result), 200
|
||||
|
||||
@app.route("/api/medications/<med_id>/adherence", methods=["GET"])
|
||||
def api_medAdherence(med_id):
|
||||
@@ -138,7 +246,26 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
days = flask.request.args.get("days", 30, type=int)
|
||||
logs = postgres.select(
|
||||
"med_logs",
|
||||
where={"medication_id": med_id},
|
||||
limit=days * 10,
|
||||
)
|
||||
taken = sum(1 for log in logs if log.get("action") == "taken")
|
||||
skipped = sum(1 for log in logs if log.get("action") == "skipped")
|
||||
total = taken + skipped
|
||||
adherence = (taken / total * 100) if total > 0 else 0
|
||||
return flask.jsonify({
|
||||
"medication_id": med_id,
|
||||
"name": med["name"],
|
||||
"taken": taken,
|
||||
"skipped": skipped,
|
||||
"adherence_percent": round(adherence, 1),
|
||||
}), 200
|
||||
|
||||
# ── Refills ───────────────────────────────────────────────────
|
||||
|
||||
@@ -148,8 +275,18 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
med = postgres.select_one("medications", {"id": med_id, "user_uuid": user_uuid})
|
||||
if not med:
|
||||
return flask.jsonify({"error": "not found"}), 404
|
||||
data = flask.request.get_json()
|
||||
pass
|
||||
if not data:
|
||||
return flask.jsonify({"error": "missing body"}), 400
|
||||
allowed = ["quantity_remaining", "refill_date", "pharmacy_notes"]
|
||||
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("medications", updates, {"id": med_id, "user_uuid": user_uuid})
|
||||
return flask.jsonify(result[0] if result else {}), 200
|
||||
|
||||
@app.route("/api/medications/refills-due", methods=["GET"])
|
||||
def api_refillsDue():
|
||||
@@ -157,4 +294,19 @@ def register(app):
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
pass
|
||||
days_ahead = flask.request.args.get("days_ahead", 7, type=int)
|
||||
from datetime import datetime, timedelta
|
||||
cutoff = (datetime.now() + timedelta(days=days_ahead)).strftime("%Y-%m-%d")
|
||||
meds = postgres.select(
|
||||
"medications",
|
||||
where={"user_uuid": user_uuid},
|
||||
)
|
||||
due = []
|
||||
for med in meds:
|
||||
qty = med.get("quantity_remaining")
|
||||
refill_date = med.get("refill_date")
|
||||
if qty is not None and qty <= 7:
|
||||
due.append(med)
|
||||
elif refill_date and refill_date <= cutoff:
|
||||
due.append(med)
|
||||
return flask.jsonify(due), 200
|
||||
|
||||
Reference in New Issue
Block a user