Per-file activity feed: event store + API + timeline panel (#530, 2/4) #539
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#539
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Second slice of #530. A per-file activity timeline in the details pane ("X updated file in Space, date"), per the OpenCloud reference.
Needs: an event store recording who/what/when per path (upload, update, rename, move, copy, share created/removed, restore),
GET /api/v1/activity?path=with paging, and the timeline panel in the details sidebar (#538).Design decision first: reuse the audit log as the queryable source, or add a separate lighter event log. The audit log carries retention/compliance semantics (runtime toggle, retainMonths) that a UI feed should probably not be coupled to — leaning separate store under the statestore pattern (survives redeploys per #153), with a size/age cap. Rename/move must re-key or follow the path, same problem as tags (#540).
Backend TDD per house rules; blocked by nothing — the panel lands in #538's shell.
Design note (build follows on approval-by-silence — flag anything off):
.cairn-state/activity.json), so it survives redeploys per #138/#153.{path, action, actor, at}with action ∈ upload, update, rename, move, copy, share-created, share-removed, restore.GET /api/v1/activity?path=&limit=newest-first,resolveOwned-class path handling, hidden on delegated paths in v1 (consistent with the versioning ADR's recipient decision).Shipped in v0.6.221 (PR #619, tag on
b83ab7f), live on both dogfoods (files.c0rdyceps.ch and files-bao.c0rdyceps.ch).Built as designed in the note above:
internal/activity: separate bounded event store atactivity.jsonbeside recents/favorites (atomic JSON via statestore). Write-time caps: 5000 events, 90 days. Explicitly not the #61 audit log — the #433 verb scanner got an exemption entry documenting exactly that.upload/update(a Stat before the write decides which),rename/move(activity.Kind: same directory = rename, different = move),copy,share-created/share-removed(both grants and public links),restore(trash, via a nil-safeTrashAPI.Acthook).GET /api/v1/activity?path=&limit=(limit ≤ 200, default 50), gated by a Stat through the caller's scoped store: paths you can't see yield errors, so delegated/foreign history stays hidden.feat.activityprobed at boot.Two deliberate scope edges, flag if either bites during dogfooding:
Tests: store unit tests (caps, ordering, rekey, persistence, Kind),
acthelper tests,pure:act-labelnode test; red witnessed before impl on both Go and node sides.