46 lines
2.0 KiB
Markdown
46 lines
2.0 KiB
Markdown
# Story: Summary + Original Document Together in the Viewer
|
|
|
|
**Phase:** `36_summary_in_viewer` · **E2E:** `tests/e2e/test_summary_in_viewer.py`
|
|
|
|
## Narrative
|
|
|
|
As **any user**, phase 30 gives every non-markdown document a
|
|
lite-model summary (stored on `documents.summary`, indexed as an
|
|
`is_summary` chunk, used for retrieval). When I open such a document —
|
|
from the Sources table, a chat source chip, or a direct URL — I only
|
|
see the raw original. I want to see **the summary and the original
|
|
document together**.
|
|
|
|
- **Given** a document that has a summary (phase 30: non-markdown A9
|
|
documents)
|
|
- **When** I open it in the document viewer (the modal or the full
|
|
page)
|
|
- **Then** a labeled Summary panel sits above the original content —
|
|
both visible at once. Documents without a summary (markdown docs,
|
|
pre-phase-30 rows, fail-soft rows) render exactly as before.
|
|
|
|
## Acceptance criteria
|
|
1. `DocContent` gains `summary: str | None`; `GET
|
|
/api/documents/content` returns `documents.summary`. The endpoint
|
|
stays public + stateless — the phase 16 soft rule (catalog gated,
|
|
viewer public) is unchanged.
|
|
2. The shared renderer `renderDocument` (`assets/document.js`)
|
|
renders the summary panel for **both** surfaces at once (the
|
|
full-page viewer + the chat/sources modal); null/empty summary →
|
|
no panel; the summary text is written with `textContent` (XSS
|
|
contract unchanged).
|
|
3. `.doc-summary` styling matches the dark tech theme (phase 08
|
|
palette, contrast ≥4.5:1) and reads as a summary, not as document
|
|
content.
|
|
4. Integration tests: a summarized non-markdown doc returns its
|
|
summary; a markdown doc returns null; anonymous access unchanged.
|
|
5. Story E2E green in isolation (the `summary_kb` fixture: the
|
|
deterministic digest panel + the full original with its tail
|
|
sentinel visible together; the markdown control doc → no panel);
|
|
regressions green; `app/` coverage >90%; ruff + pyright clean; one
|
|
`--no-gpg-sign` commit.
|
|
|
|
## Playwright Mapping Rule
|
|
`tests/e2e/test_summary_in_viewer.py` — one story, one file, run in
|
|
isolation.
|