✨(global) add storage gauge#764
Merged
Merged
Conversation
NathanVss
marked this pull request as draft
July 7, 2026 13:23
NathanVss
force-pushed
the
feat/quota-gauge
branch
3 times, most recently
from
July 13, 2026 12:57
a51d815 to
c98755a
Compare
NathanVss
marked this pull request as ready for review
July 13, 2026 13:14
NathanVss
force-pushed
the
feat/quota-gauge
branch
from
July 16, 2026 08:32
c98755a to
7b78650
Compare
PanchoutNathan
approved these changes
Jul 17, 2026
kernicPanel
reviewed
Jul 21, 2026
kernicPanel
left a comment
Collaborator
There was a problem hiding this comment.
I'm not sure that we should use a cache for the quota, the added index should be fast enough for big files count. Also I don't like signals...
Did you benchmark reply times with and without cache ?
IMHO, we should keep thing as simple as possible.
NathanVss
force-pushed
the
feat/quota-gauge
branch
from
July 22, 2026 14:46
7b78650 to
204e94e
Compare
NathanVss
force-pushed
the
feat/quota-gauge
branch
from
July 22, 2026 14:53
204e94e to
c0d2083
Compare
kernicPanel
approved these changes
Jul 23, 2026
The upload gates returned a generic "permission_denied" code whatever the entitlements backend's refusal reason. Forwarding the backend's reason as the DRF error code lets the frontend map each rejection to a specific, translatable message instead of a catch-all one.
The frontend needs the storage usage and limit to render a quota gauge. Entitlements backends can now return a quota (usage/limit, locked when the organization quota is reached, or an explicit error state) and the DeployCenter backend derives the can_upload reason from the resolve level when the service does not provide one, so the gauge and the upload errors stay consistent.
The quota gauge reads the storage usage from cache (directly for the local backend, via DeployCenter's metrics for the remote one). Both caches must be dropped as soon as a write changes a user's usage, otherwise the gauge shows stale numbers until the timeout. A post_save signal covers item saves, and the code paths doing bulk updates that bypass signals (signup invitations, user reconciliation, hard delete of a tree) invalidate explicitly for every impacted creator.
Hard-deleted items no longer occupy storage but still counted in the creator's usage, inflating the quota gauge and blocking uploads for users who had cleaned up their trash. The new partial covering index keeps the per-creator sum an index-only scan now that the quota check runs it on every uncached upload.
Deployments without a DeployCenter service had no way to enforce storage quotas. This backend computes each user's usage locally and applies a configurable default limit, overridable per user in the admin (0 meaning unlimited) and skippable for users created before a cutoff so quotas can be rolled out to new users only. The quota is soft: can_upload runs before the file size is known, so one upload can overshoot before the next one is blocked.
Both actions grow the acting user's storage usage without going through an upload: duplicating makes them creator of a new sized copy, and moving a file to the root without a direct access reassigns its creator. An over-quota user could use them to keep taking ownership of storage. Moving also invalidates the previous creator's usage cache since the reassignment only triggers the post_save invalidation for the new creator.
Operators may document how storage quotas work for their users. The optional FRONTEND_STORAGE_GAUGE_INFORMATION_LINK setting is exposed through the config API so the frontend gauge can link to that page.
Brings the StorageGaugeButton and StorageGaugeInformation components needed to render the storage quota gauge.
Uploads, moves to the root and duplications can now be refused by the backend quota gates. The API error code carries the can_upload reason, so each surface (upload list, move toast, duplicate toast) maps it to a dedicated translated message instead of a generic failure, and the 40x redirect is disabled on those calls so the user stays in place and sees the toast. The move mutation handles its own error feedback to avoid double toasting through the global handler.
Renders the quota returned by the entitlements API as a gauge in the left panel footer, with a locked state when the organization quota is reached and a tooltip carrying the error when the quota cannot be computed. Clicking it opens a settings modal with the detailed gauge and an optional documentation link. The footer is reworked to host the gauge on mobile too (user profile and app grid move there), and the entitlements query is refetched after uploads and hard deletes so the gauge follows the usage.
Several keys were missing in some languages (Dutch search filters, delete menu labels, restore toasts, file picker caption), silently falling back to English. Sync them and add a test failing whenever a key exists in one language but not the others, so gaps are caught at review time instead of in production.
The frontend storage gauge deserved its own changelog entry, and the local backend line moves after the already released entries to keep the section in insertion order.
DeployCenter now accepts the usage metrics directly in the entitlements request body, so we switch from GET to POST and send a "usage_metrics" list with the user's storage and the aggregated storage of the active users sharing the same organization claim. This avoids the extra HTTP roundtrip DeployCenter previously made to our usage metrics API when resolving entitlements. The entries reuse the Usage serializers so the pushed body and the pulled external API cannot drift. The organization serializer now takes the users queryset to be usable from both call sites, which also moves the storage computation out of the viewset. The organization claim key is configurable through a new "organization_claim" backend parameter defaulting to "siret".
The entitlements enums exposed "excedeed" in both their names and their wire values. Fix the spelling now, while the codes are only consumed by this branch, as they are part of the API contract with the frontend.
Align the driver enums, quota state, translation keys and e2e fixtures with the backend error codes now spelled "exceeded".
Following review, replace the post_save signal with a direct call in the model method. The invalidation logic stays close to the domain and is easier to trace than an implicit signal. Bulk queryset updates keep their explicit invalidation since they bypass save().
Apply a review suggestion to keep the quota lookup and its guard on a single line in the entitlements endpoint.
Duplicating an item consumes storage and moving an item to or from the root can change who owns its usage. Invalidate the entitlements cache on success so the gauge reflects the new usage without a reload.
The home and simple layouts rendered their own mobile-only panel with just the gaufre. Reusing the explorer footer keeps the settings entry and user profile consistent everywhere and removes the duplicate component. The index page is also reformatted by prettier on the way.
NathanVss
force-pushed
the
feat/quota-gauge
branch
from
July 23, 2026 15:08
c0d2083 to
635135d
Compare
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Purpose
Add a storage gauge, indicating the user how much storage is remaining.
See https://www.figma.com/design/XDjWHDLIiNY4mtpyj21EVK/Drive?node-id=14155-57350&t=BDVBrHbIVUYgp1JN-0