mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 06:06:10 +00:00
feat(documents): open the doc-scoped Coach in the side drawer, not a full page
"Ask the Coach" on a document used to navigate to /coach?doc=<id> — a full-page jump away from the vault. It now opens the real, doc-scoped conversation in the shared side drawer, and the drawer's maximize control expands it to the full /coach page while preserving scope. - Thread an optional documentId through the launch context: askCoach gains a fourth argument, the provider tracks it alongside prefill/scope and clears it on close, and LayoutCoachMount forwards it to the drawer as initialDocumentId. The open-state precedence moves into a pure resolveLaunchState helper. - The vault detail sheet closes itself and calls askCoach(..., doc.id) instead of routing away, so the drawer owns the surface. - Maximize preserves continuity: the drawer reads the live conversation id via a new imperative getter out of the conversation surface (parallel to the reset registration) and hands off to /coach?c=<id> once a thread exists, falling back to /coach?doc=<id> for a chat maximized before its first turn. The send path is untouched: every document turn still routes through the hardened fenced endpoint keyed on documentId — only where the conversation renders (drawer vs page) changed. The documents-chat e2e now asserts the drawer opens in place, doc-scoped, rather than a URL change.
This commit is contained in:
1 parent
7c96abc8ec
commit
d72f078764
9 files changed
+390
-51
No files matched your search
+26
-18
@@ -1,19 +1,21 @@
|
||||
/**
|
||||
* Document vault — the "chat about a document" entry point (v1.28.51, R3).
|
||||
* Document vault — the "chat about a document" entry point (v1.28.52, R3).
|
||||
*
|
||||
* The bespoke in-sheet chat drawer is gone (Documents R3, Design A). Asking the
|
||||
* Coach about a document now hands off to the REAL Coach, scoped to that
|
||||
* document: the detail sheet's Coach affordance navigates to `/coach?doc=<id>`,
|
||||
* where the conversation runs on the same hardened fenced endpoint but inside
|
||||
* the Coach's own surface and history.
|
||||
* The bespoke in-sheet chat drawer is gone (Documents R3). Asking the Coach
|
||||
* about a document now opens the REAL Coach conversation, scoped to that
|
||||
* document, in the shared SIDE DRAWER: the detail sheet's Coach affordance
|
||||
* closes the sheet and opens the coach drawer pre-scoped to the document (its
|
||||
* maximize control expands to the full `/coach` page). The conversation runs on
|
||||
* the same hardened fenced endpoint — only WHERE it renders changed.
|
||||
*
|
||||
* This suite pins the documents-side contract: the affordance is offered only
|
||||
* when a provider is available, and it navigates to the doc-scoped Coach; with
|
||||
* NO provider the AI area collapses to the settings pointer and no Coach entry
|
||||
* renders at all. The Coach-side rendering (the "Chatting about" scope banner +
|
||||
* the not-indexed hint) is covered by the coach-conversation component test; the
|
||||
* fenced-send guarantee (a document turn never reaches the tool route) by the
|
||||
* coach-send-target + persistence-scope unit tests.
|
||||
* when a provider is available, and it OPENS THE DOC-SCOPED DRAWER in place (no
|
||||
* full-page nav); with NO provider the AI area collapses to the settings
|
||||
* pointer and no Coach entry renders at all. The Coach-side rendering (the
|
||||
* "Chatting about" scope banner + the not-indexed hint) is covered by the
|
||||
* coach-conversation component test; the fenced-send guarantee (a document turn
|
||||
* never reaches the tool route) by the coach-send-target + persistence-scope
|
||||
* unit tests.
|
||||
*
|
||||
* v1.27.31 lesson kept: the sheet's AI area depends on the capability probe +
|
||||
* usage endpoints, so both are mocked — otherwise the AI area never renders and
|
||||
@@ -94,9 +96,9 @@ test.describe("document vault — chat about a document", () => {
|
||||
test.slow();
|
||||
});
|
||||
|
||||
// ── (a) Provider available: the Coach entry hands off to the doc-scoped Coach ──
|
||||
// ── (a) Provider available: the Coach entry opens the doc-scoped drawer ──
|
||||
|
||||
test("offers the Coach entry and hands off to the document-scoped Coach", async ({
|
||||
test("offers the Coach entry and opens the document-scoped Coach drawer in place", async ({
|
||||
page,
|
||||
}) => {
|
||||
await mockAiEnabled(page);
|
||||
@@ -106,14 +108,20 @@ test.describe("document vault — chat about a document", () => {
|
||||
await expect(sheet).toBeVisible();
|
||||
|
||||
// The neutral Coach affordance lives in the detail-sheet AI area; tapping it
|
||||
// navigates to the real Coach seeded with this document.
|
||||
// closes the sheet and opens the REAL coach drawer scoped to this document.
|
||||
const open = sheet.locator('[data-slot="document-chat-open"]');
|
||||
await expect(open).toBeVisible();
|
||||
await open.click();
|
||||
|
||||
// The documents-side contract: the URL hands off to the doc-scoped Coach.
|
||||
await page.waitForURL(new RegExp(`/coach\\?doc=${CONTENT_DOC_ID}`));
|
||||
expect(new URL(page.url()).searchParams.get("doc")).toBe(CONTENT_DOC_ID);
|
||||
// The documents-side contract: the coach drawer opens IN PLACE (no
|
||||
// full-page nav) scoped to this document — its doc-scope banner renders.
|
||||
const drawer = page.locator('[data-slot="coach-drawer"]');
|
||||
await expect(drawer).toBeVisible({ timeout: 10_000 });
|
||||
await expect(drawer.locator('[data-slot="coach-doc-scope"]')).toBeVisible({
|
||||
timeout: 10_000,
|
||||
});
|
||||
// Still on /documents — the drawer expands to the page only via maximize.
|
||||
expect(new URL(page.url()).pathname).not.toContain("/coach");
|
||||
});
|
||||
|
||||
// ── (b) No provider: the calm settings pointer, no Coach entry at all ──
|
||||
|
||||
Reference in new issue
Block a user