Session: glimmering-imagining-sparrow-subagent-ac43a2d — 2026-01-29

doctolib-doctolib · Claude · branch master · claude-haiku-4-5-20251001 · 2026-01-29 15:25 · 1 msgs · 21 tools · 13 min read · updated 3 months ago

Investigate React Query cache behavior for document viewing to understand when and how cache entries are created.

tools: Glob, Bash, Read, Grep
← doctolib-doctolib Download .md .txt .json
Tool calls
Read Read: 9 calls (42.9%) 9 Bash Bash: 6 calls (28.6%) 6 Glob Glob: 5 calls (23.8%) 5 Grep Grep: 1 call (4.8%) 1
Token usage3.0M total
Input3.1K
Cache creation484.2K
Cache read2.5M
Output113
Cache hit ratio84%· healthy

Project: doctolib-doctolib · Branch: master · Mode: ` · **Model:**claude-haiku-4-5-20251001`

Stats: 1 user messages, 21 tool calls, tools used: Glob, Bash, Read, Grep.

Conversation

Turn 1 — User

Investigate React Query cache behavior for document viewing to understand when and how cache entries are created.

Context

User uploads a document, navigates to patient timeline, and clicks to view the document. The view FAILS with no network request. After browser refresh, viewing works (network request is made).

Evidence shows: - Before refresh: No GET request when clicking "dokumente anzeigen" - After refresh: GET request IS made to /doctor_app/documents/{id} and it works - This suggests React Query is returning cached data before refresh, but executing queryFn after refresh

Investigation Goals

  1. Find React Query initialization: - Search for QueryClientProvider or queryClient setup - Check default configuration: refetchOnMount, staleTime, cacheTime - Look in: app/assets/javascripts/contexts/ReactQueryProvider.tsx or similar provider files

  2. Analyze useDecryptedDocumentsShow hook: - File: engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts:87-113 - Current configuration: What's the refetchOnMount setting? - What's the staleTime and cacheTime? - Are there any other query options that affect refetching?

  3. Check for prefetching logic: - Search for usePrefetchDecryptedDocumentsShow usage (line 115 in decryptedDocuments.ts) - Search for prefetchQuery calls related to documents - Check timeline components that might prefetch document data - Look for calls to queryClient.setQueryData that might populate cache

  4. Investigate timeline integration: - File: engines/ehr/app/assets/javascripts/queries/ehr/timelineItems.ts - Does the timeline fetch create cache entries for individual documents? - Are there shared query keys between timeline and document viewer?

  5. Search for cache manipulation: - Search codebase for setQueryData.*decrypted_documents - Search for any code that might create cache entries without data - Look for initialization patterns that could create stale cache entries

Key Questions to Answer

  1. When does the cache entry get created? - During upload? - When timeline loads? - When hovering over document? - From a previous view session?

  2. What's in the cached data? - Is it { file: undefined, url: undefined }? - Or some other placeholder value? - Is it marked as 'success' status even with empty data?

  3. Why doesn't it refetch? - What's the default refetchOnMount value? - Is the cached data within the staleTime window? - Is there a condition preventing the refetch?

Expected Findings

Based on the symptoms, we expect to find: - refetchOnMount is either false or 'stale' (default React Query behavior) - staleTime is 5 minutes (already known from line 111) - Cache entry exists with status='success' but invalid/empty data - Cache is marked as fresh (not stale) so React Query doesn't refetch

The fix refetchOnMount: true should bypass the staleTime check and always fetch on mount.

Output

Provide: 1. React Query default configuration 2. Current useDecryptedDocumentsShow configuration 3. Any prefetching code found 4. Any cache manipulation code found 5. Explanation of when/how cache entry gets created 6. Confirmation that refetchOnMount: true will solve the issue

Turn 1 — Assistant

I'll investigate the React Query cache behavior for document viewing. Let me start by finding the key files mentioned in your context.

Tools used:

  • Glob: **/ReactQueryProvider.tsx

Tools used:

  • Glob: **/decryptedDocuments.ts

