FHIR Cache: make copy project-scope instead of system-level#1941
FHIR Cache: make copy project-scope instead of system-level#1941
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the FHIR cache creation flow to copy Medplum FHIR data at project/dataset scope (rather than system-wide), and wires tokenStudyCode/studyCode through the dataset service → jobplugins → Prefect flow. It also introduces request- and token-level caching in the FHIR gateway to reduce repeated lookups.
Changes:
- Add
studyCode/tokenStudyCodeplumbing so the FHIR cache flow can resolve a Medplumfhir_project_idper dataset. - Rework
create_cachedb_fhir_pluginto copy only project-scoped FHIR resource tables (plus related history/reference/index tables). - Add in-memory caching in the FHIR gateway for datasetId lookups, project credentials, and OAuth tokens.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| functions/jobplugins/src/types.ts | Extends FHIR cache flow-run DTO to include studyCode. |
| functions/dataset/types.d.ts | Extends Dataset type to include tokenStudyCode. |
| functions/dataset/index.ts | Passes tokenStudyCode into the FHIR cache flow-run request; reads tokenStudyCode from Portal dataset payload. |
| flows/base/create_cachedb_fhir_plugin/flow.py | Switches flow orchestration to resolve fhir_project_id then copy Medplum FHIR resources into cache. |
| flows/base/create_cachedb_fhir_plugin/duckdb_postgres.py | Implements dataset-scoped copy logic and portal lookup for fhir_project_id. |
| flows/base/create_cachedb_fhir_plugin/config.py | Adds studyCode plus database_code alias and use_cache_db default. |
| flows/_shared_flow_utils/api/FhirAPI.py | Minor formatting cleanup (no functional change). |
| fhir_functions/alp-fhir-gateway/src/fhir-svc/services.ts | Adds module-level caches for datasetId and project credentials to reduce redundant lookups. |
| fhir_functions/alp-fhir-gateway/src/api/FhirAPI.ts | Adds module-level access-token cache with expiry parsing to reduce token requests. |
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 6 comments.
You can also share your feedback on Copilot code review. Take the survey.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Afreen <reachafreen@hotmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Afreen <reachafreen@hotmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.
You can also share your feedback on Copilot code review. Take the survey.
| function _parseTokenExpiry(token: string): number { | ||
| try { | ||
| const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()); | ||
| return (payload.exp as number) * 1000; | ||
| } catch { | ||
| // If the token cannot be parsed as a JWT with an exp claim, treat it as expired. | ||
| // The caller should rely on the token endpoint's expires_in value for the true expiry. | ||
| return Date.now(); | ||
| } |
There was a problem hiding this comment.
_parseTokenExpiry() decodes the JWT payload using Buffer.from(..., 'base64'), but access tokens are typically base64url encoded. That decode can fail (or produce wrong data) and you’ll treat tokens as immediately expired, negating the cache. Consider decoding with base64url (or normalizing padding/characters) and/or falling back to the token endpoint’s expires_in to set expiresAt when parsing fails.
Merge Checklist
Please cross check this list if additions / modifications needs to be done on top of your core changes and tick them off. Reviewer can as well glance through and help the developer if something is missed out.
developbranch)