feat(coach): a guided dialog for follow-ups and nudges that know their owner

Open follow-up questions now run as a guided in-chat sequence — a quiet
card offers to start, the coach asks one question at a time with
visible progress, answers can be adopted into the matching self-context
field, skipping keeps a question pending and a closing summary says
what was taken over. Proactive nudges learn three new deterministic
signals — weight drifting from its target band, a run of short nights,
an active user falling silent — address the focus the user asked to
watch, and gain per-group toggles and a frequency preference.
This commit is contained in:
Marc-André Bombeck committed 2026-06-11 11:45:58 +02:00
1 parent f13aa684f9
commit a62e00cfcd
25 files changed
+3199 -377

No files matched your search

@@ -91,7 +91,7 @@ describe("GET /api/auth/me/notification-prefs", () => {
medication: { clientManaged: false, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
});
});
@@ -112,7 +112,7 @@ describe("GET /api/auth/me/notification-prefs", () => {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
});
});
@@ -135,7 +135,7 @@ describe("GET /api/auth/me/notification-prefs", () => {
medication: { clientManaged: false, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
});
});
});
@@ -169,7 +169,7 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
});
expect(prisma.user.update).toHaveBeenCalledWith({
@@ -179,7 +179,7 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
},
},
});
@@ -193,13 +193,13 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: false, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
},
next: {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
},
changed: ["medication"],
}),
@@ -261,7 +261,7 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
},
},
});
@@ -287,7 +287,7 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
});
expect(prisma.user.update).toHaveBeenCalledWith({
@@ -297,7 +297,7 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: true, deliveryDefault: "server" },
mood: { reminderHour: 22 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
},
},
});
@@ -326,7 +326,7 @@ describe("PATCH /api/auth/me/notification-prefs", () => {
medication: { clientManaged: false, deliveryDefault: "server" },
mood: { reminderHour: 9 },
cycle: { clientManaged: false },
coach: { nudgesEnabled: true },
coach: { nudgesEnabled: true, nudgeMedication: true, nudgeVitals: true, nudgeRoutine: true, nudgeFrequency: "weekly" },
},
},
});