mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
feat(coach): evidence-based cadence suggestions with one-tap in-chat reminder
The Coach can append a ---SUGGEST-REMINDER--- sentinel to propose a measurement cadence (weight daily, the ESH/AHA 7-2-2 home-BP protocol, structured glucose). The server resolves the cadence from a closed catalog and emits an additive 'suggestion' SSE frame the chat renders as a one-tap action card; accepting it creates a MeasurementReminder with origin COACH through the same engine the Vorsorge surface uses (server-authoritative schedule, finite course window self-expires via endsOn). Non-naggy by construction: a frequency-cap cooldown, dismissal memory, a master opt-out under Coach settings, and an explicit 'I measure enough' stop path, all in the coach-prefs blob. Triple dedup at suggest, render, and create so a cadence is never double-suggested or double-created, and suggestions for a disabled module never surface. RHR/HRV stay passive -- the Coach surfaces the baseline, it never nudges to 'go measure' them. The reminder DTO now echoes origin and endsOn for the iOS client.
This commit is contained in:
1 parent
b6796eee96
commit
12f4bc24e8
29 files changed
+1538
-9
No files matched your search
+94
-1
@@ -3041,6 +3041,28 @@ paths:
|
||||
- medication
|
||||
- mobility
|
||||
- environment
|
||||
reminderSuggestions:
|
||||
type: object
|
||||
properties:
|
||||
enabled:
|
||||
default: true
|
||||
type: boolean
|
||||
stopped:
|
||||
default: false
|
||||
type: boolean
|
||||
dismissedCadences:
|
||||
default: []
|
||||
maxItems: 32
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
maxLength: 64
|
||||
lastSuggestedAt:
|
||||
default: null
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 40
|
||||
- type: "null"
|
||||
responses:
|
||||
"200":
|
||||
description: Saved preferences echoed back.
|
||||
@@ -12227,6 +12249,34 @@ components:
|
||||
- medication
|
||||
- mobility
|
||||
- environment
|
||||
reminderSuggestions:
|
||||
type: object
|
||||
properties:
|
||||
enabled:
|
||||
default: true
|
||||
type: boolean
|
||||
stopped:
|
||||
default: false
|
||||
type: boolean
|
||||
dismissedCadences:
|
||||
default: []
|
||||
maxItems: 32
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
maxLength: 64
|
||||
lastSuggestedAt:
|
||||
default: null
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 40
|
||||
- type: "null"
|
||||
required:
|
||||
- enabled
|
||||
- stopped
|
||||
- dismissedCadences
|
||||
- lastSuggestedAt
|
||||
additionalProperties: false
|
||||
required:
|
||||
- tone
|
||||
- verbosity
|
||||
@@ -12311,6 +12361,34 @@ components:
|
||||
- medication
|
||||
- mobility
|
||||
- environment
|
||||
reminderSuggestions:
|
||||
type: object
|
||||
properties:
|
||||
enabled:
|
||||
default: true
|
||||
type: boolean
|
||||
stopped:
|
||||
default: false
|
||||
type: boolean
|
||||
dismissedCadences:
|
||||
default: []
|
||||
maxItems: 32
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
maxLength: 64
|
||||
lastSuggestedAt:
|
||||
default: null
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 40
|
||||
- type: "null"
|
||||
required:
|
||||
- enabled
|
||||
- stopped
|
||||
- dismissedCadences
|
||||
- lastSuggestedAt
|
||||
additionalProperties: false
|
||||
required:
|
||||
- tone
|
||||
- verbosity
|
||||
@@ -16941,6 +17019,17 @@ components:
|
||||
format: date-time
|
||||
pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
|
||||
- type: "null"
|
||||
endsOn:
|
||||
anyOf:
|
||||
- type: string
|
||||
format: date-time
|
||||
pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
|
||||
- type: "null"
|
||||
origin:
|
||||
type: string
|
||||
enum:
|
||||
- VORSORGE
|
||||
- COACH
|
||||
notifyHour:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
@@ -16978,6 +17067,8 @@ components:
|
||||
- intervalDays
|
||||
- rrule
|
||||
- anchorDate
|
||||
- endsOn
|
||||
- origin
|
||||
- notifyHour
|
||||
- location
|
||||
- nextDueAt
|
||||
@@ -16987,7 +17078,9 @@ components:
|
||||
- updatedAt
|
||||
additionalProperties: false
|
||||
description: A Vorsorge reminder. nextDueAt is server-computed (server-authoritative). A free-text reminder carries
|
||||
measurementType=null and resolves only on a manual satisfy.
|
||||
measurementType=null and resolves only on a manual satisfy. origin distinguishes a user-created (VORSORGE)
|
||||
reminder from one minted by a Coach cadence suggestion (COACH); endsOn bounds a finite course window (null =
|
||||
open-ended).
|
||||
MeasurementReminderCreatedEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in new issue
Block a user