From f826e511d577dd73c97d0fe004eb92c945ce0e2e Mon Sep 17 00:00:00 2001 From: chelsea Date: Tue, 17 Feb 2026 18:52:35 -0600 Subject: [PATCH] fixing snitch and adaptive medication timing persistance and logic --- api/routes/adaptive_meds.py | 16 ++++++---------- api/routes/snitch.py | 16 +++++++--------- core/adaptive_meds.py | 23 +++++++++++++++------- core/snitch.py | 38 ++++++++++++++++++------------------- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/api/routes/adaptive_meds.py b/api/routes/adaptive_meds.py index 98d3610..745ae66 100644 --- a/api/routes/adaptive_meds.py +++ b/api/routes/adaptive_meds.py @@ -3,6 +3,7 @@ api/routes/adaptive_meds.py - API endpoints for adaptive medication settings """ import logging +import uuid import flask import jwt import os @@ -103,16 +104,11 @@ def register(app): } try: - # Check if settings exist - existing = adaptive_meds.get_adaptive_settings(user_uuid) - - if existing: - postgres.update( - "adaptive_med_settings", update_data, {"user_uuid": user_uuid} - ) - else: - update_data["user_uuid"] = user_uuid - postgres.insert("adaptive_med_settings", update_data) + update_data["user_uuid"] = user_uuid + update_data.setdefault("id", str(uuid.uuid4())) + postgres.upsert( + "adaptive_med_settings", update_data, conflict_columns=["user_uuid"] + ) return flask.jsonify({"success": True}), 200 except Exception as e: diff --git a/api/routes/snitch.py b/api/routes/snitch.py index b38a731..7fb75e6 100644 --- a/api/routes/snitch.py +++ b/api/routes/snitch.py @@ -2,6 +2,7 @@ api/routes/snitch.py - API endpoints for snitch system """ +import uuid import flask import jwt import os @@ -89,15 +90,10 @@ def register(app): "updated_at": datetime.utcnow(), } - # Check if settings exist - existing = snitch_core.get_snitch_settings(user_uuid) - - if existing: - postgres.update("snitch_settings", update_data, {"user_uuid": user_uuid}) - else: - update_data["user_uuid"] = user_uuid - update_data["created_at"] = datetime.utcnow() - postgres.insert("snitch_settings", update_data) + update_data["user_uuid"] = user_uuid + update_data.setdefault("id", str(uuid.uuid4())) + update_data.setdefault("created_at", datetime.utcnow()) + postgres.upsert("snitch_settings", update_data, conflict_columns=["user_uuid"]) return flask.jsonify({"success": True}), 200 @@ -161,6 +157,7 @@ def register(app): ), 400 contact_data = { + "id": str(uuid.uuid4()), "user_uuid": user_uuid, "contact_name": data["contact_name"], "contact_type": data["contact_type"], @@ -277,6 +274,7 @@ def register(app): # Insert into snitch_log so the bot will pick it up and send it log_data = { + "id": str(uuid.uuid4()), "user_uuid": user_uuid, "contact_id": contact.get("id"), "medication_id": None, # Test snitch, no actual medication diff --git a/core/adaptive_meds.py b/core/adaptive_meds.py index 5c83ce0..d4f66a2 100644 --- a/core/adaptive_meds.py +++ b/core/adaptive_meds.py @@ -9,6 +9,7 @@ This module handles: """ import json +import uuid from datetime import datetime, timedelta, time from typing import Optional, Dict, List, Tuple import core.postgres as postgres @@ -50,6 +51,7 @@ def update_user_presence(user_uuid: str, discord_user_id: str, is_online: bool): else: # Create new record data = { + "id": str(uuid.uuid4()), "user_uuid": user_uuid, "discord_user_id": discord_user_id, "is_currently_online": is_online, @@ -275,12 +277,18 @@ def should_send_nag( if time_since_last_nag < nag_interval: return False, f"Too soon ({int(time_since_last_nag)} < {nag_interval} min)" - # Check if medication was already taken today + # Check if this specific dose was already taken today logs = postgres.select( - "med_logs", {"medication_id": med_id, "user_uuid": user_uuid, "action": "taken"} + "med_logs", + { + "medication_id": med_id, + "user_uuid": user_uuid, + "action": "taken", + "scheduled_time": scheduled_time, + }, ) - # Filter to today's logs + # Filter to today's logs for this time slot today_logs = [ log for log in logs @@ -297,10 +305,10 @@ def record_nag_sent(user_uuid: str, med_id: str, scheduled_time: str): """Record that a nag was sent.""" today = user_today_for(user_uuid) - schedules = postgres.select( - "medication_schedules", - {"user_uuid": user_uuid, "medication_id": med_id, "adjustment_date": today}, - ) + query = {"user_uuid": user_uuid, "medication_id": med_id, "adjustment_date": today} + if scheduled_time is not None: + query["adjusted_time"] = scheduled_time + schedules = postgres.select("medication_schedules", query) if schedules: schedule = schedules[0] @@ -332,6 +340,7 @@ def create_daily_schedule(user_uuid: str, med_id: str, base_times: List[str]): # Create schedule records for each time for base_time, (adjusted_time, offset) in zip(base_times, adjusted_times): data = { + "id": str(uuid.uuid4()), "user_uuid": user_uuid, "medication_id": med_id, "base_time": base_time, diff --git a/core/snitch.py b/core/snitch.py index 122e210..5f3d93f 100644 --- a/core/snitch.py +++ b/core/snitch.py @@ -5,10 +5,12 @@ Handles snitch triggers, contact selection, and notification delivery. """ import json +import uuid from datetime import datetime, timedelta, date from typing import Optional, Dict, List, Tuple import core.postgres as postgres import core.notifications as notifications +from core.tz import user_today_for def get_snitch_settings(user_uuid: str) -> Optional[Dict]: @@ -31,8 +33,8 @@ def get_snitch_contacts(user_uuid: str, active_only: bool = True) -> List[Dict]: def get_todays_snitch_count(user_uuid: str) -> int: - """Get number of snitches sent today.""" - today = date.today() + """Get number of snitches sent today (in the user's local timezone).""" + today = user_today_for(user_uuid) # Query snitch log for today rows = postgres.select("snitch_log", {"user_uuid": user_uuid}) @@ -249,6 +251,7 @@ def send_snitch( # Log the snitch log_data = { + "id": str(uuid.uuid4()), "user_uuid": user_uuid, "contact_id": contact_id, "medication_id": med_id, @@ -307,24 +310,19 @@ def _send_sms_snitch(phone: str, message: str) -> bool: def update_consent(user_uuid: str, consent_given: bool): """Update user's snitch consent status.""" - settings = get_snitch_settings(user_uuid) - - if settings: - postgres.update( - "snitch_settings", - {"consent_given": consent_given, "updated_at": datetime.utcnow()}, - {"user_uuid": user_uuid}, - ) - else: - # Create settings with consent - data = { - "user_uuid": user_uuid, - "snitch_enabled": False, # Disabled until fully configured - "consent_given": consent_given, - "created_at": datetime.utcnow(), - "updated_at": datetime.utcnow(), - } - postgres.insert("snitch_settings", data) + data = { + "id": str(uuid.uuid4()), + "user_uuid": user_uuid, + "snitch_enabled": False, # Disabled until fully configured + "consent_given": consent_given, + "created_at": datetime.utcnow(), + "updated_at": datetime.utcnow(), + } + postgres.upsert( + "snitch_settings", + data, + conflict_columns=["user_uuid"], + ) def get_snitch_history(user_uuid: str, days: int = 7) -> List[Dict]: