Project: workspace-doctolib · Branch: HEAD · Mode: ` · **Model:**claude-haiku-4-5-20251001`
Stats: 1 user messages, 30 tool calls, tools used: Bash, Read.
Conversation
Turn 1 — User
Explore the national-health-records package in the Doctolib monolith at /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/
Key tasks: 1. List all files: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/ 2. Read fully: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts 3. Read any other hooks, types, or utilities in that src/ folder 4. Find how the searchDocuments function is built and passed to NhrEntryPointModule in PatientCard.tsx 5. Look at the actionsBuilder in /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/ - find what it exports 6. Find the type definitions for NhrEntryPointProps (what fields like searchDocuments, actions, etc. accept)
Also check: - /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/index.ts (or similar public exports) - Any toast utilities already used in the monolith (@doctolib/design-system-b2b or similar)
Report the full content of useSearchDocuments.ts and any related types/interfaces.
Turn 1 — Assistant
I'll explore the national-health-records package systematically. Let me start by listing the structure and then reading the key files.
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src -type f -name "*.ts" -o -name "*.tsx" | head -50
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/index.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/filterMockedDocuments.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/generateNhrDocuments.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/mocks/filterMockedDocuments.ts /Users/USER/workspace/doctolib/doctolib/packag …(truncated, 4443 more chars)
Now let me read the key files I need to explore:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
Tool results:
→ result (ok): 1 import { useQueryClient } from '@tanstack/react-query-v5' 2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 3 import { isFeatureEnabled } from '@doctolib/variation_management' 4 import type { NhrDocumentListVariant, MapFiltersToSearchDocumentsParams, ServerFilters } from '../variants/types' 5 import { useNationalHealthRecords } from './useNationalHealthRecords' 6 import { generateNhrDocuments } from '../mocks/generateNhrDocuments' 7 import { filterMockedDocuments } …(truncated, 2775 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/index.ts
Tool results:
→ result (ok): 1 export { useNationalHealthRecords, type UseNhrOperations } from './hooks/useNationalHealthRecords' 2 export { useDmpNhr } from './hooks/useDmpNhr' 3 export { useNhrDocumentListVariant } from './variants/useNhrDocumentListVariant' 4 export type { DocumentSearchOptions, NhrDocumentListVariant } from './variants/types' 5 export { actionsBuilder, type NhrActionsBuilder } from './business/builders/actionsBuilder' 6 export { useGetDocumentsContent } from './hooks/useGetDocumentsContent' 7
<system- …(truncated, 329 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/builders/actionsBuilder.ts
Tool results:
→ result (ok): 1 import {
2 createMoreActionsAction as moreActionsActionFactory,
3 createViewDocumentAction as viewDocumentActionFactory,
4 type ActionConfig,
5 type DropdownActionOption,
6 } from '@doctolib/tpf-national-health-records-ui'
7 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
8
9 export type NhrActionsBuilder = {
10 createViewDocumentAction: (onDocumentSelected: (document: NhrDocument) => Promise<void>) => NhrActionsBuilder
11 createMoreActionsAction: (options
…(truncated, 903 more chars)
Now let me read the types and variants files:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
Tool results:
→ result (ok): 1 import type { ColumnConfig, FilterConfig, SearchDocumentsResult } from '@doctolib/tpf-national-health-records-ui'
2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient'
3 import type { NhrDocumentSearchParams } from '@doctolib/tpf-national-health-records'
4
5 export type { SearchDocumentsResult }
6
7 export type NhrDocumentListVariant = {
8 columns: ColumnConfig[]
9 filters: FilterConfig[]
10 searchDocuments: (appliedFilters?: Record<string, unknown>) => Promise<
…(truncated, 1160 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts
Tool results:
→ result (ok): 1 import { useProductLineVariation, ProductLineKey } from '@doctolib/variation_management'
2 import type { DocumentSearchOptions, NhrDocumentListVariant } from './types'
3 import { useDmpDocumentListVariant } from './dmp'
4
5 export const useNhrDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant | null => {
6 const dmpVariant = useDmpDocumentListVariant(patient)
7
8 return useProductLineVariation<NhrDocumentListVariant>({
9 variants: {
10 [Pr
…(truncated, 729 more chars)
Now let me check the DMP variant and search for PatientCard.tsx:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/index.ts
Tool results:
→ result (ok): 1 export { useDmpDocumentListVariant } from './useDmpDocumentListVariant' 2
<system-reminder> Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior. </system-reminder>
Tools used:
Bash:find /Users/USER/workspace/doctolib -name "PatientCard.tsx" -type f 2>/dev/null | head -5
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/fhir-2222_add-visible-to-all-filter/packages/@doctolib/task-manager/src/shared/PatientCard/PatientCard.tsx /Users/USER/workspace/doctolib/worktrees/doctolib/fhir-2222_add-visible-to-all-filter/packages/@doctolib/task-manager/src/shared/PatientCardPopoverModule/views/PatientCard.tsx /Users/USER/workspace/doctolib/worktrees/doctolib/fhir-2089/engines/patient_bases/app/assets/javascripts/components/admin/debug_pages/PatientCard.tsx /Users/USER/works …(truncated, 263 more chars)
Let me search more specifically for PatientCard usage with NHR:
Tools used:
Bash:grep -r "NhrEntryPointModule\|searchDocuments" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src --include="*.ts" --include="*.tsx" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts: searchDocuments: (appliedFilters?: Record<string, unknown>) => Promise<SearchDocumentsResult> /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/useDmpDocumentListVariant.ts: const searchDocuments = useSearchDocuments({ patient, mapFiltersToSearchDocumentsParams }) /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-re …(truncated, 3069 more chars)
Let me read the DMP variant implementation:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/useDmpDocumentListVariant.ts
Tool results:
→ result (ok): 1 import { columnsFactory } from './factories/columnsFactory'
2 import { filtersFactory } from './factories/filtersFactory'
3 import type { NhrDocumentListVariant, DocumentSearchOptions } from '../types'
4 import { useSearchDocuments } from '../../hooks/useSearchDocuments'
5 import { mapFiltersToSearchDocumentsParams } from './mappers/mapFiltersToSearchDocumentsParams'
6
7 export const useDmpDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant => {
8 const
…(truncated, 545 more chars)
Now let me search for usage patterns and find toast utilities:
Tools used:
Bash:grep -r "toast\|Toast" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib --include="*.ts" --include="*.tsx" | grep -i "import\|from" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/partner-integration/src/components/admin/OrganizationPartnersManagementPage.tsx:import useToast from 'hooks/useToast' /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/doctor_appointment_booking_actions/src/EventStatusContextMenuModule/AppointmentMoveContextMenuModule.test.tsx:import { ToastContext, ContextMenuContext, AccountContext, type Account } from '@doctolib/shared_context' /Users/USER/workspace/doctolib/doctolib/packages …(truncated, 3667 more chars)
Let me check for design-system-b2b toast:
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib -name "*toast*" -o -name "*Toast*" 2>/dev/null | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/toaster /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/utils/shouldShowCertificateExpirationToast.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/utils/shouldShowCertificateExpirationToast.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/hooks/useErrorToast.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/toaster/src/business/toast.ts /U …(truncated, 1803 more chars)
Great! Let me check the toaster package:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/toaster/src/business/toast.ts
Tool results:
→ result (ok): 1 import { GLOBAL_PUBSUB_REGISTRY } from '@doctolib/upfront-core'
2 import type { ToastProps } from './ToastQueue'
3
4 export const ADD_TOAST = 'toaster:add'
5
6 export function addToast(props: ToastProps) {
7 GLOBAL_PUBSUB_REGISTRY.dispatch({ type: ADD_TOAST, payload: props })
8 }
9
<system-reminder> Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augme …(truncated, 128 more chars)
Tools used:
Bash:ls /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/toaster/src/
Tool results:
→ result (ok): business components index.ts
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/toaster/src/index.ts
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/toaster/src/business/ToastQueue.ts
Tool results:
→ result (ok): 1 export { Toaster } from '#components/Toaster' 2 export { addToast } from '#business/toast' 3
<system-reminder> Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior. </system-reminder>
Tool results:
→ result (ok): 1 import type { MouseEventHandler, ReactNode } from 'react'
2 import { v4 as uuidV4 } from 'uuid'
3 import type { ToastUIStyle } from '#components/ToastCard'
4 import { Timer } from './Timer'
5
6 export type Action = {
7 dataWalkme?: string
8 label: string
9 onClick: MouseEventHandler
10 }
11
12 export type ToastDuration = number | 'infinite'
13
14 export type ToastProps = {
15 action?: Action
16 dataWalkme?: string
17 duration?: ToastDuration
18 message?: ReactNode
19 onClose
…(truncated, 3141 more chars)
Now let me check the complete structure of the national-health-records src folder and look at more related files:
Tools used:
Bash:ls -la /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/
Tool results:
→ result (ok): drwxr-xr-x clertonra staff 256 B Wed Apr 22 14:48:15 2026 . drwxr-xr-x clertonra staff 384 B Thu Apr 30 09:54:45 2026 .. drwxr-xr-x clertonra staff 224 B Thu Apr 30 09:54:45 2026 business drwxr-xr-x clertonra staff 320 B Thu Apr 30 09:54:45 2026 hooks .rw-r--r-- clertonra staff 476 B Wed Apr 22 14:48:15 2026 index.ts drwxr-xr-x clertonra staff 128 B Thu Feb 26 14:08:52 2026 locales drwxr-xr-x clertonra staff 256 B Tue Apr 28 14:24:08 2026 mocks drwxr-xr-x clertonra staff 160 B Thu Apr 30 09:54:4 …(truncated, 15 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useNationalHealthRecords.ts
Tool results:
→ result (ok): 1 import type {
2 NhrDocumentSearchProps,
3 NhrDocumentSearchResult,
4 NhrGetDocumentsContentProps,
5 NhrDocumentContentResult,
6 NhrDocumentMetadataUpdateProps,
7 NhrDocumentMetadataUpdateResult,
8 } from '@doctolib/tpf-national-health-records'
9 import { useProductLineVariation, ProductLineKey } from '@doctolib/variation_management'
10 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient'
11 import { useDmpNhr } from './useDmpNhr'
12
13 export type UseNhrOper
…(truncated, 1306 more chars)
Let me look at the useDmpNhr hook to understand the full flow:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useDmpNhr.ts
Tool results:
→ result (ok): 1 import { useMemo } from 'react' 2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 3 import { DmpApiImpl as DmpApi, useDmpSetUp } from '@doctolib/dmp' 4 import { createNhrService } from '@doctolib/tpf-national-health-records' 5 import { useDocumentCategorizationFacetsIndex } from 'engines/document_categorization/queries/document_categorization/facets' 6 import { DmpNhrAdapter } from '../business/adapters/DmpNhrAdapter' 7 import type { UseNhrOperations } from './useNa …(truncated, 1152 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records -name "package.json" -exec head -20 {} \;
Tool results:
→ result (ok): { "name": "@doctolib/national-health-records", "version": "1.0.0", "publishConfig": { "registry": "https://doctolib-580698825394.d.codeartifact.eu-west-1.amazonaws.com/npm/npm-internal/" }, "repository": { "type": "git", "url": "git+https://github.com/doctolib/doctolib.git" }, "keywords": [ "upfront", "modular frontend", "in-monolith-package" ], "engines": { "node": ">= 24.8.0", "npm": ">= 11.6.0" }, "author": "@doctolib/fire", { "name": "r …(truncated, 1871 more chars)
Now let me check for any references to NhrEntryPointProps or how the module is used:
Tools used:
Bash:grep -r "NhrEntryPoint\|PatientCard" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records --include="*.ts" --include="*.tsx" 2>/dev/null
Tool results:
→ result (ok): (Bash completed with no output)
Let me search for NhrEntryPoint in the broader codebase:
Tools used:
Bash:grep -r "NhrEntryPoint" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" 2>/dev/null | head -30
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx:import { type NhrEntryPointProps } from '@doctolib/tpf-national-health-records-ui' /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx:const NhrEntryPointModule = lazy( /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_an …(truncated, 780 more chars)
Perfect! Let me read that PatientCard.tsx file:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx
Tool results:
→ result (ok): 1 import PatientFileIcon from 'images/icons/patient-file-icon.svg?as-react-component' 2 import PatientAppointmentIcon from 'images/icons/patient-appointment-icon.svg?as-react-component' 3 import { type ComponentType, lazy, useContext, useMemo, Suspense } from 'react' 4 import classNames from 'classnames' 5 import AccountContext from 'monolith_DEPRECATED/contexts/doctor/AccountContext' 6 import INSiAutomaticCallContext from '@doctolib/financial_os_api/public/contexts/INSiAutomaticCallContext' 7 i …(truncated, 7699 more chars)
Excellent! Now let me search for the tpf-national-health-records-ui package to find the NhrEntryPointProps:
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib -path "*/tpf-national-health-records-ui*" -type d 2>/dev/null | head -5
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/.yalc/@doctolib/tpf-national-health-records-ui /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/dist /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/node_modules /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src
Tools used:
Bash:grep -r "export.*NhrEntryPointProps\|interface NhrEntryPointProps\|type NhrEntryPointProps" /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui --include …(truncated, 37 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/dist/index.d.ts:export { NhrEntryPoint, type NhrEntryPointProps } from './components/NhrEntryPoint/NhrEntryPoint.js'; /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/dist/components/NhrEntryPoint/NhrEntryPoint.d.ts:export type NhrEntryPointProps = { /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/dist/components/ …(truncated, 626 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src/components/NhrEntryPoint/NhrEntryPoint.tsx
Tool results:
→ result (ok): 1 import { useState } from 'react'
2
3 import type { ActionConfig, ColumnConfig, FilterConfig, NhrPatientInfo, SearchDocumentsFn } from '../../types'
4 import { NhrDocumentListModal } from '../NhrDocumentListModal/NhrDocumentListModal'
5 import { NhrEntryPointButton } from '../NhrEntryPointButton/NhrEntryPointButton'
6
7 export type NhrEntryPointProps = {
8 patient: {
9 show_ins_features?: boolean
10 }
11 patientInfo: NhrPatientInfo
12 title: string
13 columns: ColumnConfig[]
14
…(truncated, 1502 more chars)
Now let me check the types file to understand SearchDocumentsFn:
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src -name "types*" -o -name "index.ts" | head -5
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src/types.ts /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src/index.ts /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src/test-helpers/index.ts /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src/test-helpers/fixtures/index.ts /Users/USER/workspace/doctolib/doctol …(truncated, 112 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-national-health-records-ui/src/types.ts
Tool results:
→ result (ok): 1 import type { DesignSystemIconComponent } from '@doctolib/design-system-icons'
2 import type { NhrDocument, NhrResultStatus } from '@doctolib/tpf-national-health-records'
3 import type { ReactNode } from 'react'
4
5 export type NhrPatientInfo = {
6 fullName: string
7 gender: 'male' | 'female' | 'other'
8 birthDate: string
9 age: number
10 }
11
12 export type ColumnConfig = {
13 key: string
14 header: string
15 sortable: boolean
16 /** Only required when sortable: true. Return
…(truncated, 3893 more chars)
Perfect! Now let me check the useGetDocumentsContent hook:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useGetDocumentsContent.ts
Tool results:
→ result (ok): 1 import { useState, useCallback } from 'react'
2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient'
3 import type { NhrDocumentContentResult } from '@doctolib/tpf-national-health-records'
4 import type { GetDocumentsContent } from '../variants/types'
5 import { useNationalHealthRecords } from './useNationalHealthRecords'
6
7 export const useGetDocumentsContent = ({
8 patient,
9 }: {
10 patient: Patient
11 }): { getDocumentsContent: GetDocumentsContent; documentsCon
…(truncated, 1404 more chars)
Excellent! Now let me check the mapFiltersToSearchDocumentsParams mapper:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/mappers/mapFiltersToSearchDocumentsParams.ts
Tool results:
→ result (ok): 1 / eslint-disable no-bitwise /
2 import type { NhrDocumentSearchParams } from '@doctolib/tpf-national-health-records'
3 import { DOCUMENT_STATUS, DOCUMENT_VISIBILITY } from '@doctolib/dmp'
4 import type { ServerFilters } from '../../types'
5
6 // Maps UI-level ServerFilters to the NhrDocumentSearchParams format expected by the NHR API.
7 // Each ServerFilters field needs an explicit mapping — field names do not match NhrDocumentSearchParams.
8 export function mapFiltersToSearchDocumentsParam
…(truncated, 3139 more chars)
Perfect! Now I have comprehensive information. Let me create a summary report:
Summary: National Health Records (NHR) Package Exploration
I've thoroughly explored the @doctolib/national-health-records package and its integration into the Doctolib monolith. Here's what I found:
1. Full Content of useSearchDocuments.ts
Located at: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
This hook is the core search function that:
- Takes a patient and mapFiltersToSearchDocumentsParams mapper as input
- Returns an async function that executes document searches with applied filters
- Handles both mocked documents (via feature flag nhr_document_list_search_mocked) and real DMP API calls
- Uses React Query's fetchQuery with retry logic (max 3 retries, skipping on DMPAccessDeniedByExcededThreshold errors)
- Returns SearchDocumentsResult with data, total, status, and optional message/code
2. Architecture: How searchDocuments Flows to NhrEntryPointModule
Data Flow Chain:
PatientCard.tsx
└─> useNhrDocumentListVariant(patient)
└─> useDmpDocumentListVariant(patient)
└─> useSearchDocuments({ patient, mapFiltersToSearchDocumentsParams })
└─> Returns NhrDocumentListVariant { columns, filters, searchDocuments }
└─> Passed to <NhrEntryPointModule searchDocuments={nhrVariant.searchDocuments} />
In PatientCard.tsx (lines 60-61, 126-129):
- Calls useNhrDocumentListVariant(patient) to get the variant
- Extracts searchDocuments, columns, and filters from the variant
- Passes these directly as props to <NhrEntryPointModule />
3. Key Type Definitions
NhrDocumentListVariant (variants/types.ts):
type NhrDocumentListVariant = {
columns: ColumnConfig[]
filters: FilterConfig[]
searchDocuments: (appliedFilters?: Record<string, unknown>) => Promise<SearchDocumentsResult>
}
NhrEntryPointProps (from @doctolib/tpf-national-health-records-ui):
type NhrEntryPointProps = {
patient: { show_ins_features?: boolean }
patientInfo: NhrPatientInfo
title: string
columns: ColumnConfig[]
filters: FilterConfig[]
searchDocuments: SearchDocumentsFn // (appliedFilters?: Record<string, unknown>) => Promise<SearchDocumentsResult>
actions?: ActionConfig[]
newDocumentsCount?: number
status: 'enabled' | 'disabled' | 'missing_requirements'
}
SearchDocumentsResult (from @doctolib/tpf-national-health-records-ui/types.ts):
type SearchDocumentsResult = {
data: NhrDocument[]
total?: number
status: NhrResultStatus
message?: string
code?: string
}
4. Actions Builder
Location: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/builders/actionsBuilder.ts
Exports a fluent builder pattern for constructing action configurations:
export type NhrActionsBuilder = {
createViewDocumentAction: (onDocumentSelected: (document: NhrDocument) => Promise<void>) => NhrActionsBuilder
createMoreActionsAction: (options: DropdownActionOption[]) => NhrActionsBuilder
build: () => ActionConfig[]
}
export const actionsBuilder: NhrActionsBuilder = createBuilder([])
Usage in PatientCard (lines 63-75):
const nhrActions = useMemo(
() =>
actionsBuilder
.createViewDocumentAction(async (doc) => {
console.log('View document', doc.id)
await getDocumentsContent([doc.id])
})
.createMoreActionsAction([])
.build(),
[getDocumentsContent]
)
5. Public API Exports (index.ts)
export { useNationalHealthRecords, type UseNhrOperations }
export { useDmpNhr }
export { useNhrDocumentListVariant }
export type { DocumentSearchOptions, NhrDocumentListVariant }
export { actionsBuilder, type NhrActionsBuilder }
export { useGetDocumentsContent }
6. Related Hooks & Utilities
useGetDocumentsContent - Fetches document content by IDs:
- Takes patient as input
- Returns { getDocumentsContent, documentsContent, error }
- Handles errors gracefully and maintains content state
useNationalHealthRecords - Variant-aware wrapper:
- Returns UseNhrOperations which includes searchDocuments, getDocumentsContent, updateDocumentMetadata
- Uses product line variation to support EHR France Default (DMP) vs other regions (null)
useDmpNhr - DMP-specific implementation:
- Creates DMP API and NHR service via createNhrService('fr', adapter)
- Integrates with document categorization facets
mapFiltersToSearchDocumentsParams - Converts UI filters to API params:
- Maps typeCodes → categories
- Maps date filters (procedureDate vs shareDate)
- Combines status/visibility filters using bitmasks for DMP API compatibility
7. Toast Utilities Available
The monolith has @doctolib/toaster package available:
export { Toaster } from '#components/Toaster'
export { addToast } from '#business/toast'
AddToast API:
function addToast(props: ToastProps)
type ToastProps = {
action?: Action
dataWalkme?: string
duration?: ToastDuration // number | 'infinite'
message?: ReactNode
onClose?: () => void
secondaryAction?: Action
title?: string
uiStyle?: ToastUIStyle
}
8. File Structure Summary
national-health-records/src/
├── index.ts # Public API exports
├── hooks/
│ ├── useSearchDocuments.ts # Core search hook ⭐
│ ├── useNationalHealthRecords.ts # Variant wrapper
│ ├── useDmpNhr.ts # DMP integration
│ └── useGetDocumentsContent.ts # Content fetching
├── business/
│ ├── builders/
│ │ └── actionsBuilder.ts # Action builder
│ ├── adapters/
│ │ └── DmpNhrAdapter.ts # DMP API adapter
│ └── mappers/
│ └── toNhrPatientInformation.ts
├── variants/
│ ├── types.ts # Type definitions
│ ├── useNhrDocumentListVariant.ts # Variant selector
│ └── dmp/
│ ├── useDmpDocumentListVariant.ts
│ ├── factories/
│ ├── mappers/
│ └── mapFiltersToSearchDocumentsParams.ts
└── mocks/ # Mock generators for testing
All the pieces are in place for integrating error handling (toasts), user feedback, and extended functionality in the PatientCard component!