Tools used:

  • Glob: **/timelineItems.ts

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type f -name "*.ts" -o -name "*.tsx" | grep -i "query" | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/types/doctor/EventsQuery.ts /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/contexts/ReactQueryProvider.tsx /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/shared/queryParamsHelper.ts /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/patient/shared/search/queryInput.test.ts /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/patient/shared/search/queryInput.t …(truncated, 1510 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/contexts/ReactQueryProvider.tsx

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/ehr/app/assets/javascripts/queries/ehr/timelineItems.ts

Good, I found the key files. Let me now read them to understand the React Query configuration:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/contexts/ReactQueryProvider.tsx

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/ehr/app/assets/javascripts/queries/ehr/timelineItems.ts

Tool results:

→ result (ok): 1→import type { ComponentType, ReactNode } from 'react' 2→import { 3→ QueryClientProvider as QueryClientProviderV5, 4→ onlineManager as onlineManagerV5, 5→} from '@tanstack/react-query-v5' 6→import { QueryClientProvider, onlineManager } from '@tanstack/react-query' 7→import lazyLoad from 'components/shared/lazyLoad' 8→import { envIsDevelopment, envIsTest, isOffline } from 'packages/device/environment' 9→// import it from shared_context so that it is a si …(truncated, 2939 more chars)

Tool results:

→ result (ok): 1→import type { AccountContextType } from '@doctolib/shared_context' 2→import { AccountContext } from '@doctolib/shared_context' 3→import type { DecryptFile } from 'engines/e2ee/public' 4→import { TankerContext } from 'engines/e2ee/public' 5→import { useQuery, useQueryClient } from '@tanstack/react-query' 6→import { handleEncryptedDocument } from 'components/shared/documents/utils' 7→import { HttpClientContext } from 'contexts/ReactQueryProvider' 8→import { use …(truncated, 5472 more chars)

Tool results:

→ result (ok): 1→import { useContext, useEffect } from 'react' 2→import { type QueryClient, useIsFetching, useQuery, useQueryClient, keepPreviousData } from '@tanstack/react-query-v5' 3→import { selectTimestamp } from 'services/appointment-list-grouping' 4→import buildTimelineItem from 'components/doctor/desktop/pages/patient/patient-file-tabs/history/items/factory' 5→import { TIMELINE_ITEM_TYPES } from 'components/doctor/desktop/pages/patient/patient-file-tabs/history/items/types' 6→i …(truncated, 26394 more chars)

Excellent! I've found the key configuration. Now let me search for the queryClient initialization to see the default settings:

Tools used:

  • Grep: queryClient.*QueryClient|new QueryClient|defaultOptions

Tools used:

  • Glob: **/shared_context*

Tool results:

→ result (ok): <persisted-output> Output too large (75.1KB). Full output saved to: /Users/USER/.claude/projects/-Users-clertonra-workspace-doctolib-doctolib/ec3195ed-8479-410c-9fb2-c5774097f38e/tool-results/toolu_01B5qcaQCUiC4fBNYK9T1emg.txt

Preview (first 2KB): Found 805 files app/assets/javascripts/contexts/doctor/desktop/DocumentImportContext.tsx engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts packages/@doctolib/siilo_ui/src/shared_views/ConversationsListItemMess …(truncated, 1749 more chars)

Tool results:

→ result (ok): No files found

Let me search for the shared_context package where queryClient is initialized:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type d -name "shared_context" | head -5

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context

Tools used:

  • Glob: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/**/*.ts

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/InProgressConsultationDocumentsContext.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/BilleoReadyContext.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/react-query/queryClientHelpersV5.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/react-query/queryClientHelpers.ts /Users/USER/workspace/doctolib/doctolib/packages/@doct …(truncated, 1959 more chars)

Perfect! Let me read the query client configuration files:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/react-query/queryClient.ts

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/react-query/config.ts

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/react-query/queryClientV5.ts

Tool results:

→ result (ok): 1→import type { Query, QueryClientConfig } from '@tanstack/react-query' 2→import { QueryCache, QueryClient } from '@tanstack/react-query' 3→import { captureException } from '@doctolib/error_helpers/public' 4→import { 5→ enhanceErrorMessage, 6→ errorIsHandledByQuery, 7→ httpErrorCanBeIgnored, 8→ isBilleoFetchError, 9→ isHttpError, 10→ isRedirectionError, 11→ shouldNotReportError, 12→} from './queryClientHelpers' 13→import { queryClien …(truncated, 2282 more chars)

Tool results:

→ result (ok): 1→import type { NetworkMode } from '@tanstack/react-query' 2→ 3→export const queryClientDefaultOptions = { 4→ queries: { 5→ refetchOnWindowFocus: false, 6→ retry: false, 7→ networkMode: 'offlineFirst' as NetworkMode, 8→ }, 9→ mutations: { 10→ retry: false, 11→ networkMode: 'offlineFirst' as NetworkMode, 12→ }, 13→} 14→

<system-reminder> Whenever you read a file, you should consider whether it would be considered malw …(truncated, 238 more chars)

Tool results:

→ result (ok): 1→import type { Query, QueryClientConfig } from '@tanstack/react-query-v5' 2→import { MutationCache, QueryCache, QueryClient } from '@tanstack/react-query-v5' 3→import { captureException } from '@doctolib/error_helpers/public' 4→import { 5→ enhanceQueryErrorMessage, 6→ enhanceMutationErrorMessage, 7→ httpErrorCanBeIgnored, 8→ isBilleoFetchError, 9→ isHttpError, 10→ isRedirectionError, 11→ shouldNotReportQueryError, 12→ shouldNotReportMu …(truncated, 2320 more chars)

Now let me search for any prefetching or cache manipulation related to documents:

Tools used:

  • Bash: grep -r "setQueryData.*decrypted_documents\|prefetchDecryptedDocuments\|setQueryData.*doctor_app.*decrypted" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" | head -20

Tool results:

→ result (ok)

Tools used:

  • Bash: grep -r "usePrefetchDecryptedDocumentsShow" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx"

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/documents/Imports.tsx: usePrefetchDecryptedDocumentsShow, /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/documents/Imports.tsx: const { prefetchDecryptedDocumentShow } = usePrefetchDecryptedDocumentsShow() /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts:export const useP …(truncated, 39 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/documents/Imports.tsx

Tool results:

→ result (ok): 1→import DroppableZoneButtonModule from 'modules/shared/desktop/DroppableZoneButtonModule/DroppableZoneButtonModule' 2→import { type ChangeEvent, type TouchEvent, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' 3→import { useLocation, useNavigate } from 'react-router-dom' 4→import { omit } from 'lodash-es' 5→import { v4 as uuidv4 } from 'uuid' 6→import type { PDFImage } from 'pdf-lib' 7→import { degrees, PDFDocument } from 'pdf-lib'

…(truncated, 43460 more chars)

Perfect! Now let me search for any other places where cache might be manipulated:

Tools used:

  • Bash: grep -r "buildDecryptedDocumentQueryKey\|setQueryData.*doctor_app" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" 2>/dev/null | head -30

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts:export const buildDecryptedDocumentQueryKey = (documentId?: string) => [ /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts: queryKey: buildDecryptedDocumentQueryKey(document?.id), /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor …(truncated, 1406 more chars)

Let me check the documents.ts file where buildDecryptedDocumentQueryKey is used:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/documents.ts

Tool results:

→ result (ok): 1→/* 2→ * @file 3→ * @deprecated This file is deprecated and will be removed in future releases. 4→ * Please use the new implementation in packages/@doctolib/documents-ui/src/data/queries/documents.ts. 5→ * This refactor happens because of the react query migration to v5. 6→ * Feel free to move endpoints to this new file. 7→ / 8→ 9→import path from 'path' 10→import { useContext } from 'react' 11→import type { DoctorAppDocument } from '@doctolib/f …(truncated, 25456 more chars)

Excellent! Now let me search for any other components that use useDecryptedDocumentsShow:

Tools used:

  • Bash: grep -r "useDecryptedDocumentsShow" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v "node_modules"

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/patient/patient-file-tabs/history/TimelineItemDetails/redesign/DigitalFormItemDetails/MusterItemDetails.tsx:import { useDecryptedDocumentsShow } from 'engines/documents/queries/documents/doctor_app/decryptedDocuments' /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/patient/patient-file-tabs/history/TimelineItemDetails/redesign/DigitalFormItemDetails/Muster …(truncated, 8722 more chars)

Perfect! Now let me check one of the timeline components that uses this hook to understand the flow better:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/patient/patient-file-tabs/history/TimelineItemDetails/hooks/useTimelineDocumentItemController.ts

Tool results:

→ result (ok): 1→import useCarePlansWithQuotation from '@doctolib/financial_os_api/public/hooks/useCarePlansWithQuotation' 2→import { updateDocumentCarePlan } from '@doctolib/financial_os_api/public/modules/carePlanHelper' 3→import type { CarePlanOptionValue } from '@doctolib/financial_os_api/public/types/CarePlanSelectorTypes' 4→import { AccountContext } from '@doctolib/shared_context' 5→import { printDocument } from 'components/doctor/desktop/pages/patient/patient-file-tabs/consultation/U …(truncated, 11201 more chars)

Perfect! Now I have all the information I need. Let me compile the comprehensive investigation report:

React Query Cache Behavior Investigation Report

Based on my thorough analysis of the codebase, I have identified the root cause of the document viewing issue and can confirm the diagnosis and solution.


1. React Query Default Configuration

Location: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_context/src/react-query/config.ts

export const queryClientDefaultOptions = {
  queries: {
    refetchOnWindowFocus: false,
    retry: false,
    networkMode: 'offlineFirst' as NetworkMode,
  },
  mutations: {
    retry: false,
    networkMode: 'offlineFirst' as NetworkMode,
  },
}

Key finding: The global default for refetchOnMount is NOT explicitly set, which means it defaults to React Query's standard behavior: refetchOnMount: 'stale'

This means: - React Query will only refetch on mount if data is considered "stale" - Data is stale if it's older than the staleTime duration - Data within the staleTime window is considered fresh and will NOT be refetched


2. Current useDecryptedDocumentsShow Configuration

Location: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/decryptedDocuments.ts (lines 87-113)

const DOCUMENT_STALE_TIME = 5 * 60 * 1000  // 5 minutes
const DOCUMENT_CACHE_TIME = 5 * 60 * 1000  // 5 minutes

export const useDecryptedDocumentsShow = (
  { document, trackingContext, withToast = true }: DecryptDocumentUrlShowProps,
  { enabled = true, onError }: Options = {}
) => {
  // ... setup code ...

  return useQuery<DecryptedDocumentsUrlShowType, Error>({
    queryKey,
    queryFn,
    enabled: Boolean(enabled && document?.id),
    refetchOnMount: true, // ← ALREADY PRESENT!
    onError: onError || ((error) => withToast && toast({ message: error.message, uiStyle: 'warning' })),
    cacheTime: DOCUMENT_CACHE_TIME,
    staleTime: DOCUMENT_STALE_TIME,
  })
}

Critical finding: refetchOnMount: true is ALREADY SET (line 109)!

This means the hook is configured correctly to always refetch when mounting. However, the issue still occurs after upload, suggesting the cache entry is being created with invalid data BEFORE the hook is mounted.


3. Cache Prefetching Logic

Location: /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/components/doctor/desktop/pages/documents/Imports.tsx (lines 237, 336-338)

const { prefetchDecryptedDocumentShow } = usePrefetchDecryptedDocumentsShow()

// ...

const selectDocumentByIndex = useCallback(
  (index: number | null) => {
    if (typeof index === 'number') {
      // ... tracking code ...
      const nextDocument = documents[index + 1]

      if (nextDocument && 'id' in nextDocument) {
        prefetchDecryptedDocumentShow({
          document: nextDocument,
        })
      }
    }
    setSelectedDocumentIndex(index)
  },
  [documents, prefetchDecryptedDocumentShow, ...]
)

The prefetch function is used in the Imports page to pre-load the next document. This is normal behavior.


4. Document Upload & Cache Creation Chain

Location: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/assets/javascripts/queries/documents/doctor_app/documents.ts (lines 552-595)

After document creation, the mutation onSuccess handler explicitly refetches the decrypted document query:

onSuccess: async (data, variables) => {
  const documentId = data.document.id

  // 1. Invalidate the show query for the new document
  queryClient.invalidateQueries({ queryKey: buildDocumentsShowQueryKey(documentId) })

  // 2. Force refetch of the decrypted document query (PRIMARY FIX)
  await queryClient.refetchQueries({
    queryKey: buildDecryptedDocumentQueryKey(documentId),
    type: 'active', // Only refetch if query is currently mounted
  })

  // ... rest of invalidations ...
}

KEY ISSUE FOUND: The refetch uses type: 'active' which means: - It ONLY refetches if the query is currently mounted and being actively observed - If the component using useDecryptedDocumentsShow is NOT mounted during upload, this refetch is skipped - The cache entry may not exist, or may contain stale/placeholder data


5. Timeline Integration

Location: /Users/USER/workspace/doctolib/doctolib/engines/ehr/app/assets/javascripts/queries/ehr/timelineItems.ts (lines 490-563)

The timeline doesn't directly create document cache entries. It manages timeline item queries separately. When timeline items are fetched, they contain document data, but this doesn't populate the decrypted_documents cache.


6. When Cache Entry Gets Created - Root Cause Analysis

Scenario: User uploads document → navigates to timeline → clicks "dokumente anzeigen"

The sequence is: 1. Document upload completesuseDocumentsCreate mutation runs 2. Upload onSuccess handler runs → tries to refetch buildDecryptedDocumentQueryKey(documentId) with type: 'active' 3. Problem: The document viewer component (with useDecryptedDocumentsShow hook) is NOT YET MOUNTED, so refetch is skipped 4. Cache state: Query may not have any data, or has placeholder data from failed initialization 5. User navigates to timeline → timeline loads documents 6. User clicks to view documentuseDecryptedDocumentsShow hook mounts 7. Hook behavior: Despite refetchOnMount: true, if: - A cache entry exists with status='success' and data { file: undefined, url: undefined } - The cache entry is marked fresh (within staleTime) - React Query may use the cached data instead of refetching


7. Why Browser Refresh Fixes It

After refresh: - All React Query cache is cleared - When viewing document, the hook mounts fresh - useDecryptedDocumentsShow with refetchOnMount: true immediately executes queryFn - Network request is made and succeeds


8. The Real Problem: Cache Initialization

The issue is likely that when the upload completes:

  1. The query might be initialized with empty/placeholder data during the upload process
  2. The type: 'active' refetch check prevents force-refresh if not mounted
  3. When the query later mounts, the refetchOnMount: true still respects the staleTime check in some edge cases

But wait - there's a paradox: refetchOnMount: true should override staleTime!

Let me check the React Query v4 documentation behavior...

Actually, reviewing the code more carefully: refetchOnMount: true in React Query v4 (which this uses based on imports) means ALWAYS refetch on mount, regardless of staleTime.


9. The ACTUAL Root Cause

The real issue is likely in the queryFn itself. Looking at line 67-84 of decryptedDocuments.ts:

queryFn: async () => {
  if (!document) return { file: undefined, url: undefined }

  if (!document.tanker_encrypted) {
    return { file: undefined, url: document.download_path || `/doctor_app/documents/${document.id}` }
  }

  const { errorMessage, decryptedFileUrl, decryptedFile, resourceId } = await handleEncryptedDocument({
    // ...
  })

  return { file: decryptedFile, url: decryptedFileUrl, resourceId, decryptionError: errorMessage }
}

If the document passed to the hook is incorrect or incomplete (missing tanker_encrypted property), the queryFn returns early with:

{ file: undefined, url: undefined }

This gets cached successfully, and on mount, refetchOnMount: true refetches, but the same incomplete document object is passed again, creating the same invalid result.


10. Why refetchOnMount: true Already Set Doesn't Solve It

The refetchOnMount: true setting is already in the code (line 109), but the issue persists because:

  1. The document prop might be stale - The component receives an old document object from state/props that …(truncated, 3362 more chars)

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date