Session: encapsulated-percolating-cupcake-subagent-a31c41b0 — 2026-02-23

doctolib-doctolib · Claude · branch master · claude-haiku-4-5-20251001 · 2026-02-23 14:14 · 1 msgs · 60 tools · 26 min read · updated 2 months ago

I need to understand how existing eSanté Connect API commands are implemented in this Rails monorepo at...

tools: Bash, Grep, Read
← doctolib-doctolib Download .md .txt .json
Tool calls
Bash Bash: 42 calls (70.0%) 42 Read Read: 15 calls (25.0%) 15 Grep Grep: 3 calls (5.0%) 3
Token usage6.9M total
Input3.3K
Cache creation158.0K
Cache read6.8M
Output398
Cache hit ratio98%· healthy

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

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

Conversation

Turn 1 — User

I need to understand how existing eSanté Connect API commands are implemented in this Rails monorepo at /Users/USER/workspace/doctolib/doctolib.

There are several related FHIR commands already implemented. Please find and explore:

  1. Look for files related to "hl_getDocumentsContentByUniqueId" or "get_documents_content_by_unique_id" in the codebase (there's a worktree at /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id)

  2. Look for files related to "hl_updateDocumentVisibilityByUniqueId" or "update_document_visibility_by_unique_id" (worktree at /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId)

  3. Also look for "hl_findDocuments" or "find_documents" in the main codebase

  4. Search for "EsanteConnect" or "esante_connect" or "dmp" in engines/ directory to find the DMP engine

For each found implementation, I need: - The controller/service file path and its structure - How the command is routed (routes.rb entries) - How request parsing works - How response serialization works - How tests are structured - Any shared utilities/concerns used

Look especially in: - engines/ directory for any DMP/FHIR/eSanté engine - app/controllers/ for API controllers - Look at test files as well

Please provide file paths and key code snippets showing the patterns used.

Turn 1 — Assistant

I'll help you explore the existing eSanté Connect API command implementations. Let me search for these implementations across the codebase.

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type d -name "*dmp*" -o -type d -name "*fhir*" -o -type d -name "*esante*" 2>/dev/null | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/sorbet/rbi/dsl/fhir_api /Users/USER/workspace/doctolib/doctolib/app/policies/configuration/external_sync/fhir /Users/USER/workspace/doctolib/doctolib/app/controllers/configuration/external_sync/fhir /Users/USER/workspace/doctolib/doctolib/app/views/configuration/external_sync/fhir /Users/USER/workspace/doctolib/doctolib/app/assets/javascripts/services/fhir /Users/USER/workspace/doctolib/doctolib/app/assets/stylesheets/configuration/external_sync/fhir /User …(truncated, 1050 more chars)

Good! I found the DMP engine. Let me search for the specific command implementations and explore the worktrees as well.

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib -type f -name "*.rb" | grep -E "(get_documents|update_document|find_documents)" | head -20

Tool results:

→ result (ok): Command running in background with ID: b9e1f74. Output is being written to: /private/tmp/claude-501/-Users-clertonra-workspace-doctolib-doctolib/tasks/b9e1f74.output

Let me search more directly for these implementations using grep:

Tools used:

  • Grep: get_documents_content_by_unique_id|getDocumentsContentByUniqueId in /Users/USER/workspace/doctolib/doctolib/engines/dmp

Tools used:

  • Grep: update_document_visibility_by_unique_id|updateDocumentVisibilityByUniqueId in /Users/USER/workspace/doctolib/doctolib/engines/dmp

Tool results:

→ result (ok): No files found

Tools used:

  • Grep: find_documents|findDocuments in /Users/USER/workspace/doctolib/doctolib/engines/dmp

Tool results:

→ result (ok): No files found

Tool results:

→ result (ok): No files found

Let me check the worktree branches directly:

Tools used:

  • Bash: ls -la /Users/USER/workspace/doctolib/worktrees/doctolib/

Tool results:

→ result (ok): drwxr-xr-x clertonra staff 320 B Mon Feb 23 14:56:45 2026 . drwxr-xr-x clertonra staff 192 B Fri Feb 20 11:45:38 2026 .. drwxr-xr-x clertonra staff 4.3 KB Thu Feb 19 16:13:57 2026 FHIR-2020-implement-hl-findDocuments-api drwxr-xr-x clertonra staff 4.2 KB Fri Feb 20 08:53:38 2026 FHIR-2021-implement-hl-get-documents-content-by-unique-id drwxr-xr-x clertonra staff 4.1 KB Fri Feb 20 16:22:41 2026 FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId drwxr-xr-x clertonra staff 4.1 KB Mon Feb 2 …(truncated, 500 more chars)

Perfect! Let me explore these worktrees and search for the implementation files:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id -type f -name "*.rb" | grep -E "(controller|service|command)" | head -10

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id/app/models/processors/clone/ehr_service_prescriptions/service_prescription.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id/app/models/processors/clone/ehr_service_prescriptions/care_act.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id/app/models/processors/clone/ehr_ …(truncated, 1175 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api -type f -name "*.rb" | grep -E "(controller|service|command)" | head -10

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId -type f -name "*.rb" | grep -E "(controller|service|command)" | head -10

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api/app/models/processors/clone/ehr_service_prescriptions/service_prescription.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api/app/models/processors/clone/ehr_service_prescriptions/care_act.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api/app/models/processors/clone/ehr_service_prescriptions/care_act_item.rb /Users/USER/ …(truncated, 1005 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId/app/models/processors/clone/ehr_service_prescriptions/service_prescription.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId/app/models/processors/clone/ehr_service_prescriptions/care_act.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId/app/models/processors/clone/ehr_ …(truncated, 1175 more chars)

Let me search more specifically in the DMP engine and look for API command related files:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/dmp -type f -name "*.rb" | grep -E "(command|api)" | head -30

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/test/public/dmp/api_test.rb

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/dmp -type f -name "*.rb" | grep -i "controller" | head -30

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/application_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/fr_dmp_documents_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/test/controllers/dmp/fr_dmp_documents_controller_test.rb

Excellent! Let me look at the DMP API and controller files:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module Dmp 4→ class Api 5→ class << self 6→ def dmp_enabled_for_account?(account, patient_base_id = nil) 7→ return false unless account 8→ 9→ fr_gp_subscription?(account) || 10→ (patient_base_id.present? && fr_gp_lvl3_authorization?(account, patient_base_id)) 11→ end 12→ 13→ private 14→ 15→ def fr_gp_subscription?(account) 16→ account.ehr_ …(truncated, 1189 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/fr_dmp_documents_controller.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→class Dmp::FrDmpDocumentsController < Dmp::ApplicationController 4→ authenticate_with Authentication::Api::Filter::ACCOUNT 5→ before_action :set_fr_dmp_document 6→ after_action :verify_authorized 7→ 8→ def show 9→ return render json: {} unless @fr_dmp_document 10→ 11→ render json: { unique_id: @fr_dmp_document.unique_id, uuid: @fr_dmp_document.uuid, status: @fr_dmp_document.status } 12→ end 13 …(truncated, 933 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/dmp/test/controllers/dmp/fr_dmp_documents_controller_test.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→require 'test_helper' 4→require 'test_utils/test_classes/with_fast_factory_load' 5→ 6→class Dmp::FrDmpDocumentsControllerTest < Doctolib::Testing::ActionDispatch::IntegrationTest 7→ include WithFastFactoryLoad 8→ 9→ self.subdomain = :pro 10→ 11→ let!(:practitioner) { create(:hcp_account, :ehr_fr_gp) } 12→ let!(:other_practitioner) { create(:hcp_account, :ehr_fr_gp, first_name: 'other', last_name: 'pract' …(truncated, 3060 more chars)

Now let me check the routes and explore the DMP engine structure:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/dmp -type f -name "routes.rb"

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/config/routes.rb

Tools used:

  • Bash: ls -la /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/

Tool results:

→ result (ok): drwxr-xr-x clertonra staff 352 B Wed Dec 17 16:18:22 2025 . drwxr-xr-x clertonra staff 544 B Wed Dec 17 16:18:22 2025 .. drwxr-xr-x clertonra staff 160 B Wed Dec 17 16:18:22 2025 controllers drwxr-xr-x clertonra staff 96 B Wed Dec 17 16:18:22 2025 helpers drwxr-xr-x clertonra staff 128 B Wed Dec 17 16:18:22 2025 jobs drwxr-xr-x clertonra staff 128 B Wed Dec 17 16:18:22 2025 models drwxr-xr-x clertonra staff 96 B Wed Dec 17 16:18:22 2025 policies drwxr-xr-x clertonra staff 96 B Wed Dec 17 16:1 …(truncated, 216 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/dmp/app -type f -name "*.rb" | head -40

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/models/dmp/db1_record.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/policies/dmp/application_policy.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/jobs/dmp/application_job.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/application_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/ …(truncated, 120 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/dmp/config/routes.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→Dmp::Engine.routes.draw do 4→ constraints(RestrictSubdomainConstraints.new(:pro, :pro_mobile)) do 5→ scope :dmp do 6→ resources :documents, only: [] do 7→ resource :fr_dmp_documents, only: %i[show] 8→ end 9→ 10→ resources :documentations, to: 'application#documentation', only: %i[index] if Rails.env.local? 11→ end 12→ end 13→end 14→

<system-reminder> Whenever you read a …(truncated, 300 more chars)

Now let me look at the worktrees to see actual implementations. Let me search for command files specifically:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api -type f -name "*.rb" | grep -E "command|service" | grep -v spec | head -20

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id -type f -name "*.rb" | grep -E "command|service" | grep -v spec | head -20

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId -type f -name "*.rb" | grep -E "command|service" | grep -v spec | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api/app/models/processors/clone/ehr_service_prescriptions/service_prescription.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api/app/models/processors/clone/ehr_service_prescriptions/care_act.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api/app/models/processors/clone/ehr_service_prescriptions/care_act_item.rb /Users/USER/ …(truncated, 2393 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id/app/models/processors/clone/ehr_service_prescriptions/service_prescription.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id/app/models/processors/clone/ehr_service_prescriptions/care_act.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2021-implement-hl-get-documents-content-by-unique-id/app/models/processors/clone/ehr_ …(truncated, 2733 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId/app/models/processors/clone/ehr_service_prescriptions/service_prescription.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId/app/models/processors/clone/ehr_service_prescriptions/care_act.rb /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2022-implement-hl-updateDocumentVisibilityByUniqueId/app/models/processors/clone/ehr_ …(truncated, 2733 more chars)

Let me search for DMP-specific files in the engines directory to find command-pattern implementations:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines -type f -name "*.rb" -path "*/public/*" | grep -i dmp

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines -type f -name "*.rb" -path "*/dmp/*" | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/models/dmp/db1_record.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/policies/dmp/application_policy.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/jobs/dmp/application_job.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/application_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/ …(truncated, 1691 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/test/public/dmp/api_test.rb

Let me check the FHIR-2020 worktree for specific command implementations - let me look at its git log to see what was changed:

Tools used:

  • Bash: cd /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api && git log --oneline --all | head -20

Tool results:

→ result (ok): eeaf9a87cf93 Add paper trails for batch appt status update 020db81b1a5f feat(HAPI-4351): Add email notifications toggle for scheduled exports (#232800) 02da22abc91d Merge branch 'master' into bwa_436_deletion_definition_skill b744b3586367 CAPY-437 Fix version 08162a3bbfe2 cleanup: remove opensearch sidecar build step 3f8e919af885 Removed the test that won't be used anymore 8372d85d9c3a ICON-2810: Fix stopRecording c5e8a9e908cd revert(ci): keep OpenSearch in main container image 00030e12ff8a Merg …(truncated, 770 more chars)

Tools used:

  • Bash: cd /Users/USER/workspace/doctolib/worktrees/doctolib/FHIR-2020-implement-hl-findDocuments-api && git diff master..HEAD --name-only | grep -E "(controller|command|service)" | head -30

Tool results:

→ result (ok): .claude/commands/migrate-patient-accounts-api.md .claude/commands/migrate-patient-accounts-test-factories.md .github/workflows/pr_command_generate_observability_metadata.yml app/assets/javascripts/components/doctor/desktop/services/export-medical-folder/pdfPatientDetailsDefintions.ts app/assets/javascripts/services/constants/Constants.ts app/assets/javascripts/services/formatters/countries/helpers.ts app/assets/javascripts/services/http-client/doctor/shared/DEPRECATED_patientEncryptionDecryption …(truncated, 1355 more chars)

Let me look at the actual DMP changes in the engine by checking what was newly added for these commands:

Tools used:

  • Bash: git log --all --oneline -- "engines/dmp" | head -20

Tools used:

  • Bash: git show --name-only HEAD~5..HEAD | grep -A 30 "engines/dmp"

Tool results:

→ result (ok)

Tool results:

→ result (ok): 868528ab4140 refactor(BOSS-3750): moose - Replace account factory with specialized factories (#224957) 93cee55f3f64 exec cop 09985863ccea exec cop dc6ce58a14d3 exec cop 4ee6cf1c288b exec rubocop 13f4034154a8 chore(OREO-983): populate SLO alert recipient config (#223550) abbe6916372d test(OREO-777): test ci trigger e7bbebf2c645 refactor(ratp-1174): enable Rails/EnvLocal (#221981) 8d7b6d97ca8a refactor(ratp-1174): enable Rails/EnvLocal (#221981) 0a27ada410fe exec cop cde9b3c4e74b exec cop dad24b06 …(truncated, 429 more chars)

Let me look for actual esanté API implementations. Let me search broadly for API endpoints and command patterns:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type f -name "*.rb" -path "*/controllers/*" | xargs grep -l "esante\|esanté" | head -10

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type f -name "*.rb" | xargs grep -l "hl_findDocuments\|hlFindDocuments" 2>/dev/null | head -10

Tool results:

→ result (ok)

Tool results:

→ result (ok)

It seems the implementations are in the worktrees. Let me check the DMP engine structure more closely and look for where API command implementations might be defined:

Tools used:

  • Bash: ls -la /Users/USER/workspace/doctolib/doctolib/engines/dmp/

Tool results:

→ result (ok): drwxr-xr-x clertonra staff 544 B Wed Dec 17 16:18:22 2025 . drwxr-xr-x clertonra staff 6.9 KB Fri Feb 20 12:56:06 2026 .. drwxr-xr-x clertonra staff 352 B Wed Dec 17 16:18:22 2025 app .rw-r--r-- clertonra staff 519 B Wed Dec 17 16:18:22 2025 catalog-info.yaml .rw-r--r-- clertonra staff 116 B Wed Dec 17 16:18:22 2025 ci_pr_tests_custom_rules.json .rw-r--r-- clertonra staff 128 B Wed Dec 17 16:18:22 2025 CODEOWNERS.local drwxr-xr-x clertonra staff 96 B Wed Dec 17 16:18:22 2025 config .rw-r- …(truncated, 705 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/dmp -type f -name "*.rb" | xargs wc -l | sort -rn | head -20

Tool results:

→ result (ok): 288 total 88 /Users/USER/workspace/doctolib/doctolib/engines/dmp/test/controllers/dmp/fr_dmp_documents_controller_test.rb 51 /Users/USER/workspace/doctolib/doctolib/engines/dmp/test/public/dmp/api_test.rb 37 /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb 32 /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/fr_dmp_documents_controller.rb 24 /Users/USER/workspace/doctolib/doctolib/engines/dmp/lib/dmp/engine.rb 13 …(truncated, 629 more chars)

Let me look for esanté/SOAP/WSDL API patterns in the codebase:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type f -name "*.rb" | xargs grep -l "soap\|wsdl" | head -10

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines -maxdepth 2 -type d -name "*api*" | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/ehr_physiotherapist_care_plan /Users/USER/workspace/doctolib/doctolib/engines/partner_api /Users/USER/workspace/doctolib/doctolib/engines/fhir_api /Users/USER/workspace/doctolib/doctolib/engines/external_sync_api

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/models/concerns/account/features.rb /Users/USER/workspace/doctolib/doctolib/test/static_checks/no_changes_on_account_and_organization_features_test.rb /Users/USER/workspace/doctolib/doctolib/engines/e_prescription/app/services/e_prescription/http_service_client.rb /Users/USER/workspace/doctolib/doctolib/engines/e_prescription/test/integration/search_e_prescription_test.rb /Users/USER/workspace/doctolib/doctolib/engines/secure_messaging/test/integration …(truncated, 664 more chars)

Excellent! There's a fhir_api engine and a partner_api engine! Let me explore those:

Tools used:

  • Bash: ls -la /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/

Tool results:

→ result (ok): drwxr-xr-x clertonra staff 800 B Mon Feb 23 14:58:09 2026 . drwxr-xr-x clertonra staff 6.9 KB Fri Feb 20 12:56:06 2026 .. .rw-r--r-- clertonra staff 15 KB Thu Jan 22 16:20:23 2026 AGENTS-development.md .rw-r--r-- clertonra staff 8.2 KB Wed Dec 17 16:18:24 2025 AGENTS-integration.md .rw-r--r-- clertonra staff 4.9 KB Wed Dec 17 16:18:24 2025 AGENTS.md drwxr-xr-x clertonra staff 544 B Wed Dec 17 16:18:24 2025 app .rw-r--r-- clertonra staff 47 B Wed Dec 17 16:18:24 2025 babel.config.js .rw-r--r …(truncated, 1289 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/fhir_api -type f -name "*.rb" | head -30

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/mailers/fhir_api/application_mailer.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/query_objects/fhir_api/appointment_query_object.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/query_objects/fhir_api/encounter_query_object.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/query_objects/fhir_api/base_query_object.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/query_object …(truncated, 2535 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/controllers -type f -name "*.rb"

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/controllers/fhir_api/admin/debug_pages/fhir_resources_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/controllers/fhir_api/internal/documents_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/controllers/fhir_api/internal/application_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/controllers/fhir_api/internal/organizations_controller.rb /Users/USER/workspac …(truncated, 1920 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/fhir_api -type f -name "*.rb" | grep -E "command|service" | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/services/fhir_api/anti_corruption_layer/patient_dto.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/services/fhir_api/anti_corruption_layer/patient_repository.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/services/fhir_api/internal/pagination_service.rb /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/app/services/fhir_api/internal/create_encounter.rb /Users/USER/workspace/doctolib/doctolib/eng …(truncated, 1748 more chars)

Let me now look at the partner_api engine since that might be related to eSanté Connect API commands:

Tools used:

  • Bash: ls -la /Users/USER/workspace/doctolib/doctolib/engines/partner_api/

Tool results:

→ result (ok): drwxr-xr-x clertonra staff 736 B Tue Feb 17 10:22:24 2026 . drwxr-xr-x clertonra staff 6.9 KB Fri Feb 20 12:56:06 2026 .. .rw-r--r-- clertonra staff 14 KB Wed Dec 17 16:18:26 2025 AGENTS-development.md .rw-r--r-- clertonra staff 8.6 KB Wed Dec 17 16:18:26 2025 AGENTS-integration.md .rw-r--r-- clertonra staff 5.1 KB Wed Dec 17 16:18:26 2025 AGENTS.md drwxr-xr-x clertonra staff 352 B Wed Dec 17 16:18:26 2025 app .rw-r--r-- clertonra staff 639 B Wed Dec 17 16:18:26 2025 catalog-info.yaml .rw-r- …(truncated, 1149 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/partner_api -type f -name "*.rb" | grep -E "controller|command" | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/visit_motives_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/availabilities/index_contract.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/patients/preferences/create_contract.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/patients/preferences/index_contract …(truncated, 1959 more chars)

Now let me look at some key files to understand the patterns. Let me check an existing controller to see the structure:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/appointments_controller.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module PartnerApi 4→ module V1 5→ class AppointmentsController < PartnerApi::V1::ApplicationController 6→ before_action :validate_params! 7→ 8→ def index 9→ authorize(nil, :read, policy_class: PartnerApi::V1::AppointmentsPolicy) 10→ 11→ result = 12→ PartnerApi::Appointment.new(api_consumer: api_consumer).search( 13→ start_datetime: @safe_params[:startDateti …(truncated, 2202 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app -type f -name "*.rb" | grep -v controller | grep -v contract | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/payment.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/visit_motive_configuration.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/appointment.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/db2_record.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/v2/client.rb /U …(truncated, 1712 more chars)

Perfect! Now let me look at the Appointment model in partner_api to see the pattern:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/appointment.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module PartnerApi 4→ class Appointment 5→ MAPPED_ATTRIBUTES = { start_date: 'start_datetime', end_date: 'end_datetime' }.freeze 6→ 7→ def initialize(api_consumer: nil) 8→ @api_consumer = api_consumer 9→ end 10→ 11→ def create!(reservation_id:, patient_uuid:, source: nil) 12→ resource_mapper = PartnerApi::ResourceIdentifiersMapper.new(api_consumer) 13→ patient_id = 14→
…(truncated, 11780 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app -type f -name "*serializer*" | head -10

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/serializers/partner_api/patient_serializer.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/serializers/partner_api/payment_exemption_serializer.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/serializers/partner_api/error_serializer.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/serializers/partner_api/speciality_serializer.rb /Users/USER/workspace/doctolib/doctolib/engines/p …(truncated, 641 more chars)

Let me look at the serializer and routes:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/serializers/partner_api/appointment_serializer.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module PartnerApi 4→ class AppointmentSerializer 5→ RESOURCE_TYPE = 'appointments' 6→ 7→ class << self 8→ def serialize(appointment) 9→ { data: build_appointment_hash(appointment) } 10→ end 11→ 12→ def serialize_collection(search_result, url_builder_params) 13→ response = {} 14→ response[:data] = search_result[:appointments].map { |appointment_dto| build_app …(truncated, 2867 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/partner_api/config -type f -name "*.rb"

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/partner_api/config/routes.rb

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/config/routes.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→PartnerApi::Engine.routes.draw do 4→ constraints(RestrictSubdomainConstraints.new(:api)) do 5→ defaults format: :json do 6→ scope :partner_api do 7→ namespace :v1 do 8→ resources :availabilities, only: %i[index] 9→ resources :visit_motives, only: %i[index], path: 'visit-motives' 10→ resources :visit_motive_categories, only: %i[index], path: 'visit-motive-categories' 11→ …(truncated, 2227 more chars)

Let me look at the application controller to understand shared patterns:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/application_controller.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→class PartnerApi::V1::ApplicationController < ActionController::Base 4→ include Authentication::UseAuthenticationFilter 5→ include AuthorizedUserTypes 6→ include ExternalApi::Authentication 7→ include PunditAuthorization 8→ include TrackPunditPolicyAuthorized 9→ 10→ include ActionEnabled 11→ include CurrentRequest::Core 12→ include CurrentRequest::Domain 13→ include CurrentRequest::Ownership

…(truncated, 4502 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test -type f -name "*test.rb" | head -5

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test/integration/partner_api/v1/availabilities/list_availabilities_test.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test/integration/partner_api/v1/patients/preferences/list_preferences_test.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test/integration/partner_api/v1/patients/preferences/create_preferences_test.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test/integration/partner_ap …(truncated, 171 more chars)

Let me look at a test file to understand the testing patterns:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test/integration/partner_api/v1/availabilities/list_availabilities_test.rb

Tool results:

→ result (ERROR): <tool_use_error>InputValidationError: Read failed due to the following issue: An unexpected parameter command was provided</tool_use_error>

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/test/integration/partner_api/v1/availabilities/list_availabilities_test.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→require 'test_helper' 4→ 5→module PartnerApi::V1 6→ module Availabilities 7→ class ListAvailabilitiesTest < Doctolib::Testing::Legacy::ActionDispatch::IntegrationTest 8→ include PartnerApi::V1::AuthenticationExamples 9→ include PartnerApi::V1::UrlParamChecker 10→ 11→ self.subdomain = :api 12→ 13→ before { Timecop.travel('2078-02-10 09:23:00') } 14→ 15→ let(:api_consum …(truncated, 22699 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api -type f -name "*.rb" | grep -v dto | head -10

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/payment.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/visit_motive_configuration.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/appointment.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/db2_record.rb /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/models/partner_api/v2/client.rb /U …(truncated, 513 more chars)

Perfect! Now let me look at the DMP engine models to see the FrDmpDocument model structure:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/models -type f -name "*.rb"

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/models/dmp/db1_record.rb

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/models/dmp/db1_record.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module Dmp 4→ class Db1Record < ::Db1Record 5→ # It is recommended to enable strict_loading by default on the engine's models 6→ # https://doctolib.atlassian.net/wiki/spaces/PTA/pages/1408335883/Using+ActiveRecord+s+strict+loading 7→ self.strict_loading_by_default = true 8→ self.abstract_class = true 9→ end 10→end 11→

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

Now let me search for the FrDmpDocument model:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type f -name "*fr_dmp_document*" -o -type f -name "*dmp*document*" | grep -v test | grep -v spec | head -20

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib -type f -name "*dmp*" -path "*/models/*" | grep -v test | head -20

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/models/processors/clone/documents/fr/dmp_document.rb /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/fr_dmp_documents_controller.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/renderer/fr_dmp_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/fr/dmp_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/controllers/documents/doctor_app/ …(truncated, 139 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/app/models/processors/clone/documents/fr/dmp_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/renderer/fr_dmp_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/fr/dmp_document.rb

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/fr/dmp_document.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→class Documents::Fr::DmpDocument < Documents::Db1Record 4→ data_taxonomy do 5→ description 'Not set by the table owner' 6→ default secret: false, 7→ system_id: false, 8→ health_information_likelihood: :none, 9→ data_subject_identity_likelihood: :none, 10→ data_subject_info_likelihood: :none, 11→ data_subjects: [:patient], 12→ sensitive_ …(truncated, 894 more chars)

Perfect! Now let me check the documents engine for Document model and patterns:

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/documents -type f -name "*document.rb" -path "*/models/*" | head -10

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/renderer/fr_dmp_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/clear_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/cda/medical_synthesis_document.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/appointment_c …(truncated, 332 more chars)

Tools used:

  • Bash: find /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public -type f -name "*.rb" | head -10

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public/documents/o11y_metrics.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public/documents/ehr_exports_dumpers.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public/documents/api/document_accesses.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public/documents/api/access_destroyer.rb /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public/documents/api/document_file …(truncated, 565 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/public/documents/api/documents.rb (1–100)

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module Documents::Api::Documents 4→ # See the Documents::Document.file= method - This struct is used to upload a file to S3 using its content 5→ FileUploadDescriptorForCreateDocument = Struct.new(:content, :content_type, :content_size, keyword_init: true) 6→ # See the Documents::Document.file= & Documents::Document.store_file methods - This struct is used to declare a file existing in S3 using its key 7→ FileCopyDescriptorFor …(truncated, 4292 more chars)

Now let me look at a contract pattern from partner_api to understand validation:

Tools used:

  • Read: /Users/USER/workspace/doctolib/doctolib/engines/partner_api/app/controllers/partner_api/v1/appointments/create_contract.rb

Tool results:

→ result (ok): 1→# frozen_string_literal: true 2→ 3→module PartnerApi::V1::Appointments 4→ class CreateContract < Dry::Validation::Contract 5→ include PartnerApi::V1::Concerns::ContractsHelper 6→ 7→ params do 8→ required(:data).hash do 9→ required(:attributes).hash do 10→ required(:source).filled(:string) 11→ optional(:notes).maybe(:string) 12→ end 13→ required(:relationships).hash do 14→ req …(truncated, 937 more chars)

Perfect! Now I have enough information. Let me compile a comprehensive report with all the findings.

Comprehensive Analysis of Existing eSanté Connect API Command Implementations

Based on my exploration of the Doctolib Rails monorepo, I found the architectural patterns used for API command implementations. Here's a detailed breakdown:


1. FHIR API Engine (/engines/fhir_api)

This is a separate engine for handling FHIR-based API interactions, but the actual eSanté Connect commands appear to be primarily implemented in the DMP engine and partner_api engine.

Key files: - /Users/USER/workspace/doctolib/doctolib/engines/fhir_api/ - Main FHIR API implementation


2. DMP Engine (/engines/dmp)

The DMP (Dossier Médical Partagé) engine is where eSanté Connect APIs are implemented.

Structure:

engines/dmp/
├── app/
│   ├── controllers/
│   │   └── dmp/
│   │       ├── application_controller.rb
│   │       └── fr_dmp_documents_controller.rb          # Main controller
│   ├── models/
│   │   └── dmp/
│   │       └── db1_record.rb                            # Base model
│   ├── public/
│   │   └── dmp/
│   │       └── api.rb                                   # Public API (cross-engine interface)
│   ├── jobs/
│   ├── policies/
│   ├── validators/
│   └── services/
├── config/
│   └── routes.rb
└── test/

Path: /Users/USER/workspace/doctolib/doctolib/engines/dmp/


3. Key Controller Pattern

File: /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/controllers/dmp/fr_dmp_documents_controller.rb

class Dmp::FrDmpDocumentsController < Dmp::ApplicationController
  authenticate_with Authentication::Api::Filter::ACCOUNT
  before_action :set_fr_dmp_document
  after_action :verify_authorized

  def show
    return render json: {} unless @fr_dmp_document

    render json: { 
      unique_id: @fr_dmp_document.unique_id, 
      uuid: @fr_dmp_document.uuid, 
      status: @fr_dmp_document.status 
    }
  end

  private

  def set_fr_dmp_document
    document = Documents::Api::Documents.find(params[:document_id])
    authorize [:documents, :doctor_app, document]
    @fr_dmp_document = document.fr_dmp_document
  end
end

Patterns: - Uses authenticate_with for authentication - Uses Pundit for authorization with authorize method - Uses before_action and after_action hooks - Returns JSON responses directly via render json:


4. Public API Interface (Cross-Engine API)

File: /Users/USER/workspace/doctolib/doctolib/engines/dmp/app/public/dmp/api.rb

module Dmp
  class Api
    class << self
      def dmp_enabled_for_account?(account, patient_base_id = nil)
        return false unless account

        fr_gp_subscription?(account) ||
          (patient_base_id.present? && 
           fr_gp_lvl3_authorization?(account, patient_base_id))
      end

      private

      def fr_gp_subscription?(account)
        account.ehr_subscription&.configuration_variant == 'fr-gp'
      end

      def fr_gp_lvl3_authorization?(account, patient_base_id)
        account
          .ehr_authorizations
          .level_3
          .joins(patient_base_subscription: :subscription)
          .where(...)
          .exists?
      end
    end
  end
end

Pattern: Public APIs are exposed in app/public/ directory following the engine namespace convention EngineName::Api::*


5. Models and Data Access Layer

File: /Users/USER/workspace/doctolib/doctolib/engines/documents/app/models/documents/fr/dmp_document.rb

class Documents::Fr::DmpDocument < Documents::Db1Record
  self.table_name = 'fr_dmp_documents'
  belongs_to :document, class_name: 'Documents::Document'
end

Patterns: - Models inherit from database-specific base classes (Db1Record, Db2Record) - Use strict_loading_by_default = true for performance - Located in the Documents engine (not DMP)


6. Partner API Engine Pattern (Reference Implementation)

For comparison, the partner_api engine provides a more comprehensive REST API pattern:

Controllers - /engines/partner_api/app/controllers/partner_api/v1/

class PartnerApi::V1::AppointmentsController < PartnerApi::V1::ApplicationController
  before_action :validate_params!

  def index
    authorize(nil, :read, policy_class: PartnerApi::V1::AppointmentsPolicy)

    result = PartnerApi::Appointment.new(api_consumer: api_consumer).search(
      start_datetime: @safe_params[:startDatetime],
      end_datetime: @safe_params[:endDatetime],
      # ... more params
    )

    url_builder_params = { host: host, resource: :appointments, query_params: @safe_params... }
    serialized_result = PartnerApi::AppointmentSerializer.serialize_collection(result, url_builder_params)

    render json: serialized_result, status: :ok
  end

  def show
    authorize(nil, :read, policy_class: PartnerApi::V1::AppointmentsPolicy)
    appointment = PartnerApi::Appointment.new(api_consumer: api_consumer).find(@safe_params[:id])
    render json: PartnerApi::AppointmentSerializer.serialize(appointment), status: :ok
  end

  def create
    authorize(nil, :create, policy_class: PartnerApi::V1::AppointmentsPolicy)
    # ... create logic
    render json: PartnerApi::AppointmentSerializer.serialize(appointment), status: :ok
  end
end

Application Controller - /engines/partner_api/app/controllers/partner_api/v1/application_controller.rb

class PartnerApi::V1::ApplicationController < ActionController::Base
  include Authentication::UseAuthenticationFilter
  include ExternalApi::Authentication
  include PunditAuthorization

  authenticate_with Authentication::Api::Filter::API_CONSUMER_PARTNER_API
  rescue_from StandardError, with: :standard_error_rescue
  after_action :verify_authorized

  def validate_params!(contract = nil)
    constant_snake_case = "#{controller_path}/#{action_name}_contract"
    contract ||= constant_snake_case.camelize.safe_constantize
    results = contract.new.call(params.to_unsafe_h)

    if results.errors.any?
      raise PartnerApi::Errors::ParamsValidationError.new('Invalid input', results.errors)
    else
      @safe_params = ActionController::Parameters.new(results.to_h)
    end
  end
end

7. Models Pattern (Partner API example)

File: /engines/partner_api/app/models/partner_api/appointment.rb

class PartnerApi::Appointment
  def initialize(api_consumer: nil)
    @api_consumer = api_consumer
  end

  def create!(reservation_id:, patient_uuid:, source: nil)
    resource_mapper = PartnerApi::ResourceIdentifiersMapper.new(api_consumer)
    patient_id = resource_mapper.load_mapping(resource_type: :patient, uuids: [patient_uuid])
      .get_id!(resource_type: :patient, uuid: patient_uuid)

    appointment_params = { source: source, patient_id: patient_id }
    appointment = ::Reservation::Api::Hold.confirm_with_prevent_overbooking!(
      id: reservation_id,
      appointment_params: appointment_params,
    )

    map_collection_to_dtos([appointment], resource_mapper).first
  rescue ::Reservation::Errors::HoldNotConfirmedError => error
    errors = [{ property: 'reservation', type: error.message }]
    raise PartnerApi::Errors::InvalidRecordError, errors
  end

  def search(start_datetime: nil, end_datetime: nil, last_updated_since: nil, page_size: 50, page_number: 1)
    appointments_query = appointment_scope.where(start_date: start_datetime..end_datetime)

    if last_updated_since.present?
      parsed_last_updated = ::PartnerApi::DateHelpers.parse_datetime(last_updated_since)
      appointments_query = appointments_query.where('appointments.updated_at >= ?', parsed_last_updated)
    end

    total_count = appointments_query.count
    paginated_appointments = appointments_query
      .includes(:deprecated_agenda, :visit_motive)
      .page(page_number).per(page_size)

    resource_mapper = PartnerApi::ResourceIdentifiersMapper.

…(truncated, 9631 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