Skip to content

fix: fetch storage quota from backend on mount#76

Merged
FSM1 merged 4 commits into
mainfrom
claude/fix-storage-quota-display-0SnSB
Feb 10, 2026
Merged

fix: fetch storage quota from backend on mount#76
FSM1 merged 4 commits into
mainfrom
claude/fix-storage-quota-display-0SnSB

Conversation

@FSM1

@FSM1 FSM1 commented Feb 10, 2026

Copy link
Copy Markdown
Owner

The quota display stayed at zero after re-login because fetchQuota()
was only called during upload flows. The zustand store initialized with
usedBytes: 0 and nothing triggered a backend sync on app load. Added a
useEffect to StorageQuota that calls fetchQuota() on mount so the
display always reflects persisted usage.

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke

Summary by CodeRabbit

  • Bug Fixes
    • Fixed storage quota display to automatically refresh quota data on component load, ensuring users see the most current storage usage information.

The quota display stayed at zero after re-login because fetchQuota()
was only called during upload flows. The zustand store initialized with
usedBytes: 0 and nothing triggered a backend sync on app load. Added a
useEffect to StorageQuota that calls fetchQuota() on mount so the
display always reflects persisted usage.

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke
Copilot AI review requested due to automatic review settings February 10, 2026 04:00
@coderabbitai

coderabbitai Bot commented Feb 10, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@FSM1 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

The StorageQuota component now imports useEffect from React and invokes fetchQuota from useQuotaStore on component mount to refresh quota data. The percentage calculation and rendering logic remain unchanged.

Changes

Cohort / File(s) Summary
Data Fetching on Mount
apps/web/src/components/layout/StorageQuota.tsx
Added useEffect hook to call fetchQuota from useQuotaStore on component mount to refresh quota data.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: fetch storage quota from backend on mount' directly and clearly summarizes the main change: adding logic to fetch storage quota data from the backend when the StorageQuota component mounts.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-storage-quota-display-0SnSB

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ensures the storage quota indicator reflects persisted backend usage after a re-login by triggering a quota sync when the quota UI mounts.

Changes:

  • Add a useEffect in StorageQuota to call fetchQuota() on mount.
  • Update the component to pull fetchQuota from the quota Zustand store.

Comment on lines +27 to +31
// Fetch quota from backend on mount so the display reflects
// actual usage (e.g. files uploaded in previous sessions).
useEffect(() => {
fetchQuota();
}, [fetchQuota]);

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this component is rendered inside AppShell even while auth is still isLoading (see FilesPage/SettingsPage), this effect will run before the user is authenticated. That can trigger an unnecessary /vault/quota request (and potentially a refresh-token flow + store resets on refresh failure) when there is no session. Consider gating the call so it only runs once the user is authenticated / has an access token, and add a simple guard to avoid double-fetch in React 18 StrictMode (effects run twice in dev).

Copilot uses AI. Check for mistakes.
After page reload, StorageQuota's unconditional fetchQuota() fired
before session restoration completed, sending an unauthenticated
request that triggered the 401 → refresh token flow. With server-side
refresh token rotation, this raced with restoreSession's own refresh
call — one would fail, and the interceptor's catch handler called
logout(), destroying the session for all subsequent e2e tests.

Guard fetchQuota() with isAuthenticated so it only fires once the
session is fully restored.

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke
Add two new e2e tests:
- 3.6.1: Verifies quota display shows non-zero usage after uploading
  13+ files during the session
- 3.7.1: Verifies quota persists after page reload (regression test
  for the quota-stuck-at-zero bug where fetchQuota was never called
  on mount)

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke
@FSM1 FSM1 merged commit 713292e into main Feb 10, 2026
7 checks passed
@FSM1 FSM1 deleted the claude/fix-storage-quota-display-0SnSB branch February 10, 2026 05:02
FSM1 added a commit that referenced this pull request Feb 10, 2026
* feat: add external file drag-and-drop from Finder/Explorer

Files dragged from the OS file manager can now be dropped onto:
- The file browser area (uploads to current folder)
- Folder rows in the file list (uploads to that folder)
- Breadcrumb segments (uploads to that folder)

Internal drag-and-drop (move operations) continues to work as before.
External drags show a 'copy' cursor and visual feedback on the content
area. A new useDropUpload hook extracts reusable upload-on-drop logic.

https://claude.ai/code/session_016z77d1zrWcRefW1Lhogprh

* docs: close TEE critical bugs todo (C1/C2/H1) — already fixed in codebase (#79)

* docs: close TEE critical bugs todo (C1/C2/H1) — already fixed in codebase

Security review findings C1 (missing epoch fields), C2 (hex/base64 mismatch),
and H1 (health response shape) were all resolved during implementation.
Marked as RESOLVED in security review and moved todo to done.

https://claude.ai/code/session_01H4skah3QYgLKWJDpxDUFps

* Update .planning/security/REVIEW-2026-02-07-tee-phase8.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: prevent IPNS sequence rollback with PublishCoordinator

Add PublishCoordinator to FUSE layer with:
- Per-IPNS-name monotonic sequence cache (never decreases)
- Per-folder tokio::sync::Mutex to serialize concurrent publishes
- resolve_sequence() returns cached value on resolve failure,
  or errors if no cache exists (never falls back to seq=0)

Updated all 3 publish paths:
- spawn_metadata_publish (rename/delete/move operations)
- File upload release (write operations)
- mkdir parent folder publish

Fixes security review L-6 (REVIEW-2026-02-08-phase9-desktop.md)
and LOW-SEVERITY-BACKLOG.md item 18.

https://claude.ai/code/session_01H4skah3QYgLKWJDpxDUFps

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: fetch storage quota from backend on mount (#76)

* fix: fetch storage quota from backend on mount

The quota display stayed at zero after re-login because fetchQuota()
was only called during upload flows. The zustand store initialized with
usedBytes: 0 and nothing triggered a backend sync on app load. Added a
useEffect to StorageQuota that calls fetchQuota() on mount so the
display always reflects persisted usage.

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke

* fix: guard fetchQuota with auth check to prevent e2e logout race

After page reload, StorageQuota's unconditional fetchQuota() fired
before session restoration completed, sending an unauthenticated
request that triggered the 401 → refresh token flow. With server-side
refresh token rotation, this raced with restoreSession's own refresh
call — one would fail, and the interceptor's catch handler called
logout(), destroying the session for all subsequent e2e tests.

Guard fetchQuota() with isAuthenticated so it only fires once the
session is fully restored.

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke

* chore: add debug session notes for storage quota investigation

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke

* test: add e2e assertions for storage quota after upload and reload

Add two new e2e tests:
- 3.6.1: Verifies quota display shows non-zero usage after uploading
  13+ files during the session
- 3.7.1: Verifies quota persists after page reload (regression test
  for the quota-stuck-at-zero bug where fetchQuota was never called
  on mount)

https://claude.ai/code/session_01F11Fe3ZAvUTbt4FHg4V5Ke

---------

Co-authored-by: Claude <noreply@anthropic.com>

* refactor: deduplicate drag detection and upload logic

Address PR review feedback:

1. Extract isExternalFileDrag(dataTransfer) helper into useDropUpload
   to replace repeated Files/application-json type checks across
   FileBrowser, FileListItem, and Breadcrumbs.

2. Refactor UploadZone and EmptyState to delegate upload logic to
   useDropUpload hook, eliminating triple-duplicated validation,
   quota checking, duplicate detection, and IPFS cleanup code.

3. Export MAX_FILE_SIZE from useDropUpload as single source of truth.

https://claude.ai/code/session_016z77d1zrWcRefW1Lhogprh

* chore: release 0.2.0 (#75)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: address CodeRabbit review feedback on drag-and-drop PR

Critical:
- handleFileDrop now returns boolean success indicator so
  UploadZone.onUploadComplete only fires after successful upload,
  not after validation failures or errors.

Nitpicks:
- Remove redundant useFileUpload() in UploadZone and EmptyState;
  get isUploading from useDropUpload instead.
- Remove dead catch blocks in UploadZone/EmptyState since
  handleFileDrop handles all errors internally.
- Consolidate double getData('application/json') call in
  FileListItem and Breadcrumbs drop handlers into single read.
- Add window dragend/dragleave/drop listeners in FileBrowser
  to reset drag counter when user abandons drag outside window.

https://claude.ai/code/session_016z77d1zrWcRefW1Lhogprh

* docs: align Pencil design with staging app + add interaction screens (Pt 2) (#81)

* docs(quick-005): align Pencil design with deployed staging app

Reorganized cipher-box-design.pen from scattered exploration frames
into a structured reference matching the actual staging deployment.

- Deleted 7 old exploration artifacts (Option A/B, Toolbar Options, etc.)
- Created 3 labeled sections: Desktop Screens, Mobile Screens, Components
- Rebuilt 5 desktop screens showing full E2E flow (login → file browser → context menu)
- Rebuilt 4 mobile screens with responsive layout differences (2-col, no sidebar)
- Fixed 8+ discrepancies between design and staging (text, colors, layout)
- No app code changes needed — staging implementation is accurate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(quick-005): add modal, DnD, scroll, and breadcrumb screens to Pencil design

Add 14 new screens (8 desktop + 6 mobile) covering interaction states
missing from the initial design alignment:

Desktop (screens 6-13):
- Rename dialog with green-glow input field
- Move dialog with folder tree and selection indicator
- Upload in progress with per-file progress bars
- DnD drag-to-folder with row/breadcrumb drop targets
- DnD upload drop zone with active glow effect
- Delete confirmation with destructive red action
- Scrollable file list (forward-looking) with scroll indicator
- Breadcrumb truncation (forward-looking) with collapsed "..." pill

Mobile (screens 5-10):
- Rename, Move, Upload, Delete modals (358px width)
- Scrollable file list with scroll track
- Breadcrumb truncation with aggressive collapse (root/…/current)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add Pencil MCP multi-screen design learnings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add file/folder details modal with CID and encryption metadata (#82)

* feat: add file/folder details modal with CID and encryption metadata

Add a Details option to the context menu that opens a modal showing
technical metadata for files and folders:

Files: content CID, folder metadata CID, encryption mode, file IV,
wrapped file key (redacted), size, timestamps.

Folders: IPNS name, metadata CID (live-resolved), sequence number,
wrapped folder key and IPNS key (redacted), child count, timestamps.

CID values are copyable to clipboard. Terminal aesthetic maintained.

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* docs(quick-006): add file/folder details modal

Quick task completed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* style: fix prettier formatting in DetailsDialog

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* chore: add package-lock.json

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* chore: remove erroneous package-lock.json

Project uses pnpm, not npm.

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* docs(learnings): quick-006 - use pnpm not npm

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* docs(quick-006): add Pencil design update spec for details modal

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* fix: address PR review feedback on DetailsDialog

- Wrap JSX comment text in braces to fix Biome noCommentText rule
- Add setTimeout cleanup via useRef to prevent state updates after unmount
- Add :focus-visible style on copy button for keyboard accessibility
- Reset metadataLoading on early return when IPNS name is missing
- Use null for unloaded folder childCount instead of misleading 0
- Add aria-label and aria-pressed to copy button for screen readers
- Apply base details-value class alongside modifier classes (--dim, --redacted)

https://claude.ai/code/session_01BACpg8j4E2GzGFJBCnGV9j

* feat(design): add file/folder details modal screens and context menu item

Add screens 14 (File Details Modal) and 15 (Folder Details Modal) with
full overlay pattern, and add "ⓘ Details" to the context menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test(e2e): add details dialog coverage and todo for flaky reload tests

Add DetailsDialogPage page object and tests 3.65/3.66 verifying file
and folder details modal (labels, badges, sections, copy buttons,
redacted values). Add clickDetails() to ContextMenuPage.

Also captures todo for pre-existing flaky tests 3.8/3.10 (IPNS
cold-load timing after page reload).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: reset metadataCid when ipnsName is missing on item change

Prevents stale CID from a previously viewed item being displayed when
the dialog item changes without closing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(learnings): pr review comment triage workflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove completed pencil design update spec

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: move batch-duplicate check outside folder guard and fix lint

- Move intra-batch duplicate filename check outside the `if (folder)`
  block so it runs even when the target folder isn't cached yet
- Replace forEach with for...of + void to avoid Biome lint error
  (useIterableCallbackReturn)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add external file drag-and-drop from Finder/Explorer

Files dragged from the OS file manager can now be dropped onto:
- The file browser area (uploads to current folder)
- Folder rows in the file list (uploads to that folder)
- Breadcrumb segments (uploads to that folder)

Internal drag-and-drop (move operations) continues to work as before.
External drags show a 'copy' cursor and visual feedback on the content
area. A new useDropUpload hook extracts reusable upload-on-drop logic.

https://claude.ai/code/session_016z77d1zrWcRefW1Lhogprh

* refactor: deduplicate drag detection and upload logic

Address PR review feedback:

1. Extract isExternalFileDrag(dataTransfer) helper into useDropUpload
   to replace repeated Files/application-json type checks across
   FileBrowser, FileListItem, and Breadcrumbs.

2. Refactor UploadZone and EmptyState to delegate upload logic to
   useDropUpload hook, eliminating triple-duplicated validation,
   quota checking, duplicate detection, and IPFS cleanup code.

3. Export MAX_FILE_SIZE from useDropUpload as single source of truth.

https://claude.ai/code/session_016z77d1zrWcRefW1Lhogprh

* fix: address CodeRabbit review feedback on drag-and-drop PR

Critical:
- handleFileDrop now returns boolean success indicator so
  UploadZone.onUploadComplete only fires after successful upload,
  not after validation failures or errors.

Nitpicks:
- Remove redundant useFileUpload() in UploadZone and EmptyState;
  get isUploading from useDropUpload instead.
- Remove dead catch blocks in UploadZone/EmptyState since
  handleFileDrop handles all errors internally.
- Consolidate double getData('application/json') call in
  FileListItem and Breadcrumbs drop handlers into single read.
- Add window dragend/dragleave/drop listeners in FileBrowser
  to reset drag counter when user abandons drag outside window.

https://claude.ai/code/session_016z77d1zrWcRefW1Lhogprh

* fix: move batch-duplicate check outside folder guard and fix lint

- Move intra-batch duplicate filename check outside the `if (folder)`
  block so it runs even when the target folder isn't cached yet
- Replace forEach with for...of + void to avoid Biome lint error
  (useIterableCallbackReturn)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(gsd): expand UI task detection keywords across all workflows

The UI keyword heuristic was missing interaction terms (drag, drop,
hover, animation, etc.) causing tasks like DnD to skip the design
workflow. Unified and expanded the keyword list across all 3 locations:
quick.md, discuss-phase.md, and gsd-verifier.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(design): add drag-and-drop interaction state screens

Add 4 new Pencil design screens (15-18) showing DnD visual feedback:
- Drop on content area: green border + overlay prompt
- Drop on folder row: row highlight with left accent
- Drop on breadcrumb: segment highlight box
- Drop on empty state: border + prominent upload CTA

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(desktop): log warning on IPNS sequence number parse failure

Replace silent unwrap_or(0) with explicit match that logs a warning
when the API returns a non-numeric sequence number. Prevents silent
sequence rollback on cold cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web): guard formatBytes against negative input

Math.log(negative) yields NaN, causing "NaN undefined" display.
Treat negative values the same as zero.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants