Skip to content

Fix: Address PR #401 review suggestions#402

Merged
masonfox merged 3 commits intodevelopfrom
fix/pr-401-review-suggestions
Mar 19, 2026
Merged

Fix: Address PR #401 review suggestions#402
masonfox merged 3 commits intodevelopfrom
fix/pr-401-review-suggestions

Conversation

@masonfox
Copy link
Copy Markdown
Owner

Summary

Addresses 4 code quality improvements identified in PR #401 review feedback.

Changes

1. Remove unused import (hooks/usePageTitle.ts)

  • Issue: useRef was imported but never used
  • Fix: Removed unused import to prevent lint failures
  • Impact: Clean code, no functional change

2. Fix shelf ID 0 handling bug (hooks/useShelfBooks.ts) 🐛

  • Issue: if (!shelfId) treats 0 as falsy, incorrectly skipping shelf ID 0
  • Fix: Changed to if (shelfId === null) for strict null checking
  • Impact: Critical bug fix - shelf with ID 0 now works correctly
  • Type: shelfId is typed as number | null, so this aligns with the type system

3. Add targeted query invalidations (hooks/usePullToRefreshLogic.ts)

  • Issue: Unmapped paths like /journal and /settings fell back to invalidating all queries
  • Fix: Added specific invalidation keys for these routes:
    • /journal["journal-entries", "journal-archive"]
    • /settings["user-preferences"]
  • Impact: Prevents expensive full-cache invalidation, improves pull-to-refresh performance

4. Use query key factory consistently (hooks/useLibraryData.ts)

  • Issue: Query key used hardcoded 'library-books' string while refresh used queryKeys.library.books()
  • Fix: Changed to [...queryKeys.library.books(), ...] for consistent factory usage
  • Impact: Prevents query key drift, ensures invalidation and query construction stay coupled

Testing

  • ✅ All tests passing: 4006/4007 tests (99.98%)
  • ✅ 1 pre-existing failure in streaks-coverage.test.ts (unrelated, already failing on develop)
  • ✅ No new test failures introduced
  • ✅ All 4 fixes verified with existing test coverage

Files Changed

  • lib/hooks/usePageTitle.ts - Removed unused import
  • hooks/useShelfBooks.ts - Fixed null check for shelf ID 0
  • hooks/usePullToRefreshLogic.ts - Added targeted invalidations
  • hooks/useLibraryData.ts - Use query key factory consistently

Review Feedback Source

PR #401 Review Comment Thread

Implements 4 code quality improvements from PR review feedback:

1. Remove unused import in usePageTitle.ts
   - Removed unused useRef import that would fail lint checks

2. Fix null check bug in useShelfBooks.ts (critical)
   - Changed '!shelfId' to 'shelfId === null' to properly handle shelf ID 0
   - Prevents incorrectly skipping shelf with ID 0

3. Add targeted query invalidations for journal/settings
   - Added specific invalidation keys for /journal and /settings routes
   - Prevents expensive fallback that invalidates all queries
   - Improves pull-to-refresh performance on these pages

4. Use query key factory consistently in useLibraryData.ts
   - Changed from hardcoded 'library-books' to queryKeys.library.books()
   - Prevents query key drift between invalidation and query construction
   - Ensures refresh and invalidation stay coupled to factory

All fixes verified with test suite (4006/4007 tests passing, 1 pre-existing failure unrelated to changes).

Resolves review feedback from: #401 (review)
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 19, 2026

Codecov Report

❌ Patch coverage is 70.00000% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
lib/query-keys.ts 0.00% 2 Missing ⚠️
hooks/useShelfBooks.ts 87.50% 0 Missing and 1 partial ⚠️

