RelocateEntityService gains a third mutually-exclusive scope,
src_user_id, alongside entity_ids and src_policy_id. The new
NewRelocateUserTask selects entities via created_by and reuses the
existing cursor-resumable transfer path. The admin user editor gains
a "Relocate files" button opening the relocate dialog prefilled with
the user scope.
Generated with Devin
@ -221,6 +221,7 @@ Order = user-visible value first; each ships with backend + UI + tests.
- [x] Storage policy total capacity (upstream #2178 item 1) — `PolicySetting.MaxTotalSize` caps cumulative entity bytes per policy; enforced in `PrepareUpload`, batch upload validation, and `copyFiles` (baseline usage + per-batch accumulation since tx writes are invisible to the usage query); canonical `ErrInsufficientCapacity` preserved so `errors.Is` quota handling still matches; admin policy editor gains a Max total capacity SizeInput, en+zh locales
- [x] Storage policy overflow chain (upstream #2178 item 4) — `PolicySetting.OverflowPolicyID` links a fallback policy; `overflowChain` walks hops with cycle guard + hop cap, skipping suspended members and resolving load-balance members to weighted children; `PrepareUpload` spills to the first member with headroom for the file size so name/size/extension rules apply to the landing policy; `PreValidateUpload` checks aggregate chain headroom since batches may split across members; admin policy editor gains an Overflow policy select, en+zh locales
- [x] Thumbnail generation controls (upstream #2178 items 7+8) — `PolicySetting.ThumbForceProxy` skips the backend's native thumbnail API even when supported, implying the local proxy pipeline; `PolicySetting.ThumbStoragePolicyID` redirects generated thumb entities to a designated policy (honored via `PreferredStoragePolicy` for thumbnail uploads in `PrepareUpload`); Thumbnails section gains both controls, en+zh locales
- [x] Per-user blob relocation (upstream #2729/misc) — `RelocateEntityService` gains a third scope `src_user_id` (mutually exclusive with `entity_ids`/`src_policy_id`); `NewRelocateUserTask` selects entities by `created_by` with the same cursor-resumable transfer path; admin user editor gains a "Relocate files" button opening the relocate dialog prefilled with the user scope; en+zh locales