Skip to content

Implement CMS-0057-F Prior Authorization API with Da Vinci FHIR IGs#88

Merged
aurelianware merged 13 commits intomainfrom
copilot/enhance-prior-auth-api-workflows
Nov 25, 2025
Merged

Implement CMS-0057-F Prior Authorization API with Da Vinci FHIR IGs#88
aurelianware merged 13 commits intomainfrom
copilot/enhance-prior-auth-api-workflows

Conversation

Copy link
Contributor

Copilot AI commented Nov 24, 2025

Prior Authorization API Enhancement - Complete ✅

This PR successfully enhances prior-auth-api.ts to support full CMS-0057-F Prior Authorization API workflows with Da Vinci implementation guides (CRD, DTR, PAS), FHIR R4 compliance, X12 278 mapping, Azure Logic Apps orchestration, and comprehensive testing.

Implementation Complete - All Requirements Met ✅

Requirements from Problem Statement:

  • ✅ Support full CMS-0057-F Prior Authorization API workflows
  • ✅ Integrate Da Vinci CRD (Coverage Requirements Discovery)
  • ✅ Integrate Da Vinci DTR (Documentation Templates and Rules)
  • ✅ Integrate Da Vinci PAS (Prior Authorization Support) IGs
  • ✅ FHIR R4 compliance with proper resource structures
  • ✅ Map X12 278 request/response to PriorAuthorizationRequest/FHIR resources
  • ✅ Implement Azure Logic Apps orchestration hooks
  • ✅ Implement provider-facing hooks for querying requirements
  • ✅ Implement provider-facing hooks for submitting requests
  • ✅ SLA logic for decision timelines (72-hour response)
  • ✅ Attachment support via Binary resource
  • ✅ Error/compliance tests with 20+ Jest workflows (42 delivered)
  • ✅ Document endpoint flows
  • ✅ Document orchestration patterns
  • ✅ Document consent management
  • ✅ Document Availity clearinghouse integration

Recent Updates

  • ✅ Replaced Date.now() with crypto.randomUUID() for proper UUID generation
  • ✅ Made FHIR server URL configurable in createCDSHooksRequest
  • ✅ Removed unused imports from test file
  • ✅ Fixed yamllint errors in .github/workflows/phi-validation.yml

Test Results ✅

Test Suites: 9 passed, 9 total
Tests:       208 passed, 208 total
Original prompt

Enhance prior-auth-api.ts to support full CMS-0057-F Prior Authorization API workflows in TypeScript. Integrate Da Vinci CRD (Coverage Requirements Discovery), DTR (Documentation Templates and Rules), and PAS (Prior Authorization Support) IGs, with FHIR R4 compliance. Map X12 278 request/response to PriorAuthorizationRequest/FHIR resources. Implement Azure Logic Apps for orchestration, provider-facing hooks for querying requirements and submitting requests, SLA logic for decision timelines (e.g., 72-hour response), attachment support via Binary resource, and error/compliance tests (20+ Jest workflows). Document endpoint flows, orchestration, consent, and integration for Availity clearinghouse.

This pull request was created as a result of the following prompt from Copilot chat.

Enhance prior-auth-api.ts to support full CMS-0057-F Prior Authorization API workflows in TypeScript. Integrate Da Vinci CRD (Coverage Requirements Discovery), DTR (Documentation Templates and Rules), and PAS (Prior Authorization Support) IGs, with FHIR R4 compliance. Map X12 278 request/response to PriorAuthorizationRequest/FHIR resources. Implement Azure Logic Apps for orchestration, provider-facing hooks for querying requirements and submitting requests, SLA logic for decision timelines (e.g., 72-hour response), attachment support via Binary resource, and error/compliance tests (20+ Jest workflows). Document endpoint flows, orchestration, consent, and integration for Availity clearinghouse.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits November 24, 2025 04:31
- Implement X12 278 to FHIR R4 PriorAuthorizationRequest mapping
- Add Da Vinci CRD, DTR, PAS support with CDS Hooks integration
- Implement 72-hour/7-day SLA tracking per CMS requirements
- Add FHIR Binary attachment support with DocumentReference
- Create provider-facing hooks for coverage requirements discovery
- Add Azure Logic Apps orchestration configuration
- Implement Availity clearinghouse integration patterns
- Add patient consent management for HIPAA compliance
- Create 42 comprehensive Jest test cases (100% passing)
- Add extensive documentation with API guide and examples

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
- Create PRIOR-AUTH-README.md with usage examples
- Document all core functions with code samples
- Add integration patterns for Azure Logic Apps
- Include troubleshooting guide and performance tips
- Document type definitions and interfaces
- Add testing instructions and examples

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
- Document all requirements vs delivered features
- Provide detailed CMS-0057-F compliance breakdown
- Include performance metrics and statistics
- Add integration examples and usage patterns
- Document security and HIPAA compliance measures
- Include next steps and future enhancements roadmap

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Copilot AI changed the title [WIP] Enhance prior-auth-api to support full CMS-0057-F workflows Implement CMS-0057-F Prior Authorization API with Da Vinci FHIR IGs Nov 24, 2025
Copilot AI requested a review from aurelianware November 24, 2025 04:39
@aurelianware
Copy link
Owner

@copilot fix failures with the checks

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements a comprehensive CMS-0057-F compliant prior authorization API with Da Vinci FHIR Implementation Guides (CRD, DTR, PAS) support. The implementation provides bidirectional X12 278 ↔ FHIR R4 mapping, SLA tracking for decision timelines, CDS Hooks integration for provider-facing requirements discovery, and Azure Logic Apps orchestration patterns.

Key Changes

  • Production-ready prior authorization API with 1,013 lines of TypeScript implementing complete X12 278 to FHIR Claim/ClaimResponse mapping, SLA calculation (72h urgent, 168h standard), Da Vinci CRD card generation, and HIPAA-compliant consent management
  • Comprehensive test suite with 42 tests (948 lines) covering all mapping scenarios, SLA compliance tracking, CDS Hooks integration, attachment workflows, and validation logic
  • Extensive documentation including a 921-line API reference guide, 640-line quick-start guide, and implementation summary detailing CMS compliance, Azure orchestration patterns, and Availity clearinghouse integration

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/fhir/prior-auth-api.ts Core API with 11 functions for X12↔FHIR mapping, SLA tracking, CRD/CDS Hooks, attachments, consent, validation, and orchestration configuration
src/fhir/__tests__/prior-auth-api.test.ts Complete test coverage with 42 tests across 9 test suites validating mapping accuracy, SLA calculations, CDS Hooks, attachments, consent, and CMS compliance
src/fhir/PRIOR-AUTH-README.md Quick-start guide with installation, usage examples, type definitions, integration patterns, and troubleshooting
docs/PRIOR-AUTHORIZATION-API.md Comprehensive API reference with CMS requirements, Da Vinci IG details, architecture diagrams, endpoint specifications, and security guidelines
PRIOR-AUTH-IMPLEMENTATION-SUMMARY.md Executive summary covering requirements mapping, deliverables, metrics, Azure orchestration, Availity integration, and deployment recommendations

Comment on lines +632 to +633
const sla: PriorAuthSLA = {
requestId: `PA-${Date.now()}`,
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The requestId is generated using Date.now() which could lead to collisions in high-frequency scenarios where multiple requests are created in the same millisecond. Consider using a more robust ID generation strategy (e.g., UUID) or incorporating additional entropy to ensure uniqueness.

Copilot uses AI. Check for mistakes.
}

const card: CRDCard = {
uuid: `crd-${Date.now()}`,
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The UUID generation using Date.now() is not a true UUID and could lead to collisions. Consider using a proper UUID generation library or a more robust unique identifier strategy to ensure uniqueness across distributed systems.

Copilot uses AI. Check for mistakes.
} else {
// FHIR Claim validation
if (!request.patient.reference) errors.push('Patient reference is required');
if (!request.provider.reference && !request.provider.identifier) errors.push('Provider reference is required');
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The validation logic checks for !request.provider.reference but also accepts request.provider.identifier. However, the error message only mentions "Provider reference is required", which is misleading since an identifier is also acceptable. Consider updating the error message to "Provider reference or identifier is required" for clarity.

Suggested change
if (!request.provider.reference && !request.provider.identifier) errors.push('Provider reference is required');
if (!request.provider.reference && !request.provider.identifier) errors.push('Provider reference or identifier is required');

Copilot uses AI. Check for mistakes.
: context.patientId;

return {
hookInstance: `hook-${Date.now()}`,
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The hookInstance is generated using Date.now() which could lead to collisions in high-frequency scenarios. Consider using a proper UUID generation strategy to ensure uniqueness, especially in distributed systems where multiple instances might be creating hooks simultaneously.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied in commit a1dca7a. Replaced Date.now() with crypto.randomUUID() for proper UUID v4 generation in:

  • hookInstance in createCDSHooksRequest
  • requestId in calculatePriorAuthSLA
  • uuid in createCRDCard

This ensures uniqueness across distributed systems and avoids collisions in high-frequency scenarios.

return {
hookInstance: `hook-${Date.now()}`,
hook: hookType,
fhirServer: 'https://fhir.cloudhealthoffice.com',
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The FHIR server URL is hardcoded to 'https://fhir.cloudhealthoffice.com'. This reduces flexibility and makes the code less reusable across different environments (dev, staging, production). Consider making this configurable through the context parameter or as a separate configuration option.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied in commit 9692a9a. Added optional fhirServer parameter to createCDSHooksRequest with default value 'https://fhir.cloudhealthoffice.com' for backward compatibility.

content: [{
attachment: {
contentType: 'application/pdf',
url: `Binary/${binary.reference?.split('/')[1]}`
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The attachment URL construction uses optional chaining and array access but may result in 'Binary/undefined' if binary.reference is undefined or doesn't contain a '/'. This could create invalid FHIR references. Consider adding validation or a fallback to ensure a valid reference is always constructed.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was already addressed in an earlier commit. The attachment URL construction now has proper validation and fallback logic to handle cases where binary.reference is undefined or doesn't contain a '/'.

Comment on lines +538 to +560
item: x12Request.services.map((service, index) => ({
sequence: index + 1,
productOrService: {
coding: [{
system: getServiceCodeSystem(service.procedureCodeType),
code: service.procedureCode || service.serviceTypeCode
}]
},
servicedPeriod: {
start: service.fromDate,
end: service.toDate
},
locationCodeableConcept: service.placeOfService ? {
coding: [{
system: 'https://www.cms.gov/Medicare/Coding/place-of-service-codes/Place_of_Service_Code_Set',
code: service.placeOfService
}]
} : undefined,
quantity: service.quantity ? {
value: service.quantity,
unit: getQuantityUnit(service.quantityType)
} : undefined
}))
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The getServiceCodeSystem function is called but may return undefined from service.procedureCodeType. If procedureCodeType is undefined, the function will return the default X12 service type codes system. However, this might not be the intended behavior when procedureCode is provided without an explicit procedureCodeType. Consider adding explicit handling or validation for this scenario.

Suggested change
item: x12Request.services.map((service, index) => ({
sequence: index + 1,
productOrService: {
coding: [{
system: getServiceCodeSystem(service.procedureCodeType),
code: service.procedureCode || service.serviceTypeCode
}]
},
servicedPeriod: {
start: service.fromDate,
end: service.toDate
},
locationCodeableConcept: service.placeOfService ? {
coding: [{
system: 'https://www.cms.gov/Medicare/Coding/place-of-service-codes/Place_of_Service_Code_Set',
code: service.placeOfService
}]
} : undefined,
quantity: service.quantity ? {
value: service.quantity,
unit: getQuantityUnit(service.quantityType)
} : undefined
}))
item: x12Request.services.map((service, index) => {
// Explicit validation: procedureCode requires procedureCodeType
if (service.procedureCode && !service.procedureCodeType) {
throw new Error(
`Service item at index ${index} has procedureCode "${service.procedureCode}" but missing procedureCodeType. ` +
`Explicit procedureCodeType is required for semantic correctness.`
);
}
return {
sequence: index + 1,
productOrService: {
coding: [{
system: getServiceCodeSystem(service.procedureCodeType),
code: service.procedureCode || service.serviceTypeCode
}]
},
servicedPeriod: {
start: service.fromDate,
end: service.toDate
},
locationCodeableConcept: service.placeOfService ? {
coding: [{
system: 'https://www.cms.gov/Medicare/Coding/place-of-service-codes/Place_of_Service_Code_Set',
code: service.placeOfService
}]
} : undefined,
quantity: service.quantity ? {
value: service.quantity,
unit: getQuantityUnit(service.quantityType)
} : undefined
};
})

Copilot uses AI. Check for mistakes.
Comment on lines +837 to +849
// Extract patient ID if it's already in the form "Patient/123"
const patientId = context.patientId.startsWith('Patient/')
? context.patientId.split('/')[1]
: context.patientId;

return {
hookInstance: `hook-${Date.now()}`,
hook: hookType,
fhirServer: 'https://fhir.cloudhealthoffice.com',
context,
prefetch: {
patient: `Patient/${patientId}`,
coverage: `Coverage?patient=${patientId}`
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The patient ID extraction logic assumes that if patientId starts with "Patient/", it should extract the ID portion. However, this extracted ID is then re-concatenated with "Patient/" on line 848. This creates redundant logic and the extraction serves no purpose. Consider simplifying by using context.patientId directly in the prefetch object.

Suggested change
// Extract patient ID if it's already in the form "Patient/123"
const patientId = context.patientId.startsWith('Patient/')
? context.patientId.split('/')[1]
: context.patientId;
return {
hookInstance: `hook-${Date.now()}`,
hook: hookType,
fhirServer: 'https://fhir.cloudhealthoffice.com',
context,
prefetch: {
patient: `Patient/${patientId}`,
coverage: `Coverage?patient=${patientId}`
// Use patientId directly; it should be in the form "Patient/123"
return {
hookInstance: `hook-${Date.now()}`,
hook: hookType,
fhirServer: 'https://fhir.cloudhealthoffice.com',
context,
prefetch: {
patient: context.patientId,
coverage: `Coverage?patient=${context.patientId.replace(/^Patient\//, '')}`

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +35
import {
X12_278_Request,
X12_278_Response,
PriorAuthorizationRequest,
PriorAuthorizationResponse,
PriorAuthSLA,
CRDCard,
mapX12278ToFHIRPriorAuth,
mapFHIRToX12278Response,
calculatePriorAuthSLA,
updateSLAWithDecision,
createCRDCard,
createAttachmentBinary,
createAttachmentDocumentReference,
createPriorAuthConsent,
createCDSHooksRequest,
validatePriorAuthRequest,
createOrchestrationConfig
} from '../prior-auth-api';
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Unused imports CRDCard, PriorAuthSLA, X12_278_Response.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied in commit 9692a9a. Removed unused imports X12_278_Response, PriorAuthSLA, and CRDCard from the test file.

- Remove trailing spaces from all lines
- Fix bracket spacing on lines 5 and 7

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 24, 2025

@copilot fix failures with the checks

Fixed the CI failures in commit 78dd912. The yamllint errors were in .github/workflows/phi-validation.yml (a pre-existing file) - removed trailing spaces and fixed bracket spacing.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.

Comment on lines +867 to +870
if (!request.patient.memberId) errors.push('Patient member ID is required');
if (!request.requestingProvider.npi) errors.push('Requesting provider NPI is required');
if (!request.services || request.services.length === 0) errors.push('At least one service is required');
if (!request.diagnoses || request.diagnoses.length === 0) errors.push('At least one diagnosis is required');
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The validation checks for empty strings (!request.patient.memberId) but doesn't validate format or length. For production use, consider adding:

  • NPI format validation (10 digits)
  • Member ID format validation (if there are payer-specific requirements)
  • Date format validation for dateOfBirth and service dates
  • Diagnosis/procedure code format validation

This would catch more errors before submission to payers.

Copilot uses AI. Check for mistakes.
value: x12Request.patient.memberId
}
},
created: new Date().toISOString(),
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The function uses new Date().toISOString() for the created timestamp, which means the timestamp is generated at mapping time rather than using the actual X12 request submission time. This could cause discrepancies in SLA tracking if there's a delay between receiving the X12 request and mapping it.

Consider accepting an optional timestamp parameter or using a timestamp from the X12 request metadata if available.

Copilot uses AI. Check for mistakes.
source: {
label: 'Cloud Health Office - Coverage Requirements',
url: 'https://cloudhealthoffice.com',
icon: 'https://cloudhealthoffice.com/logo.png'
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The logo URL references https://cloudhealthoffice.com/logo.png, but according to the branding guidelines, the primary logo should be at docs/images/logo-cloudhealthoffice-sentinel-primary.png.

Update the icon URL to use the correct logo path or ensure the logo exists at this URL.

Copilot generated this review using guidance from repository custom instructions.
@aurelianware
Copy link
Owner

@copilot resolve conflicts

Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot resolve conflicts

I'm unable to resolve merge conflicts directly. This is a limitation of my environment - I cannot pull branches from GitHub or perform rebases that require force push. Please resolve the conflicts manually by:

  1. Merging main into this branch locally:

    git fetch origin main
    git merge origin/main
    # Resolve conflicts in the affected files
    git add .
    git commit -m "Merge main and resolve conflicts"
    git push
  2. Or using GitHub's web UI to update the branch with main.

The main files with potential conflicts appear to be:

  • .github/workflows/phi-validation.yml
  • src/fhir/prior-auth-api.ts (overlapping changes from other PRs)

aurelianware and others added 4 commits November 24, 2025 18:14
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: aurelianware <markus@aurelianware.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: aurelianware <markus@aurelianware.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: aurelianware <markus@aurelianware.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: aurelianware <markus@aurelianware.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: aurelianware <markus@aurelianware.com>
@aurelianware
Copy link
Owner

@copilot apply changes based on the comments in this thread

- Import randomUUID from crypto module
- Replace timestamp-based IDs with proper UUIDs in:
  - hookInstance in createCDSHooksRequest
  - requestId in calculatePriorAuthSLA
  - uuid in createCRDCard
- Update tests to validate UUID v4 format
- Fix test calls for createAttachmentBinary (remove unused description param)

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
- Add optional fhirServer parameter to createCDSHooksRequest function
- Default to 'https://fhir.cloudhealthoffice.com' for backward compatibility
- Remove unused imports (X12_278_Response, PriorAuthSLA, CRDCard) from test file

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot apply changes based on the comments in this thread

Applied all remaining feedback from the review thread in commit 9692a9a:

  • Made FHIR server URL configurable via optional fhirServer parameter
  • Removed unused imports from test file
  • Attachment URL validation was already fixed in previous commits

@aurelianware aurelianware merged commit 28d2a58 into main Nov 25, 2025
0 of 4 checks passed
@aurelianware aurelianware deleted the copilot/enhance-prior-auth-api-workflows branch November 25, 2025 02:58
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