Skip to content

[ENG-381] feat: add extension support for datapoints#3661

Merged
vigneshhari merged 4 commits into
ohcnetwork:developfrom
Jacobjeevan:ENG-381-extensions
May 26, 2026
Merged

[ENG-381] feat: add extension support for datapoints#3661
vigneshhari merged 4 commits into
ohcnetwork:developfrom
Jacobjeevan:ENG-381-extensions

Conversation

@Jacobjeevan
Copy link
Copy Markdown
Contributor

@Jacobjeevan Jacobjeevan commented May 25, 2026

Proposed Changes

ENG-381

  • add extensions support for datapoints

Merge Checklist

  • Tests added/fixed
  • Update docs in /docs
  • Linting Complete
  • Any other necessary step

Only PR's with test cases included and passing lint and test pipelines will be reviewed

@ohcnetwork/care-backend-maintainers @ohcnetwork/care-backend-admins

Summary by CodeRabbit

  • New Features
    • Added support for accessing patient extensions data through JSON-style paths, enabling more flexible retrieval and display of arbitrary patient extension information in reports.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

📝 Walkthrough

Walkthrough

A new extensions field is added to BasePatientContextBuilder to expose patient extensions data via JSON-path-style access. The field includes preview metadata and a mapping that safely returns the extensions or an empty object when unavailable.

Changes

Patient Extensions Context Field

Layer / File(s) Summary
Extensions field declaration and mapping
care/emr/reports/context_builder/data_points/patient.py
BasePatientContextBuilder gains a new extensions context field with preview metadata, JSON-path documentation, and a lambda that returns p.extensions or {} when falsy.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing the required 'Associated Issue' section (which references ENG-381 in the title) and 'Architecture changes' section. The 'Proposed Changes' section lacks detail about what extensions are or why they're needed. Add the 'Associated Issue' section with a link to ENG-381 explaining how this solves the feature request, and provide more detail about the architectural impact of adding extensions support to datapoints.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding extension support for datapoints, which aligns with the actual code modification adding an extensions field.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 75.85%. Comparing base (77bd3b1) to head (20abd05).
⚠️ Report is 2 commits behind head on develop.

Files with missing lines Patch % Lines
...emr/reports/context_builder/data_points/patient.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3661      +/-   ##
===========================================
+ Coverage    75.83%   75.85%   +0.02%     
===========================================
  Files          479      479              
  Lines        23014    23035      +21     
  Branches      2378     2378              
===========================================
+ Hits         17452    17473      +21     
- Misses        4988     4989       +1     
+ Partials       574      573       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Jacobjeevan Jacobjeevan marked this pull request as ready for review May 26, 2026 13:40
@Jacobjeevan Jacobjeevan requested a review from a team as a code owner May 26, 2026 13:40
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 26, 2026

Greptile Summary

Adds extensions as a new datapoint field on BasePatientContextBuilder, exposing the Patient model's extensions JSONField to the report template context.

  • A single Field is added with a lambda mapping (p.extensions or {}), a representative preview_value, and a usage hint in description. The mapping is correct; the or {} guard is a harmless defensive fallback since the DB column already defaults to {}.
  • The field omits field_type, so the schema emitted by build_schema() will advertise this field as \"string\" even though its runtime value is a dict — minor but worth aligning with the actual return type.

Confidence Score: 4/5

The change is a small, additive field declaration with no side effects on existing fields or queries.

The only concern is that field_type defaults to "string" while the returned value is always a dict; the build_schema() utility exposes this type to consumers, so template authors consulting the schema will see an inaccurate type hint. The actual runtime behaviour of the field is correct.

care/emr/reports/context_builder/data_points/patient.py — the new extensions field should specify field_type="json" to match its actual return type

Important Files Changed

Filename Overview
care/emr/reports/context_builder/data_points/patient.py Adds an extensions Field to BasePatientContextBuilder that exposes the Patient model's JSONField; field_type is left as the default "string" despite the value being a dict, which is surfaced in the schema API

Reviews (1): Last reviewed commit: "chore: switch to just json" | Re-trigger Greptile

Comment on lines +184 to +193
extensions = Field(
display="Patient Extensions",
mapping=lambda p: p.extensions or {},
preview_value={
"patient_demographics": {
"related_person": "Jane Doe",
},
},
description="Patient extensions as JSON (e.g. patient.extensions.patient_demographics)",
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The field_type defaults to "string", but this field actually returns a dict. The build_schema() utility exposes attr.type in the schema output consumed by frontend/template tooling, so leaving it as "string" will mislead consumers about what to expect when rendering patient.extensions.

Suggested change
extensions = Field(
display="Patient Extensions",
mapping=lambda p: p.extensions or {},
preview_value={
"patient_demographics": {
"related_person": "Jane Doe",
},
},
description="Patient extensions as JSON (e.g. patient.extensions.patient_demographics)",
)
extensions = Field(
display="Patient Extensions",
mapping=lambda p: p.extensions or {},
preview_value={
"patient_demographics": {
"related_person": "Jane Doe",
},
},
description="Patient extensions as JSON (e.g. patient.extensions.patient_demographics)",
field_type="json",
)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@care/emr/reports/context_builder/data_points/patient.py`:
- Around line 184-193: The mapping for the Field named "extensions" currently
assumes Patient.extensions is a dict by using mapping=lambda p: p.extensions or
{}, but since writes may bypass validators, change it to defensively return a
dict only when extensions is actually a dict; update the mapping to check type
(e.g. use isinstance(p.extensions, dict) in the lambda) so non-dict values fall
back to {} — locate the Field declaration for "extensions" and modify its
mapping lambda accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d355de59-ed59-488e-9217-85eaa6bd50cd

📥 Commits

Reviewing files that changed from the base of the PR and between 77bd3b1 and 20abd05.

📒 Files selected for processing (1)
  • care/emr/reports/context_builder/data_points/patient.py

Comment on lines +184 to +193
extensions = Field(
display="Patient Extensions",
mapping=lambda p: p.extensions or {},
preview_value={
"patient_demographics": {
"related_person": "Jane Doe",
},
},
description="Patient extensions as JSON (e.g. patient.extensions.patient_demographics)",
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check the Patient model's extensions field type to ensure it's a JSONField

# Search for the Patient model definition and extensions field
ast-grep --pattern $'class Patient($$$):
  $$$
  extensions = $$$
  $$$'

# Also search for any field definition with 'extensions' in Patient-related files
rg -n --type=py -C5 'extensions.*=' care/emr/models/patient.py

Repository: ohcnetwork/care

Length of output: 8504


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the surrounding context of the new `extensions` field in the context builder
sed -n '140,230p' care/emr/reports/context_builder/data_points/patient.py

# Check for how `extensions` is referenced/parsed elsewhere (especially expecting dict/object)
rg -n --type=py "extensions(\.|\[|$)" care/emr | head -n 200

# Check for any model validators/clean methods enforcing `extensions` shape
rg -n --type=py "class Patient|extensions\s*=" care/emr/models/patient.py care/emr/models -S

Repository: ohcnetwork/care

Length of output: 7520


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the extension validator logic that reads `obj.extensions[key]`
sed -n '1,220p' care/emr/extensions/validator.py

# Inspect Patient model for any clean/validation logic specific to extensions
rg -n --type=py "def (clean|full_clean|save)|extensions" care/emr/models/patient.py

# Inspect any extension parsing/writing paths that might enforce dict/object shape
rg -n --type=py "extensions\s*=" care/emr/models/patient.py care/emr/models -S

Repository: ohcnetwork/care

Length of output: 3619


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find where ExtensionValidator is used for patient extensions ingestion/validation
rg -n --type=py "ExtensionValidator|validate_extensions\(" care/emr | head -n 200

# Check the patient extension resource spec/serializers for enforcing dict/object shape
rg -n --type=py "patient.*extensions|extensions.*patient|__.*extension_resource_type__|___extension_resource_type__" care/emr/resources/patient -S

Repository: ohcnetwork/care

Length of output: 2926


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,240p' care/emr/resources/patient/spec.py

sed -n '1,120p' care/emr/resources/patient/otp_based_flow.py

Repository: ohcnetwork/care

Length of output: 11129


Patient.extensions is JSONField with dict-only validation on write paths

Patient.extensions is a Django models.JSONField(default=dict), and the patient write specs (PatientCreateSpec/PatientUpdateSpec/PatientOTPWriteSpec) inherit ExtensionValidator, which rejects non-dict extensions payloads. So mapping=lambda p: p.extensions or {} matches the app’s expected shape for JSON-path usage.

Minor hardening: if data can be written bypassing validators, use mapping=lambda p: p.extensions if isinstance(p.extensions, dict) else {}.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@care/emr/reports/context_builder/data_points/patient.py` around lines 184 -
193, The mapping for the Field named "extensions" currently assumes
Patient.extensions is a dict by using mapping=lambda p: p.extensions or {}, but
since writes may bypass validators, change it to defensively return a dict only
when extensions is actually a dict; update the mapping to check type (e.g. use
isinstance(p.extensions, dict) in the lambda) so non-dict values fall back to {}
— locate the Field declaration for "extensions" and modify its mapping lambda
accordingly.

@vigneshhari vigneshhari merged commit 64c21c7 into ohcnetwork:develop May 26, 2026
7 checks passed
jesbinjoseph added a commit to egovhealthcare/care that referenced this pull request May 28, 2026
[ENG-381] feat: add extension support for datapoints (ohcnetwork#3661)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants