Adds the prior authorisation event construction logic with documentation updates#282
Adds the prior authorisation event construction logic with documentation updates#282
Conversation
WalkthroughThis PR introduces prior authorization analytics support by adding new claim processing utilities, defined constants and enum types, updated service handlers to collect analytics data, dashboard templates for visualization, and comprehensive documentation updates describing both CMS and prior authorization metrics. Changes
Sequence DiagramsequenceDiagram
actor Client
participant ServiceHandler as ClaimResponse Handler
participant ClaimProcessor as Claim Utils
participant Database as FHIR Repository
participant Analytics as Analytics Event
participant FHIRContext as FHIR Context
Client->>ServiceHandler: PUT ClaimResponse (outcome=COMPLETED)
ServiceHandler->>ServiceHandler: Extract claimResponse.request.reference
ServiceHandler->>ClaimProcessor: Parse Claim ID from reference
ClaimProcessor-->>ServiceHandler: Claim ID
ServiceHandler->>Database: Fetch referenced Claim
Database-->>ServiceHandler: Claim data
ServiceHandler->>ClaimProcessor: determineClaimType(claim.priority)
ClaimProcessor-->>ServiceHandler: claimType (STANDARD=1/EXPEDITED=2)
ServiceHandler->>ClaimProcessor: determineClaimStatus(claimResponse)
ClaimProcessor-->>ServiceHandler: claimStatus (APPROVED=3/DENIED=5)
ServiceHandler->>ClaimProcessor: calculateTimeToDecide(timestamps)
ClaimProcessor-->>ServiceHandler: timeToDecide (hours)
ServiceHandler->>ClaimProcessor: isSlaViolated(timeToDecide, claimType)
ClaimProcessor-->>ServiceHandler: isSLAViolated (boolean)
ServiceHandler->>Analytics: Construct PriorAuthorisationAnalyticsResponseEvent
Analytics-->>ServiceHandler: Analytics event
ServiceHandler->>FHIRContext: setProperty(analyticsEvent)
FHIRContext-->>ServiceHandler: Stored
ServiceHandler->>Database: Update ClaimResponse
ServiceHandler-->>Client: ClaimResponse|OperationOutcome|FHIRError|error
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@fhir-service/Dependencies.toml`:
- Line 80: The TOML file contains duplicate "version" keys inside several
[[package]] blocks causing parse errors; remove the extra "version" entries so
each [[package]] block has a single version key, and update the dependency
auto-generation logic (the code that emits [[package]] blocks) to ensure it
writes only one "version" assignment per package; after changes, validate by
parsing Dependencies.toml with a TOML parser to confirm no "Cannot overwrite a
value" errors remain.
In `@fhir-service/records.bal`:
- Around line 654-658: Remove the trailing semicolons from the enum declarations
to match the file's style; specifically update the ClaimPriority enum (and the
other enums referenced: BulkMatchStatus, DaVinciExportStatus, ResourceType) by
deleting the trailing ";" after the closing brace so the declarations end with
"}" only; ensure you only remove the semicolons and do not alter enum member
names or values.
In `@fhir-service/resources/analytics_README.md`:
- Around line 5-22: The document mixes British "Authorisation" and American
"Authorization"; pick one spelling and make it consistent by renaming the
heading "Prior Authorisation Analytics" and updating all occurrences of
"authorization"/"authorisation" in the section (including the lines listing
standard and expedited prior authorization requests and any mentions like "Prior
Authorization Metrics") and update any referenced Moesif docs links or text to
match the chosen variant so the section reads consistently.
In `@fhir-service/resources/analytics/moesif/moesif_README.md`:
- Around line 21-23: Replace the image-style Markdown for the dashboard
templates with normal links: change the two entries that use "" and "" to standard link
syntax like "[Sample CMS Analytics Dashboard
Template](moesif-cms-dashboard-template.json)" and "[Sample Prior Authorisation
Analytics Dashboard
Template](prior-auth-analytics-moesif-dashboard-template.json)" so the JSON
files are clickable imports instead of attempted images.
In
`@fhir-service/resources/analytics/moesif/prior-auth-analytics-moesif-dashboard-template.json`:
- Around line 735-746: The dashboard widget currently has an empty es_query and
a urlQuery grouping by request.route.raw so it shows route volumes; update the
widget's es_query to include the same ClaimResponse/status filters used by the
other prior-auth widgets and add a clause to filter
metadata.priorAuth.isSLAViolated == true (or the equivalent JSON boolean path).
Ensure the es_query contains the ClaimResponse/status conditions and the SLA
boolean filter and leave the urlQuery grouping/metrics as-is so the widget now
only counts events where metadata.priorAuth.isSLAViolated is true and matches
the PA status filters.
- Around line 561-645: The widgets claim "hours" but
metadata.priorAuth.timeToDecide (produced by calculateTimeToDecide() in
fhir-service/utils.bal) is in minutes; update the aggregations named like
metadata__priorAuth__timeToDecide|weighted_avg to convert minutes→hours (divide
the value by 60 in the weighted_avg value via a scripted/value expression) or
alternatively change the widget names/labels to "minutes" consistently; apply
the same fix to the other affected widgets (e.g., the one around lines 648-732)
that use metadata.priorAuth.timeToDecide.
- Around line 203-288: The widget's scripted metrics for "% of approved standard
claims" and the other similar widgets only count statuses 3 (approved) and 5
(denied) and therefore exclude PARTIALLY_APPROVED (value 4) from the
denominator, causing percentages to be overstated; update the aggregation
scripts and any formula/denominator references that use
metadata.priorAuth.claimStatus to include status 4 in the total (or explicitly
document intentional exclusion) — search for the scripted metrics named like
"scripted__1221885305|sum" / "scripted__404236855|sum" and the script strings
comparing [metadata.priorAuth.claimStatus] == 3 or == 5 and change them so the
denominator sums include records where claimStatus == 3 OR 4 OR 5 (or adjust the
percentage formula to use sum(approved + partially_approved + denied) as the
denominator), and apply the same change to the other affected widgets referenced
in the comment.
In `@fhir-service/service.bal`:
- Around line 720-728: The timeToDecide is being derived from the incoming
claimResponse.meta?.lastUpdated before persistence; instead compute it from the
server-side persisted completion timestamp returned by updateClaimResponse() (or
the updated ClaimResponse's meta.lastUpdated) after the update succeeds. Move
the call to calculateTimeToDecide to after updateClaimResponse(), pass the
updated/persisted lastUpdated value (not the incoming payload), then build the
r4:PriorAuthorisationAnalyticsResponseEvent and call
fhirContext.setProperty(r4:PRIOR_AUTH_ANALYTICS_EVENT, event) using that
server-derived timeToDecide; ensure you still call isSlaViolated(claimType,
timeToDecide) with the new value.
- Around line 706-728: The analytics enrichment (calls to getById and
claimResource.cloneWithType) must not abort the PUT; wrap the linked-Claim
lookup and clone in a non-throwing guard (e.g., use a var assignment and
type-check or trap) so failures are logged and skipped instead of propagating
via check — locate the isolated resource function put and replace the lines
using check getById(fhirConnector, CLAIM, claimId) and check
claimResource.cloneWithType() with a safe path that on error logs the problem
and skips building/setting the r4:PRIOR_AUTH_ANALYTICS_EVENT (or continues
without calling fhirContext.setProperty), leaving updateClaimResponse() to run
and return its normal result.
In `@fhir-service/utils.bal`:
- Around line 1624-1628: The formatTimeDifference function currently truncates
elapsed seconds to whole hours (int cast), causing near-hour overages to be
lost; change formatTimeDifference to compute hours by dividing diffSeconds by
3600 and rounding up (ceiling) so partial hours count as a full hour (e.g., use
math:ceil on diffSeconds/3600 and return as int); update any callers such as
isSlaViolated to rely on the new behavior.
- Around line 1596-1601: The log message in the SLA branch using the
timeToDecide check incorrectly labels the standard-claim path as "Claim type:
Expedited"; update the debug log in the else branch that returns true to use
"Claim type: Standard" (keep the same template with timeToDecide) so the two
branches correctly report "Expedited" when timeToDecide <= 168 and "Standard"
when > 168; locate the branch using the timeToDecide variable and the existing
log:printDebug calls to make this change.
- Around line 1460-1514: The code counts A1 adjudications across adjudications
but compares to numberOfItems; change counting to be one approval per item:
inside the foreach davincipas:PASClaimResponseItem items loop initialize a local
boolean (e.g., itemApproved) false, then when iterating adjudications/extensions
and you hit a code equal to A1 (within the reviewActionCoding.code check that
uses REVIEW_ACTION_URL and REVIEW_ACTION_CODE_URL), set itemApproved = true,
increment numberOfApprovedAdjudications once for that item, and break out of the
inner adjudication/extension loops so you don’t double-count; ensure
numberOfApprovedAdjudications is only incremented at most once per
davincipas:PASClaimResponseItem.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 50329df7-ef50-4653-b7bd-d39e457de65d
⛔ Files ignored due to path filters (1)
fhir-service/resources/analytics/moesif/prior_auth_analytics_sample_moesif_dashboard.pngis excluded by!**/*.png
📒 Files selected for processing (9)
fhir-service/Dependencies.tomlfhir-service/constants.balfhir-service/records.balfhir-service/resources/analytics/moesif/moesif-cms-dashboard-template.jsonfhir-service/resources/analytics/moesif/moesif_README.mdfhir-service/resources/analytics/moesif/prior-auth-analytics-moesif-dashboard-template.jsonfhir-service/resources/analytics_README.mdfhir-service/service.balfhir-service/utils.bal
fhir-service/resources/analytics/moesif/prior-auth-analytics-moesif-dashboard-template.json
Show resolved
Hide resolved
|
Closing this PR. Please refer to #286 |
Adds the prior authorisation event construction logic with documentation updates
Summary by CodeRabbit
New Features
Documentation
Chores