❌ Your patch status has failed because the patch coverage (70.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #402      +/-   ##
===========================================
- Coverage    78.64%   78.62%   -0.03%     
===========================================
  Files          167      167              
  Lines         7538     7540       +2     
  Branches      1846     1846              
===========================================
  Hits          5928     5928              
- Misses        1125     1127       +2     
  Partials       485      485              
Flag Coverage Δ
unittests 78.62% <70.00%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
hooks/useLibraryData.ts 78.84% <ø> (ø)
lib/hooks/usePageTitle.ts 70.58% <ø> (ø)
hooks/useShelfBooks.ts 96.36% <87.50%> (ø)
lib/query-keys.ts 94.11% <0.00%> (-5.89%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The previous implementation incorrectly passed an array ['journal-entries', 'journal-archive']
as a single query key to invalidateQueries. This would not match the actual query keys used
in the journal page (['journal-entries', timezone] and ['journal-archive', timezone]).

Fixed by using explicit parallel invalidation with Promise.all to properly invalidate both
journal entries and archive queries using prefix matching.

Also removed unnecessary settings page entry since that page doesn't use React Query.

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 applies follow-up fixes from PR #401 review feedback, mainly around React Query key consistency, targeted cache invalidation, and a shelf ID edge case.

Changes:

  • Removes an unused React import in usePageTitle.
  • Adjusts useShelfBooks to treat shelfId = 0 as valid (null-only guard).
  • Adds a /journal special-case in pull-to-refresh to avoid full-cache invalidation.
  • Aligns useLibraryData’s query key construction with the centralized queryKeys factory.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
lib/hooks/usePageTitle.ts Removes unused useRef import.
hooks/useShelfBooks.ts Updates null-checking for shelf fetching logic.
hooks/usePullToRefreshLogic.ts Adds targeted invalidation for /journal instead of invalidating all queries.
hooks/useLibraryData.ts Uses queryKeys.library.books() as the base for the infinite query key.

You can also share your feedback on Copilot code review. Take the survey.

Implemented all suggestions from Copilot review:

1. Complete shelfId=0 bug fix in useShelfBooks.ts
   - Replaced all 7 instances of !shelfId with shelfId === null
   - Fixes: addBooksMutation, removeBookMutation, removeBooksMutation,
     reorderBooksMutation, moveBooksMutation, moveToTopMutation, moveToBottomMutation
   - Now shelf ID 0 is properly supported across all operations

2. Add query key factory base methods
   - Added queryKeys.journal.entriesBase() returning ['journal-entries']
   - Added queryKeys.journal.archiveBase() returning ['journal-archive']
   - Prevents key drift between query definition and invalidation
   - Aligns with Query Key Factory Pattern from patterns.md

3. Use factory methods in usePullToRefreshLogic.ts
   - Replaced hardcoded strings with queryKeys.journal.entriesBase()
   - Replaced hardcoded strings with queryKeys.journal.archiveBase()
   - Ensures consistency with centralized query key factory

All 4007 tests pass.
Repository owner deleted a comment from Copilot AI Mar 19, 2026
@masonfox masonfox requested a review from Copilot March 19, 2026 13:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 addresses review feedback from PR #401 by tightening query key consistency, fixing a shelf ID edge case, and reducing unnecessary React Query invalidations to improve refresh performance.

Changes:

  • Fixed shelfId === 0 being treated as “missing” by switching falsy checks to strict null checks in useShelfBooks.
  • Added journal base query keys and used them to invalidate journal caches via prefix matching on pull-to-refresh.
  • Updated library query key construction to consistently use the centralized query key factory.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/query-keys.ts Adds base journal keys for prefix invalidation (entriesBase, archiveBase).
lib/hooks/usePageTitle.ts Removes an unused React import.
hooks/useShelfBooks.ts Fixes shelf ID 0 handling by using strict null checks.
hooks/usePullToRefreshLogic.ts Adds targeted invalidation for /journal via base keys (but /settings handling appears missing vs PR description).
hooks/useLibraryData.ts Uses queryKeys.library.books() as the base for the infinite query key to prevent drift.
Comments suppressed due to low confidence (1)

hooks/usePullToRefreshLogic.ts:62

  • PR description says pull-to-refresh adds targeted invalidation for /settings (e.g. ['user-preferences']), but /settings is still not mapped here, so it will fall through to invalidateQueries() and invalidate the entire cache. Either add an explicit /settings invalidation key (and define it in lib/query-keys.ts) or update the PR description to match the actual behavior.
      // Map pages to their query key invalidation
      const invalidationsByPath: Record<string, readonly unknown[]> = {
        "/": queryKeys.dashboard.all(),
        "/library": queryKeys.library.books(),
        "/read-next": queryKeys.readNext.base(),
        "/series": queryKeys.series.all(),
        "/stats": queryKeys.stats.all(),
        "/goals": queryKeys.goals.base(),
        "/streak": queryKeys.streak.base(),
        "/shelves": queryKeys.shelf.base(),
        "/tags": queryKeys.tags.base(),
      };

      const queryKey = invalidationsByPath[pathname];
      
      if (queryKey) {
        await queryClient.invalidateQueries({ queryKey });
      } else if (pathname === "/journal") {
        // Special case: Invalidate both journal entries and archive using prefix matching
        await Promise.all([
          queryClient.invalidateQueries({ queryKey: queryKeys.journal.entriesBase() }),
          queryClient.invalidateQueries({ queryKey: queryKeys.journal.archiveBase() }),
        ]);
      } else {
        // Fallback: invalidate all queries if we don't have specific keys
        await queryClient.invalidateQueries();
      }

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 199 to +205
journal: {
/** Base key for journal entries (prefix matching): ['journal-entries'] */
entriesBase: () => ['journal-entries'] as const,

/** Base key for journal archive (prefix matching): ['journal-archive'] */
archiveBase: () => ['journal-archive'] as const,

@masonfox masonfox merged commit 5c5e0d9 into develop Mar 19, 2026
7 of 8 checks passed
@masonfox masonfox deleted the fix/pr-401-review-suggestions branch March 19, 2026 13:36
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