Skip to content

Comments

cache invalidation for Facilityretreive cache on identifier updation#3501

Open
praffq wants to merge 1 commit intodevelopfrom
prafful/bug/cache-invalidation-on-identifier-for-facility
Open

cache invalidation for Facilityretreive cache on identifier updation#3501
praffq wants to merge 1 commit intodevelopfrom
prafful/bug/cache-invalidation-on-identifier-for-facility

Conversation

@praffq
Copy link
Contributor

@praffq praffq commented Jan 30, 2026

Proposed Changes

  • Invalidating facility spec cache on identifier update

Associated Issue

Architecture changes

  • Remove this section if not used

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

  • Bug Fixes

    • Fixed cache invalidation for facility data when patient identifier configurations are updated, preventing stale information from being displayed.
  • Chores

    • Restructured signal handlers to properly expose patient identifier caching functionality in the public API.

✏️ Tip: You can customize this high-level summary in your review settings.

@praffq praffq requested a review from a team as a code owner January 30, 2026 06:21
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Introduces Django signal handler to invalidate cached Facility data when PatientIdentifierConfig is saved. The handler is registered to the post_save signal and deletes cache entries based on Facility external_id or general Facility patterns. The implementation is exposed through the signals package's public API.

Changes

Cohort / File(s) Summary
Package Exports
care/emr/signals/__init__.py, care/emr/signals/patient_identifier/__init__.py
Exposes patient_identifier module contents in public API; minor noqa formatting adjustment to existing import.
Signal Handler Implementation
care/emr/signals/patient_identifier/cache_invalidation.py
New signal handler invalidate_facility_cache_on_identifier_change() that clears Facility cache when PatientIdentifierConfig is saved, with conditional logic for facility-specific or general cache deletion.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title references the main change (cache invalidation for Facility on identifier update) but contains a typo ('Facilityretreive' instead of 'Facility retrieve') and awkward phrasing ('updation' instead of 'update'), which slightly obscures clarity.
Description check ✅ Passed The description covers proposed changes, references the associated issue, and includes the required merge checklist, but notably indicates that tests have not yet been added (unchecked box), which conflicts with the template requirement that 'Only PR's with test cases included and passing lint and test pipelines will be reviewed'.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch prafful/bug/cache-invalidation-on-identifier-for-facility

Tip

🧪 Unit Test Generation v2 is now available!

We have significantly improved our unit test generation capabilities.

To enable: Add this to your .coderabbit.yaml configuration:

reviews:
  finishing_touches:
    unit_tests:
      enabled: true

Try it out by using the @coderabbitai generate unit tests command on your code files or under ✨ Finishing Touches on the walkthrough!

Have feedback? Share your thoughts on our Discord thread!


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

Copy link
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: 2

🤖 Fix all issues with AI agents
In `@care/emr/signals/patient_identifier/cache_invalidation.py`:
- Line 9: The signal handler invalidate_facility_cache_on_identifier_change
declares unused parameters sender and **kwargs which triggers Ruff's ARG
unused-argument warnings; update the function signature to use _sender and
**_kwargs (preserving the Django signal signature) so the parameters are
recognized as intentionally unused and the linter stops flagging them.
- Around line 9-17: The invalidate_facility_cache_on_identifier_change function
currently only deletes the cache by external_id; change it to follow the
standard pattern used in care/emr/resources/base.py by deleting both the id and
external_id keyed caches: call
cache.delete_pattern(model_cache_key(facility_model_string, pk=instance.id)) and
then, since external_id is present, also call
cache.delete_pattern(model_cache_key(facility_model_string,
pk=instance.external_id)) (or use getattr(instance, "external_id", None) if you
prefer the existing guard) so both possible cache keys are invalidated.

from care.facility.models import Facility


def invalidate_facility_cache_on_identifier_change(sender, instance, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd "cache_invalidation.py" --type f

Repository: ohcnetwork/care

Length of output: 161


🏁 Script executed:

cat -n care/emr/signals/patient_identifier/cache_invalidation.py

Repository: ohcnetwork/care

Length of output: 1028


🏁 Script executed:

# Check if Ruff is configured and if there are any lint configurations
fd "ruff.toml|pyproject.toml|setup.cfg" --type f | head -5

Repository: ohcnetwork/care

Length of output: 83


🏁 Script executed:

cat ruff.toml

Repository: ohcnetwork/care

Length of output: 965


🏁 Script executed:

# Check if there are other signal handlers in the codebase to see how they handle this
rg "post_save.connect|post_delete.connect|pre_save.connect" -A 5 --type py | head -40

Repository: ohcnetwork/care

Length of output: 1210


🏁 Script executed:

# Look at the other signal handler functions to see how they handle this
rg "def invalidate_tag_config_cache|def delete_model_cache" -A 8 --type py

Repository: ohcnetwork/care

Length of output: 1473


🏁 Script executed:

# Check the full invalidate_tag_config_cache function
cat -n care/emr/resources/tag/cache_invalidation.py | head -30

Repository: ohcnetwork/care

Length of output: 1190


🏁 Script executed:

cat -n care/emr/resources/tag/cache_invalidation.py | grep -A 15 "def invalidate_tag_config_cache"

Repository: ohcnetwork/care

Length of output: 664


🏁 Script executed:

# Verify the delete_model_cache function uses sender
cat -n care/emr/resources/base.py | grep -A 8 "def delete_model_cache"

Repository: ohcnetwork/care

Length of output: 550


Silence Ruff's unused argument warnings for signal handler parameters.
Line 9 defines sender and **kwargs but never uses them; Ruff's ARG rule will flag this. Rename to _sender and **_kwargs (the Django signal handler signature requires these, even when unused).

🔧 Lint-friendly fix
-def invalidate_facility_cache_on_identifier_change(sender, instance, **kwargs):
+def invalidate_facility_cache_on_identifier_change(_sender, instance, **_kwargs):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def invalidate_facility_cache_on_identifier_change(sender, instance, **kwargs):
def invalidate_facility_cache_on_identifier_change(_sender, instance, **_kwargs):
🧰 Tools
🪛 Ruff (0.14.14)

[warning] 9-9: Unused function argument: sender

(ARG001)


[warning] 9-9: Unused function argument: kwargs

(ARG001)

🤖 Prompt for AI Agents
In `@care/emr/signals/patient_identifier/cache_invalidation.py` at line 9, The
signal handler invalidate_facility_cache_on_identifier_change declares unused
parameters sender and **kwargs which triggers Ruff's ARG unused-argument
warnings; update the function signature to use _sender and **_kwargs (preserving
the Django signal signature) so the parameters are recognized as intentionally
unused and the linter stops flagging them.

Comment on lines +9 to +17
def invalidate_facility_cache_on_identifier_change(sender, instance, **kwargs):
facility_model_string = model_string(Facility)

if instance.facility_id:
cache.delete_pattern(
model_cache_key(facility_model_string, pk=instance.facility.external_id)
)
else:
cache.delete_pattern(model_cache_key(facility_model_string))
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find model_cache_key function definition
rg -n "def model_cache_key" --type=py

Repository: ohcnetwork/care

Length of output: 110


🏁 Script executed:

# Find model_string function definition
rg -n "def model_string" --type=py

Repository: ohcnetwork/care

Length of output: 135


🏁 Script executed:

# Find Facility model definition and external_id field
rg -n "class Facility" care/facility/models/facility.py -A 30 | head -50

Repository: ohcnetwork/care

Length of output: 2300


🏁 Script executed:

# Search for external_id field on Facility model
rg -n "external_id\s*=" care/facility/models/facility.py -B 2 -A 2

Repository: ohcnetwork/care

Length of output: 41


🏁 Script executed:

# Look for how cache keys are used elsewhere with Facility
rg -n "model_cache_key.*Facility" --type=py -B 2 -A 2

Repository: ohcnetwork/care

Length of output: 41


🏁 Script executed:

# Check if external_id has null constraints
rg -n "external_id" care/facility/models/facility.py | head -20

Repository: ohcnetwork/care

Length of output: 41


🏁 Script executed:

# Read model_cache_key implementation
sed -n '205,230p' care/emr/resources/base.py

Repository: ohcnetwork/care

Length of output: 1063


🏁 Script executed:

# Read model_string implementation
sed -n '196,210p' care/emr/resources/base.py

Repository: ohcnetwork/care

Length of output: 514


🏁 Script executed:

# Find BaseModel definition
rg -n "class BaseModel" --type=py care/

Repository: ohcnetwork/care

Length of output: 118


🏁 Script executed:

# Search for external_id more broadly in facility-related files
fd -e py care/facility | xargs rg "external_id" 2>/dev/null

Repository: ohcnetwork/care

Length of output: 50747


🏁 Script executed:

# Look at the full Facility model
wc -l care/facility/models/facility.py

Repository: ohcnetwork/care

Length of output: 95


🏁 Script executed:

# Check the base cache invalidation logic
sed -n '196,240p' care/emr/resources/base.py

Repository: ohcnetwork/care

Length of output: 1723


🏁 Script executed:

# Search for other places where Facility cache is accessed/invalidated
rg "cache.*Facility\|Facility.*cache" care/emr/resources/ -B 2 -A 2 | head -100

Repository: ohcnetwork/care

Length of output: 41


🏁 Script executed:

# Look at the actual signal handler connection for patient_identifier
rg -n "invalidate_facility_cache_on_identifier_change" --type=py -B 5 -A 10

Repository: ohcnetwork/care

Length of output: 2051


🏁 Script executed:

# Look for how cache keys are actually generated and used
rg "model_cache_key\(" care/emr/resources/base.py -A 2 -B 2

Repository: ohcnetwork/care

Length of output: 943


🏁 Script executed:

# Check if there are any other examples of facility cache invalidation
rg "invalidate.*facility\|Facility.*cache" care/emr/signals/ -i

Repository: ohcnetwork/care

Length of output: 41


🏁 Script executed:

# Check what PatientIdentifierConfig is and how it relates to Facility
rg "class PatientIdentifierConfig" --type=py -A 10

Repository: ohcnetwork/care

Length of output: 5702


🏁 Script executed:

# See if there are similar cache invalidation patterns elsewhere
rg "post_save.*connect" care/emr/signals/ -B 5 -A 5 | head -80

Repository: ohcnetwork/care

Length of output: 910


Cache invalidation should follow the established pattern: invalidate by both id and external_id.

The concern about external_id being null is unfounded—it's a UUID field with default=uuid4, so it's always populated. The cache key alignment is correct. However, the standard invalidation pattern elsewhere in care/emr/resources/base.py invalidates both by primary key (id) and by external_id:

cache.delete_pattern(model_cache_key(sender_model_string, pk=instance.id))
if external_id := getattr(instance, "external_id", None):
    cache.delete_pattern(model_cache_key(sender_model_string, pk=external_id))

Align with this pattern to avoid stale cache entries keyed by id.

🧰 Tools
🪛 Ruff (0.14.14)

[warning] 9-9: Unused function argument: sender

(ARG001)


[warning] 9-9: Unused function argument: kwargs

(ARG001)

🤖 Prompt for AI Agents
In `@care/emr/signals/patient_identifier/cache_invalidation.py` around lines 9 -
17, The invalidate_facility_cache_on_identifier_change function currently only
deletes the cache by external_id; change it to follow the standard pattern used
in care/emr/resources/base.py by deleting both the id and external_id keyed
caches: call cache.delete_pattern(model_cache_key(facility_model_string,
pk=instance.id)) and then, since external_id is present, also call
cache.delete_pattern(model_cache_key(facility_model_string,
pk=instance.external_id)) (or use getattr(instance, "external_id", None) if you
prefer the existing guard) so both possible cache keys are invalidated.

@codecov
Copy link

codecov bot commented Jan 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.44%. Comparing base (c466022) to head (7ac5284).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3501      +/-   ##
===========================================
+ Coverage    74.43%   74.44%   +0.01%     
===========================================
  Files          471      473       +2     
  Lines        21734    21747      +13     
  Branches      2264     2265       +1     
===========================================
+ Hits         16177    16189      +12     
- Misses        5055     5056       +1     
  Partials       502      502              

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

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.

Cache for instance identifiers on facility doesn't update on change

1 participant