Version snapshots: automatic and named versions #41

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

Context

Version history is a core kickoff decision (ADR 0013); snapshots are created at session end, on interval, and on demand.

Scope

Implement page_versions writes: automatic snapshot on last-participant disconnect (if changed) and every 30 active-editing minutes; POST /pages/:id/versions for named versions (label, requires write permission); contributor ids derived from Yjs update metadata since the previous version; pre_restore trigger type reserved for #42. Daily version-thinning job (keep all 90 days, then daily) per ADR 0013.

Acceptance criteria

  • closing the last editor session creates exactly one auto version (no duplicates on quick reconnects)
  • named version stores label + creator
  • contributor set is correct for a two-author fixture session
  • thinning keeps the newest snapshot per day beyond the window (time-travel test)

Technical notes

  • ADR 0013, data-model.md (page_versions).
  • Snapshots are full encoded states — self-contained restore independent of the update log.

Dependencies

Depends on #35, #40.

Size: ~1.5 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 Version history is a core kickoff decision (ADR 0013); snapshots are created at session end, on interval, and on demand. ## Scope Implement `page_versions` writes: automatic snapshot on last-participant disconnect (if changed) and every 30 active-editing minutes; `POST /pages/:id/versions` for named versions (label, requires write permission); contributor ids derived from Yjs update metadata since the previous version; `pre_restore` trigger type reserved for #42. Daily `version-thinning` job (keep all 90 days, then daily) per ADR 0013. ## Acceptance criteria - [ ] closing the last editor session creates exactly one auto version (no duplicates on quick reconnects) - [ ] named version stores label + creator - [ ] contributor set is correct for a two-author fixture session - [ ] thinning keeps the newest snapshot per day beyond the window (time-travel test) ## Technical notes - ADR 0013, data-model.md (`page_versions`). - Snapshots are full encoded states — self-contained restore independent of the update log. ## Dependencies Depends on #35, #40. **Size**: ~1.5 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
backend
collab
labels 2026-07-04 14:52:19 +02:00
Collaborator

Done in 6fb6f6f (schema base landed a commit early in 3583a04). Version history via self-contained Yjs snapshots (ADR 0013).

  • schema: page_versions (full snapshot, trigger auto/manual/pre_restore, label, created_by, contributor_ids) + page_pending_contributors accumulator.
  • collab (PostgresVersionStore): tracks contributors per open doc (onChange), flushes them to the shared accumulator on store, and writes an automatic snapshot on last-participant disconnect (only if something changed) and every 30 active-editing minutes. Snapshot + contributors are consumed atomically.
  • api: POST /pages/:id/versions creates a named version (write permission, label + creator, contributor set consumed). Daily version-thinning job keeps all versions for 90 days, then the newest auto snapshot per day; manual/pre_restore never thinned. pre_restore reserved for #42.

AC:

  • exactly one auto version on last disconnect, no duplicate on a no-op reconnect — collab DB test.
  • named version stores label + creator — api test.
  • contributor set correct for a two-author session — collab DB test asserts both authors.
  • thinning keeps the newest snapshot per day beyond the window — api time-travel test.

Pipeline green (CI+CD, Test+Int). Live on Test: api VersionsModule initialized, collab healthy on this image.

Done in `6fb6f6f` (schema base landed a commit early in `3583a04`). Version history via self-contained Yjs snapshots (ADR 0013). - schema: `page_versions` (full snapshot, trigger auto/manual/pre_restore, label, created_by, contributor_ids) + `page_pending_contributors` accumulator. - collab (`PostgresVersionStore`): tracks contributors per open doc (onChange), flushes them to the shared accumulator on store, and writes an automatic snapshot on last-participant disconnect (only if something changed) and every 30 active-editing minutes. Snapshot + contributors are consumed atomically. - api: `POST /pages/:id/versions` creates a named version (write permission, label + creator, contributor set consumed). Daily `version-thinning` job keeps all versions for 90 days, then the newest auto snapshot per day; manual/pre_restore never thinned. `pre_restore` reserved for #42. AC: - exactly one auto version on last disconnect, no duplicate on a no-op reconnect — collab DB test. - named version stores label + creator — api test. - contributor set correct for a two-author session — collab DB test asserts both authors. - thinning keeps the newest snapshot per day beyond the window — api time-travel test. Pipeline green (CI+CD, Test+Int). Live on Test: api `VersionsModule` initialized, collab healthy on this image.
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#41
No description provided.