Project: doctolib-doctolib · Branch: .invalid · Mode: ` · **Model:**claude-haiku-4-5-20251001`
Stats: 1 user messages, 26 tool calls, tools used: Bash, Read.
Conversation
Turn 1 — User
I'm planning an observability strategy for National Health Records (NHR) adapter layer in a monorepo. I need to understand:
-
The sendMonitoringEvent function signature and how it's used: - Read /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/utils/callTiConnectApi.ts (already provided as context, but check for patterns) - Search for other examples of sendMonitoringEvent usage patterns across the codebase: grep for "sendMonitoringEvent" in packages/@doctolib/ to find good examples showing the typical event structure (name, details fields)
-
The DMP package structure at /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/ - specifically: - What types are exported (read types/DmpApi.ts or similar) - What actions/methods the DmpApi interface exposes - Read /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.ts if it's an interface file - Check /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/types/ directory
-
How packages are structured in this monorepo - check /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/package.json for existing dependencies
-
Search for any existing NHR monitoring or observability hooks in the codebase.
Report the sendMonitoringEvent typical event shape (what fields does "details" contain in typical usage), and any pattern where a unique trace ID is generated for requests.
Turn 1 — Assistant
I'll help you understand the observability strategy for the NHR adapter layer. Let me search through the codebase systematically.
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib -type f -name "*.ts" -o -name "*.tsx" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ehr-core/orval.config.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/variation_management/index.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/patient_health/index.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/pro-patient-file-v2-sdk/vite.config.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/os_privacy_center/index.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/d …(truncated, 1317 more chars)
Now let me search for sendMonitoringEvent usage patterns across the codebase.
Tools used:
Bash:grep -r "sendMonitoringEvent" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib --include="*.ts" --include="*.tsx" | head -30
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/secure_messaging_inbox/src/components/doctor/desktop/shared/MailModal/MailModalBody/PatientMailModalBody.tsx:import { sendMonitoringEvent } from 'monolith_DEPRECATED/services/monitoring' /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/secure_messaging_inbox/src/components/doctor/desktop/shared/MailModal/MailModalBody/PatientMailModalBody.tsx: sendMonitoringEvent({ /Users/USER/workspace/doctolib/doctolib/packages/@do …(truncated, 5073 more chars)
Let me read a specific example and check the ti_connect file you mentioned:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/utils/callTiConnectApi.ts
Tool results:
→ result (ok): 1 import type { TiConnectorRequest } from '@doctolib/ti_connect/src/types/connector'
2
3 import { invokeElectronEvent } from '@doctolib/desktop/events'
4 import { TiConnectAction } from '@doctolib/ti_connect/src/types/ti-connect-action'
5 import { TiEvent } from '@doctolib/ti_connect/src/types/ti-event'
6 import { v4 as uuidv4 } from 'uuid'
7 import { sendMonitoringEvent } from 'monolith_DEPRECATED/services/monitoring'
8
9 interface TiConnectResponsePayload {
10 success: boolean
11 /**
12
…(truncated, 3554 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/documents-ui/src/helpers/monitoring/documentEncryptionMonitoring.ts
Tool results:
→ result (ok): 1 import { sendMonitoringEvent } from 'monolith_DEPRECATED/services/monitoring'
2 import { isFeatureEnabled } from '@doctolib/variation-management/legacy'
3 import type { ShareWith } from '@doctolib/deepwater_core/public'
4 import type { EncryptableDocumentField, DocumentEncryptionFeature } from '../types'
5
6 interface FormDataInspectionResult {
7 hasTankerEncryptedFile: boolean
8 hasClearTextFile: boolean
9 hasTankerEncryptedMetadata: boolean
10 hasClearTextMetadata: boolean
11 }
12
…(truncated, 3218 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/secure_messaging_inbox/src/components/doctor/desktop/shared/MailModal/MailModalBody/PatientMailModalBody.tsx(1–100)
Tool results:
→ result (ok): 1 import { forwardRef, useContext, useEffect, useImperativeHandle, useState } from 'react' 2 import i18n from 'monolith_DEPRECATED/services/i18n' 3 import { groupBy } from 'lodash-es' 4 import { Checkbox } from '@doctolib/design-system-b2b/Checkbox' 5 import Layout from 'monolith_DEPRECATED/components/base/Layout' 6 import Form from 'monolith_DEPRECATED/components/base/form/Form' 7 import { FormProvider, useForm } from 'react-hook-form' 8 import { InputText } from '@doctolib/design-system-b2b/In …(truncated, 4447 more chars)
Now let me check the DMP package structure:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src
Tool results:
→ result (ERROR): EISDIR: illegal operation on a directory, read '/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src'
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src -type f -name "*.ts" | grep -E "(type|interface|DmpApi)" | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/types/FrDmpTypes.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/types/DmpApi.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/api/DmpApiError.test.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp …(truncated, 108 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/types/DmpApi.ts
Tool results:
→ result (ok): 1 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient'
2 import type { ClinicalDocument } from 'engines/cdar2/types/ClinicalDocument'
3 import type { DmpDocumentToAdd, DmpDocumentToDelete } from '../business/FrDmpConfig'
4 import type { DmpWorkflow, BillingSituation, GetDocumentsContentParams, PracticeLocationOverride } from './FrDmpTypes'
5
6 export type PatientConsent = 'error' | 'authorized' | 'expired' | 'forbidden' | 'noAuthorization'
7
8 export type PatientConsentU
…(truncated, 5371 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.ts
Tools used:
Bash:ls -la /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/types/
Tool results:
→ result (ok): drwxr-xr-x clertonra staff 128 B Tue May 5 12:16:13 2026 . drwxr-xr-x clertonra staff 416 B Tue May 5 12:16:13 2026 .. .rw-r--r-- clertonra staff 5.1 KB Thu Apr 30 09:54:45 2026 DmpApi.ts .rw-r--r-- clertonra staff 22 KB Tue May 5 12:16:13 2026 FrDmpTypes.ts
Tool results:
→ result (ok): 1 / eslint-disable @typescript-eslint/no-non-null-assertion / 2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 3 import type { MedicalFolder } from '@doctolib/ehr-core' 4 import { getLoincCode } from 'monolith_DEPRECATED/models/document/document' 5 import { sendMonitoringEvent } from 'monolith_DEPRECATED/services/monitoring' 6 import { isMinor } from 'monolith_DEPRECATED/models/patient/patient' 7 import { isMedicalSynthesis } from 'monolith_DEPRECATED/components/do …(truncated, 39193 more chars)
Now let me check the national-health-records package:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/package.json
Tool results:
→ result (ok): 1 {
2 "name": "@doctolib/national-health-records",
3 "version": "1.0.0",
4 "publishConfig": {
5 "registry": "https://doctolib-580698825394.d.codeartifact.eu-west-1.amazonaws.com/npm/npm-internal/"
6 },
7 "repository": {
8 "type": "git",
9 "url": "git+https://github.com/doctolib/doctolib.git"
10 },
11 "keywords": [
12 "upfront",
13 "modular frontend",
14 "in-monolith-package"
15 ],
16 "engines": {
17 "node": ">= 24.8.0",
18 "npm": ">= 11.6.0"
19
…(truncated, 1260 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records -type f -name "*.ts" -o -name "*.tsx" | head -20
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, 1843 more chars)
Tools used:
Bash:grep -r "sendMonitoringEvent\|monitoring\|trace" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records --include="*.ts" --include="*.tsx" 2>/dev/null | head -20
Tool results:
→ result (ok): (Bash completed with no output)
Let me search for more sendMonitoringEvent examples to understand the typical event structure better:
Tools used:
Bash:grep -A 10 "sendMonitoringEvent({" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/documents-ui/src/services/fetchDocument.test.ts 2>/dev/null | head -50
Tool results:
→ result (ok): (Bash completed with no output)
Tools used:
Bash:grep -B 2 -A 15 "sendMonitoringEvent({" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/utils/callTiConnectApi.ts 2>/dev/null
Tool results:
→ result (ok): const traceId = uuidv4()
sendMonitoringEvent({ name: 'ti_connect_send_event', details: { event_name: eventName, action, trace: { id: traceId }, }, }).catch(() => { // Ignore errors in monitoring })
return invokeElectronEvent<TiConnectResponse>(eventName, { action, payload, traceId, }) --
try {
sendMonitoringEvent({
name: 'ti_connect_response_received',
details: {
event_name: eventName,
…(truncated, 875 more chars)
Perfect! Now let me check a few more examples to get a comprehensive view:
Tools used:
Bash:grep -B 2 -A 12 "sendMonitoringEvent({" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.ts 2>/dev/null
Tool results:
→ result (ok): const startedAt = performance.now() const fingerprint = await computeSharingFingerprint(fileContentBase64, title) void sendMonitoringEvent({ name: 'dmp_sharing_fingerprint_compute_duration', details: { duration: performance.now() - startedAt, context }, }) return fingerprint }
private async filterUnchangedDocuments(documents: DmpDocumentToAdd[]): Promise<DmpDocumentToAdd[]> { const results = await Promise.all( documents.map(async (document) => {
…(truncated, 136 more chars)
Tools used:
Bash:grep -B 2 -A 12 "sendMonitoringEvent({" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/documents-ui/src/helpers/monitoring/documentEncryptionMonitoring.ts 2>/dev/null
Tool results:
→ result (ok): }
sendMonitoringEvent({ name: eventName, details, }) }
Let me check if there's an existing monitoring service type definition:
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib -path "*/monolith_DEPRECATED/services/monitoring*" -o -path "*monitoring.ts" | grep -E "(service|monitoring)" | head -10
Tools used:
Bash:grep -r "export.*sendMonitoringEvent\|function sendMonitoringEvent" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" | head -5
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-commons/src/types/monolith/monitoring.ts /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-user-preferences/node_modules/@doctolib/tpf-commons/src/types/monolith/monitoring.ts /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-muster-forms/node_modules/@doctolib/tpf-commons/src/types/monolith/monitoring.ts /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-rich-texts-form/node_modu …(truncated, 971 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/services/monitoring/with-fetch.ts:export const sendMonitoringEventWithFetch = ( /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/services/monitoring/index.ts:export const sendMonitoringEvent = ( /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/monolith-mfr-tools/src/shared/datadog/send-monitoring-event.test.ts: function sendMonitoringEvent( /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/monolith-m …(truncated, 284 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/services/monitoring/index.ts
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-commons/src/types/monolith/monitoring.ts
Tool results:
→ result (ok): 1 import { getUserProductLine, isEhrUser } from 'engines/ehr/services/ehr-user-helpers' 2 import { omit } from 'lodash-es' 3 import { envIsDevelopment, envIsStaging, envIsTest } from '@doctolib/variation-management/environment' 4 import { FRONTEND_MONITOR, getNewrelicEventUrl } from 'services/constants/new-relic' 5 import httpClient from 'services/http-client/doctor/desktop/httpClient' 6 import * as Storage from 'services/storage/Storage' 7 import type { Window } from 'static/rum-datadog/rum-dat …(truncated, 2071 more chars)
Tool results:
→ result (ok): 1 export type MonitoringEvent = {
2 name: string
3 details: Record<string, unknown>
4 }
5
6 export type SendMonitoringEvent = (
7 event: MonitoringEvent,
8 options?: { includeUserIdentifiers?: boolean }
9 ) => Promise<unknown>
10
Perfect! Now let me get a summary view of the NHR package structure:
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 export { u …(truncated, 650 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useNationalHealthRecords.ts(1–80)
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, 966 more chars)
Now let me check the adapter and see what needs monitoring:
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src -name "*adapter*" -o -name "*Adapter*"
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts(1–100)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.test.ts
Tool results:
→ result (ok): 1 DmpApi, 2 DmpAuthor, 3 DmpDocument, 4 DmpDocumentContent, 5 SearchProps, 6 SearchResult as DmpSearchResult, 7 } from '@doctolib/dmp' 8 import { DmpApiError, DOCUMENT_STATUS, DOCUMENT_VISIBILITY, getPatientInsForDMP } from '@doctolib/dmp' 9 import { isUnstructured } from '@doctolib/cda/types/UnstructuredBody' 10 import { isStructured } from '@doctolib/cda/types/StructuredBody' 11 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 12 import type { 13 NhrAdapt …(truncated, 3400 more chars)
Let me read more of the adapter to see key methods:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts(100–250)
Tool results:
→ result (ok): 100 }
101
102 return { codes }
103 }
104
105 function toNhrDocument(doc: DmpDocument): NhrDocument {
106 return {
107 id: doc.uniqueId,
108 title: doc.title,
109 description: doc.description,
110 identifiers: { uniqueId: doc.uniqueId, uuid: doc.uuid },
111 creationDate: parseHl7DateToIso(doc.creationDate),
112 submissionDate: parseHl7DateToIso(doc.submissionDate),
113 serviceInformation: {
114 startDate: parseHl7DateToIso(doc.serviceStartDate),
115
…(truncated, 5031 more chars)
Perfect! Now I have enough context. Let me compile my findings into a comprehensive report. Based on my research, I can now provide a detailed summary to the user.
Summary: Observability Strategy for National Health Records (NHR) Adapter Layer
I've completed a thorough analysis of the codebase. Here are my findings:
1. sendMonitoringEvent Function Signature and Usage Patterns
Type Definition:
- Located at: /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-commons/src/types/monolith/monitoring.ts
- Function location: /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/services/monitoring/index.ts
Signature:
type MonitoringEvent = { name: string; details: Record<string, unknown> }
export const sendMonitoringEvent = (
{ name, details = {} }: MonitoringEvent,
{ includeUserIdentifiers = true } = {}
) => Promise<unknown>
Typical Event Structure - details field contains:
From ti_connect example (request/response lifecycle):
- event_name - name of the TI-Connect event
- action - action type
- trace: { id: string } - trace ID for tracking
- success - boolean for success status
- errors - error array
- body_type - typeof the body
- error - error message
From document encryption example:
- feature - feature name (e.g., 'document-encryption')
- caller - caller identifier
- endpoint - API endpoint
- sharedWith - share recipients array
- hasTankerEncryptedFile - boolean
- hasClearTextFile - boolean
- document_single_write_enabled - feature flag
- document_double_write_enabled - feature flag
- httpResponseCode - HTTP status on error
From DMP sharing example:
- duration - performance metric in milliseconds
- context - contextual information ('filter' | 'store')
2. Trace ID Pattern
Key Pattern Identified: Uses UUID v4 for unique request tracking
From /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ti_connect/src/utils/callTiConnectApi.ts:
const traceId = uuidv4()
sendMonitoringEvent({
name: 'ti_connect_send_event',
details: {
event_name: eventName,
action,
trace: { id: traceId }, // Standard trace structure
},
})
The trace ID is: - Generated at request initiation - Passed through to the backend via the request payload - Captured in response monitoring event using the backend's returned trace ID
3. DMP Package Structure
Location: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src
Types Exported (from /types/DmpApi.ts):
- DmpApi interface - main API contract
- DmpDocument - document metadata
- DmpDocumentContent - document with full content
- SearchResult - search operation result
- DmpApiErrorInfo - error details
DmpApi Interface Methods:
interface DmpApi {
share: (props: ShareProps) => Promise<void>
unshare: (props: UnshareProps) => Promise<void>
search: (props: SearchProps) => Promise<SearchResult>
getPatientConsent: () => Promise<PatientConsent>
updatePatientConsent: (consent: PatientConsentUpdate) => Promise<boolean>
getDocumentsContentByUniqueId: (props: GetDocumentsContentProps) => Promise<DmpDocumentContent[]>
updateDocumentStatus: (props: DocumentStatusUpdateProps) => Promise<DocumentStatusUpdateResult>
}
Implementation: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.ts
- Has existing monitoring: dmp_sharing_fingerprint_compute_duration event
- Uses performance.now() for performance tracking
4. NHR Package Structure
Location: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records
Dependencies (from package.json):
- @doctolib/dmp - core DMP functionality
- @doctolib/tpf-national-health-records - NHR types
- @doctolib/tpf-national-health-records-ui - NHR UI components
- @doctolib/documents-ui - document handling
- @doctolib/design-system - UI components
Key Exports (from /src/index.ts):
- useNationalHealthRecords - main hook for NHR operations
- DmpNhrAdapter - adapter implementing NhrAdapter interface
- useDmpNhr - DMP-specific NHR hook
- Hooks: useSearchDocuments, useGetDocumentsContent, useNhrDocumentStatusActions
DmpNhrAdapter Methods (from /src/business/adapters/DmpNhrAdapter.ts):
- searchDocuments(props: NhrDocumentSearchProps) - search health records
- getDocumentsContent(props: NhrGetDocumentsContentProps) - fetch document content
- updateDocumentMetadata(props: NhrDocumentMetadataUpdateProps) - update document status/visibility
5. Existing Observability Hooks in NHR Codebase
Finding: No existing sendMonitoringEvent usage found in the NHR package itself.
However, the adapter layer is a critical point where you'd want to add monitoring for:
- searchDocuments calls
- getDocumentsContent retrievals
- updateDocumentMetadata operations
- Error handling and API failures
Recommended Observability Event Structure for NHR
Based on the patterns I found, here's what I'd recommend for NHR monitoring:
// Search operation
sendMonitoringEvent({
name: 'nhr_search_documents',
details: {
trace: { id: traceId },
patient_ins: patient.nationalHealthIdentifier,
categories_count: params.categories?.length ?? 0,
status: 'success' | 'error',
duration_ms: elapsedTime,
documents_found: resultCount,
error?: errorMessage,
}
})
// Content retrieval
sendMonitoringEvent({
name: 'nhr_get_documents_content',
details: {
trace: { id: traceId },
request_ids: params.ids.length,
has_cda_content: boolean,
duration_ms: elapsedTime,
status: 'success' | 'error',
}
})
// Metadata update
sendMonitoringEvent({
name: 'nhr_update_document_metadata',
details: {
trace: { id: traceId },
payload_count: payloads.length,
property_updated: 'status' | 'visibility',
status: 'success' | 'error',
duration_ms: elapsedTime,
}
})
Key Files for Reference
- sendMonitoringEvent definition:
/Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/services/monitoring/index.ts - Type definitions:
/Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib/tpf-commons/src/types/monolith/monitoring.ts - DMP API interface:
/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/types/DmpApi.ts - DMP implementation:
/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/dmp/src/business/DmpApi.ts - NHR adapter (needs monitoring):
/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts - NHR package.json:
/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/package.json