Transfer scope: shares-only by default, estate summary, full handover explicit (#597 scope) #655

Merged
Cordy merged 12 commits from fix-scope into main 2026-09-23 01:37:37 +00:00
Owner

Implements the approved departed-transfer-scope-rev1 mockup, both halves.

Backend

  • POST /admin/owners/transfer gains scope: "all" | "shares" (missing = all, back-compatible). Shares-only moves the deduplicated, nesting-pruned grant paths through the move chokepoint into /home/<to>/<from>/…, re-points those grants atomically via the new FileStore.RepointGrantsMulti (multi-prefix, refuse-whole contract — the single-prefix form would refuse any owner with two shared paths), pre-checks quota on the shared subset, and reports remaining: true. Public links untouched: frozen with the remainder, not broken.
  • GET /admin/owners/estate?user=: lazy size walk with shared/remainder split, cached ~5 min per owner, invalidated by transfers, refused for living accounts (an admin does not casually size a colleague's home).
  • ownersDeparted also lists estate-only owners (non-empty home, no records) — a shares-only transfer or revoke-all can never hide the leftover estate.

Frontend

  • Scope choice in the transfer dialog with real counts ("2 items, 1 public link" / "n files, size" from the estate endpoint, "computing…" until it lands); shares preselected when shares exist, disabled with "nothing is shared" otherwise.
  • Per-scope facts; the everything option leads with the read-all consequence; verb buttons name the scope ("Transfer 2 items to sharer1" / "Transfer everything to sharer1").
  • Departed rows: "files remain" chip + encrypted-remainder summary (async, from the same cached endpoint); estate-only rows offer Transfer remaining files and no revoke.
  • Shares-path success gets its own toast; sharing.md updated in-PR.

Decisions honoured from the mockup review: shared folders bring their contents; delete-remaining stays out (tracked in #654, cross-referenced); estate size computed lazily per row, never on page load.

Tests: internal/share/repoint_multi_test.go, internal/api/owners_scope_test.go, web/test/xferscope.test.js.

Implements the approved departed-transfer-scope-rev1 mockup, both halves. **Backend** - `POST /admin/owners/transfer` gains `scope: "all" | "shares"` (missing = all, back-compatible). Shares-only moves the deduplicated, nesting-pruned grant paths through the move chokepoint into `/home/<to>/<from>/…`, re-points those grants atomically via the new `FileStore.RepointGrantsMulti` (multi-prefix, refuse-whole contract — the single-prefix form would refuse any owner with two shared paths), pre-checks quota on the shared subset, and reports `remaining: true`. Public links untouched: frozen with the remainder, not broken. - `GET /admin/owners/estate?user=`: lazy size walk with shared/remainder split, cached ~5 min per owner, invalidated by transfers, refused for living accounts (an admin does not casually size a colleague's home). - `ownersDeparted` also lists estate-only owners (non-empty home, no records) — a shares-only transfer or revoke-all can never hide the leftover estate. **Frontend** - Scope choice in the transfer dialog with real counts ("2 items, 1 public link" / "n files, size" from the estate endpoint, "computing…" until it lands); shares preselected when shares exist, disabled with "nothing is shared" otherwise. - Per-scope facts; the everything option leads with the read-all consequence; verb buttons name the scope ("Transfer 2 items to sharer1" / "Transfer everything to sharer1"). - Departed rows: "files remain" chip + encrypted-remainder summary (async, from the same cached endpoint); estate-only rows offer **Transfer remaining files** and no revoke. - Shares-path success gets its own toast; sharing.md updated in-PR. Decisions honoured from the mockup review: shared folders bring their contents; delete-remaining stays out (tracked in #654, cross-referenced); estate size computed lazily per row, never on page load. Tests: internal/share/repoint_multi_test.go, internal/api/owners_scope_test.go, web/test/xferscope.test.js.
Cordy merged commit 83f8f385d7 into main 2026-09-23 01:37:37 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
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: Cordy/Cairn#655
No description provided.