Fix issues #6, #7, #11, #12, #13: med reminders, push notifications, auth persistence, scheduling conflicts

- Fix TIME object vs string comparison in scheduler preventing adaptive med
  reminders from ever firing (#12, #6)
- Add frequency filtering to midnight schedule creation for every_n_days meds
- Require start_date and interval_days for every_n_days medications
- Add refresh token support (30-day) to API and bot for persistent sessions (#13)
- Add "trusted device" checkbox to frontend login for long-lived sessions (#7)
- Auto-refresh expired tokens in both bot (apiRequest) and frontend (api.ts)
- Restore bot sessions from cache on restart using refresh tokens
- Duration-aware routine scheduling conflict detection (#11)
- Add conflict check when starting routine sessions against medication times
- Add diagnostic logging to notification delivery channels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 13:05:48 -06:00
parent 6850abf7d2
commit d4adbde3df
10 changed files with 474 additions and 69 deletions

View File

@@ -75,11 +75,33 @@ def api_login():
return flask.jsonify({"error": "username and password required"}), 400
token = auth.getLoginToken(username, password)
if token:
return flask.jsonify({"token": token}), 200
response = {"token": token}
# Issue refresh token when trusted device is requested
if data.get("trust_device"):
import jwt as pyjwt
payload = pyjwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
user_uuid = payload.get("sub")
if user_uuid:
response["refresh_token"] = auth.createRefreshToken(user_uuid)
return flask.jsonify(response), 200
else:
return flask.jsonify({"error": "invalid credentials"}), 401
@app.route("/api/refresh", methods=["POST"])
def api_refresh():
"""Exchange a refresh token for a new access token."""
data = flask.request.get_json()
refresh_token = data.get("refresh_token") if data else None
if not refresh_token:
return flask.jsonify({"error": "refresh_token required"}), 400
access_token, user_uuid = auth.refreshAccessToken(refresh_token)
if access_token:
return flask.jsonify({"token": access_token}), 200
else:
return flask.jsonify({"error": "invalid or expired refresh token"}), 401
# ── User Routes ────────────────────────────────────────────────────