Kulcare Docs
DeveloperAuthentication Documentation04 featuresAbha_phr

ABDM Consent Manager Implementation Plan (Updated)

Overview

This document outlines the implementation plan for the ABDM Consent Manager (CM) module for patient-centric consent management. The implementation leverages existing HIU/HIP infrastructure without creating new database tables or fields, using ABDM APIs as the source of truth for configurations.

Current State Analysis

Existing Infrastructure

The following components are already implemented and working:

HIP (Healthcare Information Provider)

  • Controllers: HipConsentsController, HipConsentWebhooksController
  • Models: HipConsent
  • Routes: /consents endpoints for HIP
  • Webhook handlers for consent notifications

HIU (Healthcare Information User)

  • Controllers: HiuConsentRequestsController, HiuConsentWebhooksController
  • Models: HiuConsentRequest, HiuConsentArtefact
  • Services: HiuConsentRequestServices::Init, HiuConsentRequestServices::OnNotifyHiu
  • Interactors: HiuConsentRequestActions::Create, Index, Show
  • Routes: /consent_requests endpoints for HIU
  • Webhook handlers managing consent status updates

Supporting Infrastructure

  • AbdmRequest: Logs all ABDM API calls
  • AbdmWebhook: Logs all webhook data
  • Abdm::FetchGatewayTokenV3: Token management
  • PHR Login: Patient authentication system

What's Being Added

The Consent Manager (CM) module adds patient-facing capabilities:

  • Auto-approval configuration via ABDM APIs
  • Direct consent request management by patients
  • Consent approval/denial by patients
  • Consent revocation functionality
  • Enhanced consent artefact management

Architecture Approach

Core Principles

  1. No new database tables - Use existing HiuConsentRequest and HiuConsentArtefact models
  2. Leverage webhooks - Existing webhook handlers already manage consent data flow
  3. ABDM as source of truth - Store configurations in ABDM, fetch via API when needed
  4. Follow existing patterns - Use established interactor/service/controller patterns

High-Level Flow

  1. Auto-Approval Configuration: Patients configure auto-approval via ABDM API
  2. Consent Request Listing: Fetch from ABDM CM API, sync with HiuConsentRequest
  3. Consent Approval/Denial: Patient actions via ABDM CM API
  4. Consent Revocation: Revoke via ABDM API, webhook updates status
  5. Consent Artefact Management: View and manage via ABDM APIs

Integration Points

  • Uses existing clinic_patients for patient identification
  • Leverages existing ABDM token management (Abdm::FetchGatewayTokenV3)
  • Follows AbdmRequest logging pattern for all external API calls
  • Integrates with existing HIU consent request flow via webhooks

Implementation Components

No Database Changes Required

This implementation uses existing database infrastructure:

  • HiuConsentRequest: Already stores consent requests with status
  • HiuConsentArtefact: Already stores consent artefacts
  • AbdmRequest: Logs all API calls to ABDM
  • AbdmWebhook: Logs all webhook data

Auto-approval configurations are stored in ABDM and fetched via API when needed.

Service Layer Implementation

Directory Structure

parts/abdm/services/abdm/cm/
├── cm_auto_approval_services/
│   ├── create.rb          # POST /api/hiecm/consent/v3/auto/approve
│   ├── fetch.rb           # GET auto-approval configuration from ABDM
│   ├── enable.rb          # POST /api/hiecm/consent/v3/auto/approve/{id}/enable
│   └── disable.rb         # POST /api/hiecm/consent/v3/auto/approve/{id}/disable
├── cm_consent_services/
│   ├── fetch_all.rb       # GET /api/hiecm/consent/v3/request
│   ├── fetch_details.rb   # GET /api/hiecm/consent/v3/request/{id}
│   ├── approve.rb         # POST /api/hiecm/consent/v3/request/{id}/approve
│   ├── deny.rb            # POST /api/hiecm/consent/v3/request/{id}/deny
│   └── revoke.rb          # POST /api/hiecm/consent/v3/revoke
└── cm_artefact_services/
    ├── fetch_all.rb       # GET /api/hiecm/consent/v3/artefact
    ├── fetch_by_id.rb     # GET /api/hiecm/consent/v3/artefact/{id}
    └── fetch_by_request.rb # GET /api/hiecm/consent/v3/artefact/request/{requestId}

Service Implementation Pattern

module Abdm
  module Cm
    module CmConsentServices
      class Approve
        def self.perform(consent_request_id, consent_data, clinic_patient_id)
          # 1. Get authentication token
          token = Abdm::FetchGatewayTokenV3.perform
          
          # 2. Build API request
          url = "#{Rails.application.credentials.abdm_gateway_host_cm}/api/hiecm/consent/v3/request/#{consent_request_id}/approve"
          headers = build_headers(token)
          body = build_request_body(consent_data)
          
          # 3. Make API call
          begin
            result = HTTParty.post(url, body: body.to_json, headers: headers)
          rescue StandardError => e
            error = e.to_s
          end
          
          # 4. Log in AbdmRequest
          abdm_request = log_request(url, body, clinic_patient_id)
          
          # 5. Handle Response
          handle_response(result, error, abdm_request)
        end
        
        private
        
        def self.build_headers(token)
          {
            'Content-Type' => 'application/json',
            'Authorization' => "Bearer #{token}",
            'X-CM-ID' => Rails.application.credentials.abdm_cm_id,
            'X-AUTH-TOKEN' => "Bearer #{token}",
            'REQUEST-ID' => SecureRandom.uuid,
            'TIMESTAMP' => Time.now.utc.iso8601(3)
          }
        end
        
        def self.build_request_body(consent_data)
          {
            consents: consent_data[:consents]
          }
        end
        
        def self.log_request(url, body, clinic_patient_id)
          AbdmRequest.create!(
            request_id: SecureRandom.uuid,
            url: url,
            payload: body,
            requested_by_id: clinic_patient_id,
            requested_by_type: 'ClinicPatient'
          )
        end
        
        def self.handle_response(result, error, abdm_request)
          if result.present? && result.success?
            success = true
            response = result.parsed_response
            code = result.code
          elsif error.present?
            success = false
            response = { error: error }
          else
            success = false
            response = result.parsed_response
            code = result.code
          end
          
          abdm_request.update!(
            response: response,
            status_code: code,
            success: success
          )
          
          { success: success, data: response }
        end
      end
    end
  end
end

Interactor Layer Implementation

Directory Structure

parts/abdm/interactors/abdm/cm/
├── cm_auto_approval_actions/
│   ├── create.rb          # Create auto-approval configuration
│   ├── fetch.rb           # Get current configuration
│   ├── enable.rb          # Enable auto-approval for HIU
│   └── disable.rb         # Disable auto-approval for HIU
├── cm_consent_actions/
│   ├── index.rb           # List all consent requests (with filters)
│   ├── show.rb            # Show specific consent request details
│   ├── approve.rb         # Approve consent request
│   ├── deny.rb            # Deny consent request with reason
│   ├── pending.rb         # Get pending consent requests
│   ├── approved.rb        # Get approved consent requests
│   └── denied.rb          # Get denied consent requests
└── cm_artefact_actions/
    ├── index.rb           # List all consent artefacts
    ├── show.rb            # Show specific artefact details
    ├── revoke.rb          # Revoke consent artefact
    └── by_request.rb      # Get artefacts by request ID

Interactor Implementation Pattern

module Abdm
  module Cm
    module CmConsentActions
      class Approve < BaseInteractor
        def call
          require_context(:consent_request_id)
          require_context(:clinic_patient_id)
          require_context(:consents)
          
          validate_patient!
          fetch_consent_from_abdm!
          prepare_consent_data!
          
          # Call ABDM CM API to approve
          result = Abdm::Cm::CmConsentServices::Approve.perform(
            context.consent_request_id,
            context.consent_data,
            context.clinic_patient_id
          )
          
          fail_with_error!('Approval failed', result[:error]) unless result[:success]
          
          # Webhook will update HiuConsentRequest status
          
          context.records = result[:data]
          context.message = 'Consent request approved successfully'
        end
        
        private
        
        def validate_patient!
          context.clinic_patient = ClinicPatient.find_by(id: context.clinic_patient_id)
          fail_with_error!('Patient not found') unless context.clinic_patient
        end
        
        def fetch_consent_from_abdm!
          # Fetch consent details from ABDM CM API
          result = Abdm::Cm::CmConsentServices::FetchDetails.perform(
            context.consent_request_id,
            context.clinic_patient_id
          )
          fail_with_error!('Cannot fetch consent details') unless result[:success]
          context.consent_details = result[:data]
        end
        
        def prepare_consent_data!
          context.consent_data = {
            consents: context.consents.map do |consent|
              {
                hiTypes: consent[:hi_types],
                hip: { id: consent[:hip_id] },
                careContexts: consent[:care_contexts],
                permission: {
                  dateRange: {
                    from: consent[:date_from],
                    to: consent[:date_to]
                  },
                  frequency: consent[:frequency] || { unit: 'DAY', value: 0, repeats: 0 },
                  accessMode: consent[:access_mode] || 'VIEW',
                  dataEraseAt: consent[:data_erase_at]
                }
              }
            end
          }
        end
      end
    end
  end
end

Controller Layer Implementation

Controller Structure

# parts/abdm/controllers/abdm/cm/cm_auto_approvals_controller.rb
module Abdm
  module Cm
    class CmAutoApprovalsController < ApiController
      before_action :policy_check
      
      def create    # POST - Create auto-approval config
        result = Cm::CmAutoApprovalActions::Create.call(params)
        render_result(result)
      end
      
      def show      # GET - Get current config
        result = Cm::CmAutoApprovalActions::Fetch.call(params)
        render_result(result)
      end
      
      def enable    # POST - Enable auto-approval
        result = Cm::CmAutoApprovalActions::Enable.call(params)
        render_result(result)
      end
      
      def disable   # POST - Disable auto-approval
        result = Cm::CmAutoApprovalActions::Disable.call(params)
        render_result(result)
      end
      
      private
      
      def policy_check
        authorize params, policy_class: CmAutoApprovalsControllerPolicy
      end
    end
  end
end

# parts/abdm/controllers/abdm/cm/cm_consents_controller.rb
module Abdm
  module Cm
    class CmConsentsController < ApiController
      before_action :policy_check
      
      def index     # GET - List consent requests
        result = Cm::CmConsentActions::Index.call(params)
        render_result(result)
      end
      
      def show      # GET - Show consent details
        result = Cm::CmConsentActions::Show.call(params)
        render_result(result)
      end
      
      def approve   # POST - Approve consent
        result = Cm::CmConsentActions::Approve.call(params)
        render_result(result)
      end
      
      def deny      # POST - Deny consent
        result = Cm::CmConsentActions::Deny.call(params)
        render_result(result)
      end
      
      def pending   # GET - Filter pending
        result = Cm::CmConsentActions::Pending.call(params)
        render_result(result)
      end
      
      def approved  # GET - Filter approved
        result = Cm::CmConsentActions::Approved.call(params)
        render_result(result)
      end
      
      def denied    # GET - Filter denied
        result = Cm::CmConsentActions::Denied.call(params)
        render_result(result)
      end
      
      private
      
      def policy_check
        authorize params, policy_class: CmConsentsControllerPolicy
      end
    end
  end
end

Routes Configuration

# In parts/abdm/routes.rb, add under the abdm namespace:

namespace :cm do
  # Auto-approval management
  resource :auto_approval, only: [:create, :show], controller: 'cm_auto_approvals' do
    post :enable
    post :disable
  end
  
  # Consent management
  resources :consents, only: [:index, :show], controller: 'cm_consents' do
    member do
      post :approve
      post :deny
    end
    collection do
      get :pending
      get :approved
      get :denied
    end
  end
  
  # Artefact management
  resources :consent_artefacts, only: [:index, :show], controller: 'cm_consent_artefacts' do
    member do
      post :revoke
    end
    collection do
      get 'request/:request_id', action: :by_request
    end
  end
end

# Webhook routes (if needed)
match '/abdm/cm/on-auto-approval', to: 'abdm/cm/cm_webhooks#on_auto_approval', via: [:post]

API Headers Configuration

All CM API calls require the following headers:

{
  'Content-Type' => 'application/json',
  'Authorization' => "Bearer #{token}",  # From Abdm::FetchGatewayTokenV3
  'X-CM-ID' => Rails.application.credentials.abdm_cm_id,
  'X-AUTH-TOKEN' => "Bearer #{token}",
  'REQUEST-ID' => SecureRandom.uuid,
  'TIMESTAMP' => Time.now.utc.iso8601(3)
}

Data Flow

Auto-Approval Configuration Flow

  1. Patient configures auto-approval → API call to ABDM
  2. Configuration stored in ABDM (not local DB)
  3. When consent request arrives → ABDM checks auto-approval
  4. Auto-approved requests → webhook updates HiuConsentRequest status
  1. Fetch consent requests from ABDM CM API
  2. Sync with existing HiuConsentRequest records
  3. Display combined data to patient
  4. Patient approves/denies → API call to ABDM
  5. Webhook updates local HiuConsentRequest status
  1. Patient selects consent to revoke
  2. API call to ABDM with consent IDs
  3. ABDM processes revocation
  4. Webhook updates HiuConsentArtefact status

Implementation Phases

Phase 1: Foundation (Week 1)

  • Create directory structure for CM module
  • Implement fetch services (read-only operations)
  • Create basic controllers and routes
  • Test with existing HIU consent data

Phase 2: Auto-Approval (Week 1-2)

  • Implement auto-approval create service
  • Add enable/disable functionality
  • Create corresponding interactors
  • Integration testing with ABDM sandbox
  • Implement approve/deny services
  • Add consent filtering (pending/approved/denied)
  • Create patient-facing API endpoints
  • Handle error scenarios

Phase 4: Revocation & Artefacts (Week 3)

  • Implement revoke service
  • Add artefact fetch functionality
  • Complete webhook integration
  • End-to-end testing

Phase 5: Testing & Documentation (Week 4)

  • Unit tests for all services
  • Integration tests with ABDM sandbox
  • API documentation
  • Error handling improvements

Key Implementation Notes

  1. No Database Changes: All consent data uses existing HIU tables
  2. ABDM as Source: Auto-approval config stored in ABDM, not locally
  3. Webhook Integration: Existing webhook handlers update local records
  4. Authentication: Use existing PHR login for patient authentication
  5. Error Handling: Follow existing BaseInteractor error patterns
  6. Logging: All API calls logged in AbdmRequest table

API Endpoints Summary

Auto-Approval

  • POST /api/v3/abdm/cm/auto_approval - Configure auto-approval
  • GET /api/v3/abdm/cm/auto_approval - Get configuration
  • POST /api/v3/abdm/cm/auto_approval/enable - Enable
  • POST /api/v3/abdm/cm/auto_approval/disable - Disable
  • GET /api/v3/abdm/cm/consents - List all consents
  • GET /api/v3/abdm/cm/consents/:id - Get consent details
  • POST /api/v3/abdm/cm/consents/:id/approve - Approve
  • POST /api/v3/abdm/cm/consents/:id/deny - Deny
  • GET /api/v3/abdm/cm/consents/pending - Pending consents
  • GET /api/v3/abdm/cm/consents/approved - Approved consents
  • GET /api/v3/abdm/cm/consents/denied - Denied consents
  • GET /api/v3/abdm/cm/consent_artefacts - List artefacts
  • GET /api/v3/abdm/cm/consent_artefacts/:id - Get artefact
  • POST /api/v3/abdm/cm/consent_artefacts/:id/revoke - Revoke
  • GET /api/v3/abdm/cm/consent_artefacts/request/:request_id - By request

Success Metrics

  • API response time < 2 seconds
  • Successful ABDM integration
  • No database migrations required
  • Seamless integration with existing HIU/HIP modules
  • All consent operations functional

On this page