"""Profile, units and sync preferences.""" from flask import Blueprint, request, g, jsonify from auth import require_auth from services import settings as settings_svc from services import fitness_age bp = Blueprint("settings", __name__) @bp.route("", methods=["GET"]) @bp.route("/", methods=["GET"]) @require_auth def get_settings(): return jsonify(settings_svc.get_settings(g.user_id)) @bp.route("", methods=["PUT"]) @bp.route("/", methods=["PUT"]) @require_auth def put_settings(): try: return jsonify(settings_svc.save_settings(g.user_id, request.json or {})) except settings_svc.InvalidSetting as e: return jsonify({"error": str(e)}), 400 @bp.route("/options", methods=["GET"]) @require_auth def options(): """The values the pickers may offer, so the UI never invents one the backend would reject.""" return jsonify({ "sexes": list(settings_svc.SEXES), "units": list(settings_svc.UNITS), "autoSyncMinutes": list(settings_svc.INTERVALS), "historyDays": list(settings_svc.HISTORY), }) @bp.route("/rating-basis", methods=["GET"]) @require_auth def rating_basis(): """Where every rating in the app comes from. Surfaced in 设置 because a band that colours a number 偏低 is making a claim, and the user is entitled to see what that claim rests on. """ return jsonify({ "fitnessAge": fitness_age.BASIS, "bands": BAND_SOURCES, "note": ( "参考区间用于给数字一个位置感,不是诊断标准。" "AI 只负责解读这些结果,不参与设定任何阈值。" ), }) # Kept beside the UI's RANGES table (client/src/lib/ranges.ts). Each entry says # where that metric's band edges came from — the honest answer for several of # them is "general-population orientation figures", and it says so. BAND_SOURCES = [ {"metric": "步数", "bands": "<5k 偏低 · 5–8k 一般 · 8–12k 达标 · >12k 优秀", "source": "步数与死亡率的队列研究(约 8000 步起获益明显,12000 步后趋平)"}, {"metric": "静息心率", "bands": "<50 很低 · 50–65 正常 · 65–75 偏高 · >75 较高", "source": "健康成人静息心率 60–100 bpm 为正常范围,规律运动者常低于 60"}, {"metric": "心率变异性", "bands": "<25 偏低 · 25–40 一般 · 40–70 良好 · >70 很好", "source": "夜间 RMSSD 的一般人群分布;个体差异极大,趋势比绝对值更有意义"}, {"metric": "睡眠时长", "bands": "<6h 不足 · 6–7h 偏少 · 7–9h 充足 · >9h 偏多", "source": "美国睡眠医学会 / 睡眠研究会成人 7–9 小时建议"}, {"metric": "压力", "bands": "0–25 休息 · 26–50 偏低 · 51–75 中等 · >75 偏高", "source": "Garmin 官方压力分级,与手表显示一致"}, {"metric": "身体电量", "bands": "0–25 很低 · 26–50 偏低 · 51–75 良好 · >75 充足", "source": "Garmin 官方 Body Battery 分级"}, {"metric": "血氧", "bands": "<90 偏低 · 90–94 略低 · ≥95 正常", "source": "静息血氧饱和度常用临床参考;腕表光学测量误差较大,仅供趋势参考"}, {"metric": "呼吸频率", "bands": "<12 偏低 · 12–20 正常 · >20 偏高", "source": "成人静息呼吸频率 12–20 次/分"}, {"metric": "强度分钟", "bands": "<10 偏少 · 10–21 一般 · ≥21 达标", "source": "WHO 每周 150 分钟中等强度活动,折合每天约 21 分钟"}, {"metric": "训练准备度", "bands": "0–25 很低 · 26–50 偏低 · 51–75 就绪 · >75 很好", "source": "Garmin 官方 Training Readiness 分级"}, {"metric": "爬楼", "bands": "<5 偏少 · 5–10 达标 · >10 优秀", "source": "一般性活动量参考,无权威标准"}, ]