Project: doctolib-doctolib · Branch: master · Mode: ` · **Model:**claude-haiku-4-5-20251001`
Stats: 1 user messages, 39 tool calls, tools used: Bash, Read.
Conversation
Turn 1 — User
Explore the following two TypeScript packages thoroughly. For each, document: 1) All exported types and interfaces with their definitions, 2) All exported services/classes with their method signatures, 3) Existing component/hook structure, 4) Package.json exports configuration, 5) Any existing variation management patterns.
Packages to explore:
- /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/
- /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/
Also look at:
- /Users/USER/workspace/doctolib/packages/@doctolib/ - list all packages, and specifically look for national-health-records or nhr related packages. If not found, look at the structure of other @doctolib packages to understand how they export sub-paths.
Be thorough and include actual code for all TypeScript interfaces, types, and key function signatures. This is critical for planning the tech scoping.
Turn 1 — Assistant
I'll explore these TypeScript packages thoroughly to document their structure, exports, and patterns. Let me start by getting an overview of all the files and then diving into the details.
Tools used:
Bash:find /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records -type f -name "*.ts" -o -name "*.tsx" -o -name "package.json" | head -50
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/tests/business/nhr-service-factory.test.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/tests/business/systems/dmp/services/dmp-nhr-service.test.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/tests/setup.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/package.json /Users/USER/workspace/doctolib/treatm …(truncated, 997 more chars)
Let me explore both packages and the @doctolib packages:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/package.json
Tool results:
→ result (ok): 1→{ 2→ "name": "@doctolib/tpf-national-health-records", 3→ "description": "Business logic for national health records functionality in Treatment Plan & Fulfillment", 4→ "sideEffects": false, 5→ "version": "2.0.0", 6→ "repository": { 7→ "type": "git", 8→ "url": "git+https://github.com/doctolib/treatment-plan.git" 9→ }, 10→ "keywords": [ 11→ "upfront", 12→ "smaller-scope" 13→ ], 14→ "author": "@doctolib/fire", 15→ …(truncated, 2372 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/index.ts
Tool results:
→ result (ok): 1→export { createNhrService } from '#business/nhr-service-factory' 2→export type { NhrAdapter, NhrService } from '#business/types/service' 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>
Tools used:
Bash:find /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui -type f -name "*.ts" -o -name "*.tsx" -o -name "package.json" | head -50
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/tests/setup.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/.storybook/main.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/.storybook/preview.tsx /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/.storybook/vitest.config.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-hea …(truncated, 1026 more chars)
Now let me read the UI package.json and explore the source files:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.json
Tool results:
→ result (ok): 1→{ 2→ "name": "@doctolib/tpf-national-health-records-ui", 3→ "version": "2.0.0", 4→ "repository": { 5→ "type": "git", 6→ "url": "git+https://github.com/doctolib/treatment-plan.git" 7→ }, 8→ "keywords": [ 9→ "upfront", 10→ "modular frontend", 11→ "smaller-scope" 12→ ], 13→ "author": "@doctolib/fire", 14→ "license": "Doctolib", 15→ "doctolib": { 16→ "upfront-type": "smaller-scope" 17→ }, 18→ " …(truncated, 3711 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts
Tool results:
→ result (ok): 1→export { NationalHealthRecordsUi } from './components/NationalHealthRecordsUi' 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:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NationalHealthRecordsUi.tsx
Tool results:
→ result (ok): 1→export const NationalHealthRecordsUi = () => <h1>National Health Records UI Placeholder</h1> 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:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/service.ts
Tool results:
→ result (ok): 1→import type { DocumentSearchProps, DocumentSearchResult } from '#business/types/document' 2→ 3→export type CountryCode = 'fr' | 'mock' 4→ 5→export type NhrService = { 6→ searchDocuments(props: DocumentSearchProps): DocumentSearchResult 7→} 8→ 9→export type NhrAdapter = { 10→ searchDocuments(props: DocumentSearchProps): DocumentSearchResult 11→} 12→
<system-reminder> Whenever you read a file, you should consider whether it would be consider …(truncated, 245 more chars)
Let me continue exploring the business types and services:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/document.ts
Tool results:
→ result (ok): 1→import type { Author } from '#business/systems/dmp/types/types' 2→ 3→export type DocumentSearchProps = { 4→ patient: PatientInformation 5→ params: DocumentSearchParams 6→} 7→ 8→export type DocumentSearchResult = { 9→ documents: NhrDocument[] 10→} 11→ 12→export type NhrDocument = { 13→ id: string 14→ title: string 15→ description?: string 16→ identifiers: Record<string, string> 17→ creationDate: string 18→ subm …(truncated, 1393 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/index.ts
Tool results:
→ result (ok): 1→export type { DocumentSearchProps, DocumentSearchResult, NhrDocument } from './document' 2→export type { NhrService } from './service' 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>
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/nhr-service-factory.ts
Tool results:
→ result (ok): 1→import { DmpNhrService } from '#business/systems/dmp/services/dmp-nhr-service'
2→import type { CountryCode, NhrAdapter } from '#business/types/service'
3→
4→export const createNhrService = (countryCode: CountryCode, nhrAdapter: NhrAdapter) => {
5→ switch (countryCode) {
6→ case 'fr':
7→ return new DmpNhrService(nhrAdapter)
8→ default:
9→ throw new Error(Unsupported country code: ${countryCode})
10→ }
11→}
12→
<system-remi …(truncated, 325 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/systems/dmp/services/dmp-nhr-service.ts
Tool results:
→ result (ok): 1→import type { NhrAdapter } from '#business/types/service' 2→import type { 3→ DocumentSearchProps, 4→ DocumentSearchResult, 5→ NhrService, 6→} from 'treatment-plan/packages/tpf-national-health-records/src/business/types' 7→ 8→export class DmpNhrService implements NhrService { 9→ readonly country = 'fr' 10→ 11→ constructor(readonly nhrAdapter: NhrAdapter) {} 12→ 13→ searchDocuments(props: DocumentSearchProps): DocumentSearchResult {
…(truncated, 422 more chars)
Now let me check the DMP types and explore the @doctolib packages:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/systems/dmp/types/types.ts
Tool results:
→ result (ok): 1→/ 2→ * iCanopee JSON Documentation v2.1.0 3→ */ 4→ 5→/ 6→ * Telecom Structure (Section 14.49). 7→ * Represents a telecommunications address (phone, fax, email, etc.). 8→ * Source fields: i_type, i_usage, s_value. 9→ / 10→export type Telecom = { 11→ / 12→ * Telecommunications address type (code from the "Telecommunications Address Type" table). 13→ * Source: i_type. 14→ / 15→ type?: number 16→ /** 17→ * U …(truncated, 14573 more chars)
Tools used:
Bash:ls -la /Users/USER/workspace/doctolib/packages/@doctolib/ | grep -i nhr
Tool results:
→ result (ok): lsd: /Users/USER/workspace/doctolib/packages/@doctolib/: No such file or directory (os error 2).
Let me check the correct @doctolib path:
Tools used:
Bash:find /Users/USER/workspace/doctolib -maxdepth 2 -type d -name "@doctolib" 2>/dev/null
Tool results:
→ result (ok)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib -maxdepth 3 -type d -name "@doctolib" 2>/dev/null | head -5
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/node_modules/@doctolib /Users/USER/workspace/doctolib/doctolib/packages/@doctolib
Tools used:
Bash:ls -la /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ | head -30
Tool results:
→ result (ok): drwxr-xr-x clertonra staff 8.7 KB Fri Feb 27 15:26:53 2026 . drwxr-xr-x clertonra staff 288 B Wed Dec 17 16:23:06 2025 .. .rw-r--r-- clertonra staff 10 KB Tue Feb 3 17:22:37 2026 .DS_Store drwxr-xr-x clertonra staff 320 B Wed Dec 17 16:18:29 2025 accessibility_sdk drwxr-xr-x clertonra staff 320 B Mon Feb 23 14:58:09 2026 actions_history drwxr-xr-x clertonra staff 320 B Mon Feb 23 14:58:09 2026 activity_page drwxr-xr-x clertonra staff 320 B Mon Feb 23 14:58:09 2026 admin_check_in_sdk drwxr …(truncated, 1862 more chars)
Tools used:
Bash:ls /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ | grep -i nhr
Tool results:
→ result (ok)
Let me look at the overall structure of @doctolib packages to understand their patterns:
Tools used:
Bash:ls /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ | wc -l
Tool results:
→ result (ok): 276
Tools used:
Bash:ls /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ | head -50
Tool results:
→ result (ok): accessibility_sdk actions_history activity_page admin_check_in_sdk advanced_patients_filters advanced_patients_filters_sdk agenda_legal_compliance agenda_legal_compliance_sdk agenda_legal_responsibility api-consumer-settings appointment-document-reviews appointment_modification_reason appointment_move_page appointment_online_payments_sdk appointment_payment_check_in authentication authentication_sdk billing_custom_codes calendar-configuration calendar-preferences calendar-views calendar_display
…(truncated, 522 more chars)
Let me examine an example @doctolib package to understand the structure and export patterns:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/authentication/package.json
Tool results:
→ result (ok): 1→{ 2→ "name": "@doctolib/authentication", 3→ "version": "1.0.0", 4→ "license": "Doctolib", 5→ "scripts": { 6→ "test": "npm run test:unit", 7→ "test:unit": "jest --passWithNoTests", 8→ "type-check": "tsc --noEmit", 9→ "lint": "eslint ." 10→ }, 11→ "dependencies": { 12→ "react": "^18.3.1", 13→ "react-dom": "^18.3.1" 14→ }, 15→ "violations": [ 16→ "monolith_DEPRECATED/services/single-page-application/s …(truncated, 626 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/authentication/src/index.ts
Tool results:
→ result (ERROR): File does not exist. Note: your current working directory is /Users/USER/workspace/doctolib/doctolib.
Tools used:
Bash:ls -la /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/authentication/src/ 2>/dev/null | head -20
Tool results:
→ result (ok): drwxr-xr-x clertonra staff 288 B Mon Feb 16 10:39:37 2026 . drwxr-xr-x clertonra staff 352 B Wed Dec 17 16:18:29 2025 .. .rw-r--r-- clertonra staff 47 B Thu Jan 15 14:05:06 2026 constants.ts .rw-r--r-- clertonra staff 756 B Thu Jan 15 14:05:06 2026 getIdpRedirectionUrl.ts .rw-r--r-- clertonra staff 1019 B Thu Jan 15 14:05:06 2026 idpEnvironment.ts .rw-r--r-- clertonra staff 602 B Mon Feb 16 10:39:37 2026 idpUrl.ts .rw-r--r-- clertonra staff 845 B Thu Jan 15 14:05:06 2026 SetIdpUsername.te …(truncated, 150 more chars)
Let me check another @doctolib package with a more complex structure:
Tools used:
Bash:cat /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/calendar-preferences/package.json 2>/dev/null | head -60
Tool results:
→ result (ok): { "name": "@doctolib/calendar-preferences", "version": "1.0.0", "repository": { "type": "git", "url": "git+https://github.com/doctolib/doctolib.git" }, "keywords": [ "upfront", "modular frontend", "in-monolith-package" ], "author": "@doctolib/pasta", "license": "Doctolib", "doctolib": { "upfront-type": "in-monolith-package" }, "type": "module", "sideEffects": [ ".css", ".scss" ], "scripts": { "lint": "eslint .", "test": "npm r …(truncated, 1332 more chars)
Perfect! Now let me examine the tests and get a complete picture of the TPF packages:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/tests/business/nhr-service-factory.test.ts
Tool results:
→ result (ok): 1→import { createNhrService } from '#business/nhr-service-factory' 2→import { DmpNhrService } from '#business/systems/dmp/services/dmp-nhr-service' 3→import type { NhrAdapter } from '#business/types/service' 4→import { describe, expect, it } from 'vitest' 5→ 6→describe('createNhrService', () => { 7→ it('should return a DmpNhrService for country code "fr"', () => { 8→ const service = createNhrService('fr', {} as NhrAdapter) 9→ 10→ expect(service) …(truncated, 691 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/tests/business/systems/dmp/services/dmp-nhr-service.test.ts
Tool results:
→ result (ok): 1→import { DmpNhrService } from '#business/systems/dmp/services/dmp-nhr-service' 2→import type { DocumentSearchProps, DocumentSearchResult } from '#business/types/document' 3→import type { NhrAdapter } from '#business/types/service' 4→import { describe, expect, it, vi } from 'vitest' 5→ 6→const createMockAdapter = (): NhrAdapter => ({ 7→ searchDocuments: vi.fn(), 8→}) 9→ 10→const searchProps: DocumentSearchProps = { 11→ patient: { nationalHealthI …(truncated, 1739 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/systems/dmp/types/index.ts
Tool results:
→ result (ok): 1→export type { DmpDocument, DmpListParams } from './types' 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>
Let me get the remaining test file and check the UI package test:
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/__tests__/index.test.ts
Tool results:
→ result (ok): 1→import { describe, expect, it } from 'vitest' 2→ 3→describe('tpf-national-health-records-ui', () => { 4→ it('should have basic test coverage', () => { 5→ expect(true).toBe(true) 6→ }) 7→}) 8→
<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 …(truncated, 72 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui -type f \( -name "*.ts" -o -name "*.tsx" \) ! -path "*/node_modules/*" | sort
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/.storybook/main.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/.storybook/preview.tsx /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/.storybook/vitest.config.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/tests/index.test.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf …(truncated, 927 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/i18n.ts
Tool results:
→ result (ok): 1→import { i18n } from '@doctolib/tpf-commons/i18n' 2→ 3→import { loadNamespace } from './locales/loadNamespace' 4→ 5→i18n.registerNamespace('tpf_national_health_records_ui', loadNamespace) 6→ 7→export const t = i18n.t 8→export const changeLanguage = i18n.changeLanguage 9→// To be used only for storybook 10→export const getInstance = i18n.getInstance 11→
<system-reminder> Whenever you read a file, you should consider whether it would be considered …(truncated, 243 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NationalHealthRecordsUi.stories.tsx
Tool results:
→ result (ok): 1→import type { Meta, StoryObj } from '@storybook/react' 2→ 3→import { NationalHealthRecordsUi } from './NationalHealthRecordsUi' 4→ 5→const meta = { 6→ component: NationalHealthRecordsUi, 7→ title: 'NationalHealthRecordsUi', 8→ tags: ['autodocs'], 9→} satisfies Meta<typeof NationalHealthRecordsUi> 10→ 11→export default meta 12→type Story = StoryObj<typeof meta> 13→ 14→export const Default: Story = { 15→ render: () => <NationalH …(truncated, 374 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/locales/loadNamespace.ts
Tool results:
→ result (ok): 1→import type { Language } from '@doctolib/upfront-core/i18n'
2→
3→import NationalHealthRecordsUiEn from './en/tpf_national_health_records_ui.json'
4→import NationalHealthRecordsUiFr from './fr/tpf_national_health_records_ui.json'
5→
6→export const loadNamespace = (lang: Language, namespace: string) => {
7→ console.log(Loading namespace: ${namespace} for language: ${lang})
8→
9→ if (namespace !== 'tpf_national_health_records_ui') {
10→ throw new
…(truncated, 720 more chars)
Now let me check the directory structure of both packages and the @doctolib import patterns used:
Tools used:
Bash:tree -L 3 /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src 2>/dev/null || find /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-healt …(truncated, 43 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src ├── business │ ├── nhr-service-factory.ts │ ├── systems │ │ └── dmp │ └── types │ ├── document.ts │ ├── index.ts │ └── service.ts └── index.ts
5 directories, 5 files
Tools used:
Bash:tree -L 3 /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src 2>/dev/null || find /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-he …(truncated, 49 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src ├── tests │ └── index.test.ts ├── components │ ├── NationalHealthRecordsUi.stories.tsx │ └── NationalHealthRecordsUi.tsx ├── i18n.test.ts ├── i18n.ts ├── index.ts └── locales ├── en │ └── tpf_national_health_records_ui.json ├── fr │ └── tpf_national_health_records_ui.json └── loadNamespace.ts
6 directories, 9 files
Excellent! Now let me look at one more example @doctolib package to see how subpaths are exported:
Tools used:
Bash:cat /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/design-system/package.json 2>/dev/null | grep -A 50 '"exports"' | head -60
Tool results:
→ result (ok)
Tools used:
Bash:ls /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/ | grep design
Tool results:
→ result (ok): design-system-illustrations design-system-reporting
Tools used:
Bash:cat /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/design-system-illustrations/package.json 2>/dev/null | grep -A 30 '"exports"' | head -40
Tool results:
→ result (ok)
Tools used:
Bash:cat /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/preferences_sdk/package.json 2>/dev/null | jq '.exports' 2>/dev/null || cat /Users/USER/workspace/doctolib/doctolib/packages/@d …(truncated, 71 more chars)
Tool results:
→ result (ok): null
Let me check one more for subpath exports:
Tools used:
Bash:grep -A 20 '"exports"' /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/calendar-preferences/package.json | head -25
Tool results:
→ result (ok): "exports": { ".": "./src/components/default/index.tsx", "./list-view": "./src/components/list-view/index.tsx", "./print-planning": "./src/components/list-view/PrintPlanning.tsx", "./list-view/columns": "./src/data/list-view/ListViewColumnsContext.tsx" }, "dependencies": { "@atlaskit/pragmatic-drag-and-drop": "1.7.7", "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "2.1.5", "@atlaskit/pragmatic-drag-and-drop-flourish": "2.0.11", "@atlaskit/pragmatic-drag-and-d …(truncated, 370 more chars)
Perfect! Now I have all the information I need. Let me compile a comprehensive report:
Comprehensive TypeScript Package Exploration Report
I've thoroughly explored both TPF packages and reviewed the @doctolib package ecosystem structure. Here's the complete documentation:
1. PACKAGE 1: /treatment-plan/packages/tpf-national-health-records/
A. Exported Types and Interfaces
Main Entry Point Export (src/index.ts):
export { createNhrService } from '#business/nhr-service-factory'
export type { NhrAdapter, NhrService } from '#business/types/service'
Service Types (src/business/types/service.ts):
export type CountryCode = 'fr' | 'mock'
export type NhrService = {
searchDocuments(props: DocumentSearchProps): DocumentSearchResult
}
export type NhrAdapter = {
searchDocuments(props: DocumentSearchProps): DocumentSearchResult
}
Document Types (src/business/types/document.ts):
export type DocumentSearchProps = {
patient: PatientInformation
params: DocumentSearchParams
}
export type DocumentSearchResult = {
documents: NhrDocument[]
}
export type NhrDocument = {
id: string
title: string
description?: string
identifiers: Record<string, string>
creationDate: string
submissionDate?: string
serviceInformation: ServiceInformation
status: string
visibility: string
format: string
authors: Author[]
classification: DocumentClassification
}
type ServiceInformation = {
startDate?: string
endDate?: string
}
type DocumentClassification = {
medicalCodes: Code
}
type Code = {
system: string
code: string
}
type DocumentSearchParams = {
patientInformation: PatientInformation
formats: string[]
categories: string[]
status: string
serviceStartDate: DateRange
serviceStopDate: DateRange
creationDate: DateRange
submissionDate: DateRange
visibility: string
}
type PatientInformation = {
nationalHealthIdentifier: string
}
type DateRange = {
upperLimit: string
lowerLimit: string
}
DMP Types (src/business/systems/dmp/types/types.ts - comprehensive iCanopee JSON v2.1.0 types):
export type Author = {
name: string
givenName: string
profession?: string
professionOid?: string
professionDescription?: string
speciality?: string
specialityDescription?: string
internalId: string
functionCode: string
functionCodeOid: string
activityTypeCode: string
authenticationMode?: number
internalIdType?: number
addresses?: Address[]
telecoms?: Telecom[]
institution?: string
redactionDate?: Date
}
export type Address = {
type?: number
houseNumber?: string
houseNumberNumeric?: string
streetName?: string
streetNameType?: number
city?: string
postalCode?: string
state?: string
country?: string
additionalLocator?: string
precinct?: string
postBox?: string
unitId?: string
}
export type Telecom = {
type?: number
usage?: number
value?: string
}
export type DmpListParams = {
patientIns: string
categories?: string[]
formats?: string[]
practices?: string[]
creationDateFrom?: Date
creationDateTo?: Date
serviceStartDateFrom?: Date
serviceStartDateTo?: Date
serviceStopDateFrom?: Date
serviceStopDateTo?: Date
submissionDateFrom?: Date
submissionDateTo?: Date
status?: number
visibility?: number
disableMetadataSearch?: boolean
referenceIds?: string[]
eventCodes?: string[]
getTransactionFrames?: boolean
}
export type DmpDocument = {
uniqueId: string
title: string
description?: string
classCode: string
typeCode: string
creationDate: string
serviceStartDate?: string
serviceStopDate?: string
healthcareFacilityTypeCode?: string
practiceSettingCode?: string
submissionDate?: string
submissionSetId?: string
uuid: string
previousUuid?: string
nextUuid?: string
status: number
visibility: number
documentFormat: number
authors?: Author[]
eventCodes?: string[]
handle: number
referenceIds?: string[]
}
Re-exported (src/business/types/index.ts):
export type { DocumentSearchProps, DocumentSearchResult, NhrDocument } from './document'
export type { NhrService } from './service'
DMP Re-exports (src/business/systems/dmp/types/index.ts):
export type { DmpDocument, DmpListParams } from './types'
B. Services/Classes with Method Signatures
Service Factory (src/business/nhr-service-factory.ts):
export const createNhrService = (countryCode: CountryCode, nhrAdapter: NhrAdapter) => {
switch (countryCode) {
case 'fr':
return new DmpNhrService(nhrAdapter)
default:
throw new Error(`Unsupported country code: ${countryCode}`)
}
}
DMP Service (src/business/systems/dmp/services/dmp-nhr-service.ts):
export class DmpNhrService implements NhrService {
readonly country = 'fr'
constructor(readonly nhrAdapter: NhrAdapter) {}
searchDocuments(props: DocumentSearchProps): DocumentSearchResult {
return this.nhrAdapter.searchDocuments(props)
}
}
C. Component/Hook Structure
- No React components in this package (business logic only)
- No hooks or UI components
- Pure TypeScript package focused on service abstraction
D. Package.json Exports Configuration
{
"name": "@doctolib/tpf-national-health-records",
"version": "2.0.0",
"type": "module",
"sideEffects": false,
"exports": {
".": "./src/index.ts"
},
"imports": {
"#business/*": "./src/business/*.ts"
},
"files": [
"dist",
"src",
"!src/**/*.test.ts",
"!src/**/*.test.tsx",
"!src/**/*.test-d.ts",
"!src/**/*-test.tsx",
"!**/__tests__/**",
"CHANGELOG.md",
"README.md",
"package.json"
]
}
E. Variation Management Patterns
Country-based Adapter Pattern:
- Uses CountryCode type union ('fr' | 'mock') to support multiple countries
- Factory pattern (createNhrService) returns different implementations based on country
- Currently supports: France (DMP) via DmpNhrService
- Adapter pattern allows pluggable implementations of NhrAdapter
- Service delegates to injected adapter (Dependency Injection)
Testing Pattern (from tests/):
const createMockAdapter = (): NhrAdapter => ({
searchDocuments: vi.fn(),
})
const searchProps: DocumentSearchProps = { /* test data */ }
Source of Variation: Country-specific service implementations with adapter injection for domain logic (DMP vs other systems)
2. PACKAGE 2: /treatment-plan/packages/tpf-national-health-records-ui/
A. Exported Types and Interfaces
Main Entry Point (src/index.ts):
export { NationalHealthRecordsUi } from './components/NationalHealthRecordsUi'
Currently: NO EXPORTED TYPES - only component export. Package is a UI placeholder.
B. Components/Classes with Signatures
UI Component (src/components/NationalHealthRecordsUi.tsx):
export const NationalHealthRecordsUi = () => <h1>National Health Records UI Placeholder</h1>
i18n Module (src/i18n.ts):
import { i18n } from '@doctolib/tpf-commons/i18n'
import { loadNamespace } from './locales/loadNamespace'
i18n.registerNamespace('tpf_national_health_records_ui', loadNamespace)
export const t = i18n.t
export const changeLanguage = i18n.changeLanguage
export const getInstance = i18n.getInstance // For storybook
i18n Loader (src/locales/loadNamespace.ts):
import type { Language } from '@doctolib/upfront-core/i18n'
import NationalHealthRecordsUiEn from './en/tpf_national_health_records_ui.json'
import NationalHealthRecordsUiFr from './fr/tpf_national_health_records_ui.json'
export const loadNamespace = (lang: Language, namespace: string) => {
console.log(`Loading namespace: ${namespace} for language: ${lang}`)
if (namespace !== 'tpf_national_health_records_ui') {
…(truncated, 5958 more chars)