feat(coach): document chats live in the Coach view and history

Asking the Coach about a document opened a separate, half-finished chat panel
that never appeared in Coach history. The bespoke drawer is gone; a document
conversation now opens the real Coach view, appears in the Coach list with a
document badge and a "Chatting about: <title>" note, and is read back through
the same history rail as any other thread.

The prompt-injection fence is unchanged and stays server-side. A document turn
is still sent through the hardened fenced endpoint (no tools, no health
snapshot, grounded in the document text only); the coach tool route continues
to fetch with documentId null, so a document-scoped conversation can never be
continued through the tool loop even from a hostile client. Only the surface
moved into the Coach; the boundary did not.

The relaxed conversation-list and detail filters drop only the documentId
predicate — userId scoping is unchanged, so a document thread is still visible
only to its owner. CoachConversationDTO gains documentId + documentTitle
(server-derived, title/filename only); no schema change (documentId exists
since 0230). OpenAPI regenerated.
This commit is contained in:
Marc-André Bombeck committed 2026-07-16 11:01:59 +02:00
1 parent 57539283c8
commit 5b24ca0fa1
28 files changed
+605 -1112

No files matched your search

+24 -1
View File
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: HealthLog API
version: 1.28.50
version: 1.28.51
description: >-
Self-hosted personal-health-tracking PWA — public API surface for the iOS native client and external ingest.
@@ -21934,6 +21934,18 @@ components:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
documentId:
description: When set, this thread is scoped to one stored document (a document chat, run on the hardened fenced
endpoint). Null/absent for a normal health thread.
anyOf:
- type: string
- type: "null"
documentTitle:
description: The owning document's resolved title (title, falling back to filename) for the scope badge. Null on a
health thread or when the document has neither.
anyOf:
- type: string
- type: "null"
required:
- id
- title
@@ -21988,6 +22000,17 @@ components:
anyOf:
- type: string
- type: "null"
documentId:
description: When set, this thread is scoped to one stored document; the client routes its turns through the hardened
fenced document endpoint, never the tool route.
anyOf:
- type: string
- type: "null"
documentTitle:
description: The owning document's resolved title for the scope badge. Null on a health thread.
anyOf:
- type: string
- type: "null"
required:
- id
- title