fix partial-update overwrite bug in snitch and adaptive meds PUT handlers

Both handlers were building update_data with defaults for every field,
so a partial save (e.g. toggling one toggle) would silently reset all
other settings back to their defaults. Now only fields explicitly
present in the request body are written to the DB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 19:05:09 -06:00
parent f826e511d5
commit 6850abf7d2
2 changed files with 38 additions and 31 deletions

View File

@@ -91,24 +91,27 @@ def register(app):
{"error": "adaptive_mode is required when enabling adaptive timing"}
), 400
# Build update data
update_data = {
"adaptive_timing_enabled": data.get("adaptive_timing_enabled", False),
"adaptive_mode": data.get("adaptive_mode", "shift_all"),
"presence_tracking_enabled": data.get("presence_tracking_enabled", False),
"nagging_enabled": data.get("nagging_enabled", True),
"nag_interval_minutes": data.get("nag_interval_minutes", 15),
"max_nag_count": data.get("max_nag_count", 4),
"quiet_hours_start": data.get("quiet_hours_start"),
"quiet_hours_end": data.get("quiet_hours_end"),
}
# Only update fields explicitly provided in the request — never overwrite with defaults
allowed_fields = [
"adaptive_timing_enabled", "adaptive_mode", "presence_tracking_enabled",
"nagging_enabled", "nag_interval_minutes", "max_nag_count",
"quiet_hours_start", "quiet_hours_end",
]
update_data = {field: data[field] for field in allowed_fields if field in data}
if not update_data:
return flask.jsonify({"success": True}), 200
try:
update_data["user_uuid"] = user_uuid
update_data.setdefault("id", str(uuid.uuid4()))
postgres.upsert(
"adaptive_med_settings", update_data, conflict_columns=["user_uuid"]
)
existing = adaptive_meds.get_adaptive_settings(user_uuid)
if existing:
postgres.update(
"adaptive_med_settings", update_data, {"user_uuid": user_uuid}
)
else:
update_data["id"] = str(uuid.uuid4())
update_data["user_uuid"] = user_uuid
postgres.insert("adaptive_med_settings", update_data)
return flask.jsonify({"success": True}), 200
except Exception as e:

View File

@@ -78,22 +78,26 @@ def register(app):
if not data:
return flask.jsonify({"error": "No data provided"}), 400
# Build update data
update_data = {
"snitch_enabled": data.get("snitch_enabled", False),
"trigger_after_nags": data.get("trigger_after_nags", 4),
"trigger_after_missed_doses": data.get("trigger_after_missed_doses", 1),
"max_snitches_per_day": data.get("max_snitches_per_day", 2),
"require_consent": data.get("require_consent", True),
"consent_given": data.get("consent_given", False),
"snitch_cooldown_hours": data.get("snitch_cooldown_hours", 4),
"updated_at": datetime.utcnow(),
}
# Only update fields explicitly provided in the request — never overwrite with defaults
allowed_fields = [
"snitch_enabled", "trigger_after_nags", "trigger_after_missed_doses",
"max_snitches_per_day", "require_consent", "consent_given", "snitch_cooldown_hours",
]
update_data = {field: data[field] for field in allowed_fields if field in 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"])
if not update_data:
return flask.jsonify({"success": True}), 200
update_data["updated_at"] = datetime.utcnow()
existing = snitch_core.get_snitch_settings(user_uuid)
if existing:
postgres.update("snitch_settings", update_data, {"user_uuid": user_uuid})
else:
update_data["id"] = str(uuid.uuid4())
update_data["user_uuid"] = user_uuid
update_data["created_at"] = datetime.utcnow()
postgres.insert("snitch_settings", update_data)
return flask.jsonify({"success": True}), 200