Skip to content

[Eng 387] feat : add encounter minimal spec to medication dispense#3663

Merged
vigneshhari merged 1 commit into
developfrom
ENG-387-add-encounter-minimal-spec-to-medication-dispense
May 28, 2026
Merged

[Eng 387] feat : add encounter minimal spec to medication dispense#3663
vigneshhari merged 1 commit into
developfrom
ENG-387-add-encounter-minimal-spec-to-medication-dispense

Conversation

@nandkishorr
Copy link
Copy Markdown
Contributor

@nandkishorr nandkishorr commented May 28, 2026

Proposed Changes

  • Added encounter minimum spec in medication dispense retrieve.

Associated Issue

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

Release Notes

  • New Features
    • Medication dispensing records now include associated encounter information when retrieved, providing additional context for dispensing transactions.

Review Change Stack

@nandkishorr nandkishorr self-assigned this May 28, 2026
@nandkishorr nandkishorr requested a review from a team as a code owner May 28, 2026 09:36
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2dd459dd-fab7-4bf5-a15e-d843a80a0f41

📥 Commits

Reviewing files that changed from the base of the PR and between 8d1da0a and 89c9140.

📒 Files selected for processing (1)
  • care/emr/resources/medication/dispense/spec.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • care/emr/resources/medication/dispense/spec.py

📝 Walkthrough

Walkthrough

The medication dispense retrieval spec now includes a serialized encounter object in its response. The change adds an import for EncounterSpecBase and extends the MedicationDispenseRetrieveSpec class with an encounter field and custom serialization logic that populates the encounter data using the encounter serializer.

Changes

Medication Dispense Encounter Serialization

Layer / File(s) Summary
Encounter field and serialization
care/emr/resources/medication/dispense/spec.py
MedicationDispenseRetrieveSpec imports EncounterSpecBase and adds encounter: dict field; perform_extra_serialization method now calls parent serializer and populates mapping["encounter"] by serializing the associated encounter object.

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding encounter specification to medication dispense retrieve functionality.
Description check ✅ Passed The description covers proposed changes and associated issue, though the checklist items lack evidence of completion despite stating tests and linting are required.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ENG-387-add-encounter-minimal-spec-to-medication-dispense

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR makes two independent changes: it adds an encounter field (serialized via EncounterSpecBase) to MedicationDispenseRetrieveSpec, and it refactors the DiagnosticReportViewSet.get_queryset authorization logic from if/elif/else with a trailing raise ValidationError to per-branch early-exit raise PermissionDenied guards. A 755-line test file for the diagnostic report API is also added.

  • The authorization refactor in diagnostic_report.py corrects the HTTP status code for permission failures from 400 (ValidationError) to 403 (PermissionDenied) and is covered by the new tests.
  • The MedicationDispenseRetrieveSpec spec change follows the existing serialization pattern used for other nested objects but ships with no accompanying tests for the medication dispense retrieve endpoint.

Confidence Score: 4/5

Safe to merge; the diagnostic report authorization refactor is logically correct and well-tested, and the spec change is a small additive field following established patterns.

Both changes are low-risk. The authorization fix correctly swaps ValidationError for PermissionDenied and the new test suite validates those 403 paths. The medication dispense spec change is a straightforward field addition consistent with how sibling specs handle nested objects. The only gap is the absence of tests for the spec change itself.

care/emr/resources/medication/dispense/spec.py — the new encounter field in MedicationDispenseRetrieveSpec has no test coverage.

Important Files Changed

Filename Overview
care/emr/resources/medication/dispense/spec.py Adds encounter: dict field and perform_extra_serialization override to MedicationDispenseRetrieveSpec, serializing the encounter using EncounterSpecBase. Pattern is consistent with how other nested objects (item, location) are handled in the parent; no test coverage added for this new field.
care/emr/api/viewsets/diagnostic_report.py Refactors get_queryset authorization: replaces if/elif/else with early-return guards and replaces the former ValidationError (HTTP 400) with PermissionDenied (HTTP 403) for all authorization failures. Logic is correct and the HTTP status codes are now semantically accurate.
care/emr/tests/test_diagnostic_report_api.py New 755-line test file covering create/retrieve/list/update/upsert-observation scenarios for the DiagnosticReport API, including permission variants. Tests are well-structured and cover the expected 403 responses introduced by the authorization refactor. Uses secrets.choice where random.choice is conventional for non-security test data.

Reviews (1): Last reviewed commit: "feat:added encounter base spec" | Re-trigger Greptile

"system": "http://terminology.hl7.org/CodeSystem/v2-0074",
},
"service_request": kwargs.setdefault(
"service_request", self.service_request
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 Unconventional import for test randomization

secrets.choice is the cryptographically-secure variant designed for security-sensitive selections (tokens, passwords, etc.). For generating random test data, random.choice is the conventional choice and avoids any unintended coupling to the secrets module.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 238 to +244
class MedicationDispenseRetrieveSpec(MedicationDispenseReadSpec):
pass
encounter: dict

@classmethod
def perform_extra_serialization(cls, mapping, obj):
super().perform_extra_serialization(mapping, obj)
mapping["encounter"] = EncounterSpecBase.serialize(obj.encounter).to_json()
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 No test coverage for the spec change

The primary purpose of this PR is adding the encounter field to MedicationDispenseRetrieveSpec, but the added test file (test_diagnostic_report_api.py) contains no tests for the medication dispense retrieve endpoint or for the presence/correctness of the encounter key in its response. If a future refactor breaks the serialization (e.g., obj.encounter is null, or EncounterSpecBase.serialize changes shape), there is no test to catch it.

@nandkishorr nandkishorr force-pushed the ENG-387-add-encounter-minimal-spec-to-medication-dispense branch from 8d1da0a to 89c9140 Compare May 28, 2026 09:40
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.

🧹 Nitpick comments (2)
care/emr/api/viewsets/diagnostic_report.py (1)

148-158: 💤 Low value

Redundant get_patient_obj() call and filter.

Line 117 already calls self.get_patient_obj() and filters the queryset by that patient. Here at line 149, you're calling it again (extra DB query), and the filter at line 158 is also redundant since the queryset is already patient-scoped.

You could just return queryset directly after the authorization check, or cache the patient from line 117.

♻️ Suggested simplification
         # Authorize with Patient
-        patient = self.get_patient_obj()
         if not AuthorizationController.call(
             "can_view_clinical_data",
             self.request.user,
-            patient,
+            self.get_patient_obj(),
         ):
             raise PermissionDenied(
                 "You do not have permission to view clinical data for this patient"
             )
-        return queryset.filter(patient=patient)
+        return queryset  # Already filtered by patient at line 117
🤖 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/api/viewsets/diagnostic_report.py` around lines 148 - 158, The code
redundantly calls self.get_patient_obj() and re-filters the queryset after it
was already obtained and filtered earlier; update the view to avoid the extra DB
call by either reusing the already-cached patient object from the earlier call
(store it in a local variable like patient_from_scope and use that for the
AuthorizationController.call check) or simply perform the permission check with
AuthorizationController.call("can_view_clinical_data", self.request.user,
patient) and then return queryset directly instead of returning
queryset.filter(patient=patient); adjust the block around get_patient_obj(),
AuthorizationController.call, and the return to remove the duplicate
get_patient_obj() and redundant queryset.filter(patient=patient).
care/emr/tests/test_diagnostic_report_api.py (1)

1-1: 💤 Low value

Using secrets.choice for non-security test data is unconventional.

The secrets module is intended for cryptographically secure random values. For test fixtures where reproducibility can be helpful, random.choice would be the standard choice. Though I'm sure you had your reasons.

♻️ Suggested fix
-from secrets import choice
+from random import choice
🤖 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/tests/test_diagnostic_report_api.py` at line 1, The test imports
secrets.choice which is meant for cryptographic use; replace that import with
random.choice and update any uses of choice in test_diagnostic_report_api.py
(e.g., where choice(...) is called) to use the random module so tests use
non-crypto RNG; optionally seed random.seed(...) near test setup for
reproducible fixtures if needed.
🤖 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.

Nitpick comments:
In `@care/emr/api/viewsets/diagnostic_report.py`:
- Around line 148-158: The code redundantly calls self.get_patient_obj() and
re-filters the queryset after it was already obtained and filtered earlier;
update the view to avoid the extra DB call by either reusing the already-cached
patient object from the earlier call (store it in a local variable like
patient_from_scope and use that for the AuthorizationController.call check) or
simply perform the permission check with
AuthorizationController.call("can_view_clinical_data", self.request.user,
patient) and then return queryset directly instead of returning
queryset.filter(patient=patient); adjust the block around get_patient_obj(),
AuthorizationController.call, and the return to remove the duplicate
get_patient_obj() and redundant queryset.filter(patient=patient).

In `@care/emr/tests/test_diagnostic_report_api.py`:
- Line 1: The test imports secrets.choice which is meant for cryptographic use;
replace that import with random.choice and update any uses of choice in
test_diagnostic_report_api.py (e.g., where choice(...) is called) to use the
random module so tests use non-crypto RNG; optionally seed random.seed(...) near
test setup for reproducible fixtures if needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8890c190-ea2d-4dc5-82bf-16b4fc791d8e

📥 Commits

Reviewing files that changed from the base of the PR and between 64c21c7 and 8d1da0a.

📒 Files selected for processing (3)
  • care/emr/api/viewsets/diagnostic_report.py
  • care/emr/resources/medication/dispense/spec.py
  • care/emr/tests/test_diagnostic_report_api.py

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 66.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.85%. Comparing base (e3b31fb) to head (89c9140).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
care/emr/resources/medication/dispense/spec.py 66.66% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3663      +/-   ##
===========================================
- Coverage    75.85%   75.85%   -0.01%     
===========================================
  Files          479      479              
  Lines        23034    23040       +6     
  Branches      2378     2378              
===========================================
+ Hits         17472    17476       +4     
- Misses        4989     4991       +2     
  Partials       573      573              

☔ 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.

@vigneshhari vigneshhari merged commit c8efcd3 into develop May 28, 2026
11 of 12 checks passed
@vigneshhari vigneshhari deleted the ENG-387-add-encounter-minimal-spec-to-medication-dispense branch May 28, 2026 10:01
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.

2 participants