Version history UI: list, view, diff, restore #42

Closed
opened 2026-07-04 14:52:19 +02:00 by fable-5 · 1 comment
Collaborator

Context

Users need to see who changed what and restore old states (ADR 0013).

Scope

Page history panel: version list (time, trigger, label, contributors), read-only render of a selected version (Yjs snapshot → doc → HTML via shared code), text diff against current (markdown-level, insert/delete highlighting), restore action (creates pre_restore snapshot, applies restored content as a regular update through the collab document so live participants converge). API endpoints for list/get/restore.

Acceptance criteria

  • restoring an old version updates live for a second connected client (e2e)
  • diff highlights added/removed text for a fixture pair
  • pre-restore snapshot appears in history; history is append-only (restore never deletes versions)
  • history access requires write permission (assert 403 for read-only fixture user)

Technical notes

  • ADR 0013 (restore semantics), permissions.md (history requires edit).
  • Diff on the markdown representation is sufficient (documented simplification).

Dependencies

Depends on #41.

Size: ~2 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context Users need to see who changed what and restore old states (ADR 0013). ## Scope Page history panel: version list (time, trigger, label, contributors), read-only render of a selected version (Yjs snapshot → doc → HTML via shared code), text diff against current (markdown-level, insert/delete highlighting), restore action (creates `pre_restore` snapshot, applies restored content as a regular update through the collab document so live participants converge). API endpoints for list/get/restore. ## Acceptance criteria - [ ] restoring an old version updates live for a second connected client (e2e) - [ ] diff highlights added/removed text for a fixture pair - [ ] pre-restore snapshot appears in history; history is append-only (restore never deletes versions) - [ ] history access requires write permission (assert 403 for read-only fixture user) ## Technical notes - ADR 0013 (restore semantics), permissions.md (history requires edit). - Diff on the markdown representation is sufficient (documented simplification). ## Dependencies Depends on #41. **Size**: ~2 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M3 — Real-time collaboration & history milestone 2026-07-04 14:52:19 +02:00
fable-5 added the
frontend
backend
labels 2026-07-04 14:52:19 +02:00
Collaborator

Done in 1bda137. Version history: list, view, diff, restore (ADR 0013). Completes M3.

  • shared: dependency-free word-level diffMarkdown (unit-tested); PageVersionContentView; page_restore NOTIFY channel.
  • api: GET /pages/:id/versions (list), GET .../:versionId (read-only HTML + Markdown for diffing), POST .../:versionId/restore. All write-permission-gated (history is gated like editing, permissions.md). Restore checks permission then emits the notification; the api never deletes a version.
  • collab: a page_restore listener applies the restore on the live document via openDirectConnection — snapshots the current state as PRE_RESTORE, then replaces the content in one transaction, so every connected client converges and it persists like a normal edit.
  • web: HistoryPanel (version list with time/trigger/label/contributors, read-only render, Markdown diff vs current, restore), toggled from the page menu. de+en.

AC:

  • restoring updates live for a connected client — collab DB integration test: a connected provider converges on the restored content after the notification.
  • diff highlights added/removed for a fixture pair — shared unit test.
  • pre-restore snapshot appears; history append-only — verified in tests and live.
  • history requires write permission — list/get/restore all assert it (non-owner → 404 under interim).

Pipeline green (CI+CD, Test+Int). Live on Test (fixture-user): created a named version (label+creator), listed, fetched content, restored → collab logged restore.applied and history shows manual + pre_restore + auto (append-only). With this, M3 (#33–#42) is complete.

Done in `1bda137`. Version history: list, view, diff, restore (ADR 0013). Completes M3. - shared: dependency-free word-level `diffMarkdown` (unit-tested); `PageVersionContentView`; `page_restore` NOTIFY channel. - api: `GET /pages/:id/versions` (list), `GET .../:versionId` (read-only HTML + Markdown for diffing), `POST .../:versionId/restore`. All write-permission-gated (history is gated like editing, permissions.md). Restore checks permission then emits the notification; the api never deletes a version. - collab: a `page_restore` listener applies the restore on the live document via `openDirectConnection` — snapshots the current state as `PRE_RESTORE`, then replaces the content in one transaction, so every connected client converges and it persists like a normal edit. - web: `HistoryPanel` (version list with time/trigger/label/contributors, read-only render, Markdown diff vs current, restore), toggled from the page menu. de+en. AC: - restoring updates live for a connected client — collab DB integration test: a connected provider converges on the restored content after the notification. - diff highlights added/removed for a fixture pair — shared unit test. - pre-restore snapshot appears; history append-only — verified in tests and live. - history requires write permission — list/get/restore all assert it (non-owner → 404 under interim). Pipeline green (CI+CD, Test+Int). Live on Test (fixture-user): created a named version (label+creator), listed, fetched content, restored → collab logged `restore.applied` and history shows manual + pre_restore + auto (append-only). With this, **M3 (#33–#42) is complete.**
Sign in to join this conversation.
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#42
No description provided.