PR: #471: feat(documents): segment-aware citation UX [Story-1873] by @ankitmaheshwari-com
View PR →
Story-1873 · RFD-DOC-002 S8 · DR-8 / DR-12 / DR-13

Segment-aware citation UX

A document does not cite the same way for every format. A PDF or Word file cites a page; a slide deck cites a slide; a spreadsheet cites a sheet + row. Quoting “page 7” of a PowerPoint is a lie a tribunal can catch. This story makes the Record cite honestly per segment type, stops the app from ever summing pages + slides + rows into one fake “pages” total, surfaces the new render states with their reasons, and marks the PRAMAAN-rendered copy we actually cite.

What changed

Typed citations (DR-8)

A new pure module src/lib/documents/segment-citation.ts owns the citation grammar: SegmentKind = page | slide | sheet_row, plus the i18n key each kind resolves to. The CitationLabel primitive renders the honest anchor — “page 12”, “slide 7”, “Sheet ‘Q1 Ledger’, row 14” — never a bare page number for a non-paged format.

Never sum incommensurable units (DR-12 / R4)

Summary.totalPages (a single cross-document page sum) is replaced by segmentCounts, a per-kind tally that the engine accumulates into each document’s own kind. The register footer, slicer, and group headers now render “142 pages · 30 slides · 480 rows” side by side — pages, slides, and rows are never collapsed into one figure.

PRAMAAN-rendered honesty (DR-12 / DR-1)

The detail drawer shows a PramaanRenderedBadge for rendered Office docs, with a one-line note that citations bind to the PRAMAAN-rendered PDF — while the original upload stays downloadable through the existing privilege-gated download action.

New states & reasons (DR-13)

The status pill now splits a status(reason) token and shows a clear cause: unreadable(render_failed) → “Unreadable · render failed”, needs_review(render_partial), needs_review(ocr_budget) — localized in en + hi, never a raw enum token.

The citation grammar

Format family Segment kind Citation form Count form
PDF, DOCX, RTF, TXT page page 12 24 pages
PPTX slide slide 7 30 slides
XLSX, CSV sheet_row Sheet ‘Q1 Ledger’, row 14 480 rows

Contract status & seams (verified against merged main)

Files touched

Verification

Files changed

26 file(s), +600 / -77 lines

Path Role + -
messages/en.jsonConfig+23-1
messages/hi.jsonConfig+23-1
src/components/documents/citation-label.stories.tsxComponent+36-0
src/components/documents/citation-label.tsxComponent+29-0
src/components/documents/detail/document-detail-drawer.tsxComponent+15-2
src/components/documents/detail/pramaan-rendered-badge.stories.tsxComponent+15-0
src/components/documents/detail/pramaan-rendered-badge.tsxComponent+34-0
src/components/documents/detail/presentation.tsComponent+17-0
src/components/documents/register/document-status-pill.stories.tsxComponent+15-0
src/components/documents/register/document-status-pill.tsxComponent+19-7
src/components/documents/register/presentation.tsComponent+28-9
src/components/documents/register/register-cell.tsxComponent+4-1
src/components/documents/register/register-group-header.stories.tsxComponent+5-3
src/components/documents/register/register-group-header.tsxComponent+6-4
src/components/documents/register/register-slice-navigator.tsxComponent+16-17
src/components/documents/segment-counts.stories.tsxComponent+32-0
src/components/documents/segment-counts.tsxComponent+33-0
src/lib/documents/register/adapter.test.tsLibrary+15-0
src/lib/documents/register/adapter.tsLibrary+4-0
src/lib/documents/register/fixtures.tsLibrary+1-0
src/lib/documents/register/pagination.test.tsLibrary+3-3
src/lib/documents/register/types.tsLibrary+19-6
src/lib/documents/register/view-state.test.tsLibrary+23-8
src/lib/documents/register/view-state.tsLibrary+27-15
src/lib/documents/segment-citation.test.tsLibrary+64-0
src/lib/documents/segment-citation.tsLibrary+94-0