feat(transcription): let read-only users read transcriptions (read tab only, no edit) (#697) #700
Reference in New Issue
Block a user
Delete Branch "feat/issue-697-readers-read-transcriptions"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #697.
Lets a
READ_ALLuser open and read an existing transcription on the document detail page — read view only, with every edit affordance suppressed. Writers are unchanged.Behaviour
Approach
hasTranscriptionis a cheap server-computed boolean on the document detail payload (decided with the maintainer), available at first paint — no client store, no full block fetch, no layout shift.Backend
TranscriptionBlockRepository.existsByDocumentId(cheap EXISTS) →TranscriptionBlockQueryService.hasBlocks.Documentgains a@Transient hasTranscription, populated inDocumentService.getDocumentById(the query service was already injected — no new dependency, no cycle).DocumentTS type.Frontend
(canWrite || hasTranscription) && isPdfon both the desktop top-bar and the mobile menu; reader label "Transkription lesen".TranscriptionPanelHeadergainscanEdit— readers get a plain "Transkription" heading instead of the toggle, status line kept.onModeChangeguarded,panelModedefaults to'read', writer-only OCR status check skipped.canAnnotate={canWrite}throughDocumentViewer→PdfViewerso the annotation layer'scanDraw(which also gates delete/resize) is off for readers.transcription_read_label,transcription_panel_title(de/en/es).Tests
existsByDocumentId, query-servicehasBlocks,DocumentServicepopulateshasTranscription, and the READ_ALL→403 / READ_ALL→200 permission boundary (239 backend tests green locally; Testcontainers repo test green).DocumentTopBarActions/DocumentMobileMenureader-gate cases,TranscriptionPanelHeadercanEdit,PdfViewerdraw-surface gating, and an E2E happy path (reader opens read view, no edit tab, cannot switch to edit).TDD throughout (red → green → atomic commit). Companion to #696 (the simple write-control gates, already on main).
🤖 Generated with Claude Code
transcription_read_label ("Transkription lesen") for the read-only entry control and transcription_panel_title ("Transkription") for the plain header readers see instead of the Lesen/Bearbeiten toggle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>On the document detail page, pass canEdit={canWrite} to the panel header, guard onModeChange so a reader can never flip to edit, and default panelMode to 'read' for readers. Thread canAnnotate={canWrite} through DocumentViewer to PdfViewer so the annotation layer's canDraw (which also gates delete and resize) is off for readers — they can open and read, but not draw, edit, or delete. The writer-only OCR status check is also skipped for readers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Move the hasTranscription existence query out of the shared getDocumentById into a dedicated getDocumentDetail used solely by GET /api/documents/{id}. The flag is only consumed by the detail page, so the extra EXISTS query no longer runs for the many internal getDocumentById callers (e.g. the Geschichte resolve loop and the dashboard resume path). Behaviour of the detail endpoint is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>