Kulcare Docs
General

Federation Schema

Purpose: Federated deployment support for on-premise installations syncing to central cloud Tenant Scoped: No (facility-based access control) RLS Enabled: No Location: Central Cloud only

Overview

The federation schema manages:

  • Registry of on-premise facility installations
  • Master Patient Index for cross-facility identity
  • Inbound sync tracking from on-premise facilities
  • Aggregated clinical data for patient portal
  • Feature configuration per deployment mode
  • Cloud-proxied appointment booking

This schema exists only on the Central Cloud, not on on-premise installations.


How Federated Deployment Works

The Two Deployment Modes

Kulcare operates in two deployment modes from a single codebase:

+------------------------------------------------------------------+
|                     DEPLOYMENT ARCHITECTURE                       |
+------------------------------------------------------------------+
|                                                                   |
|   CLOUD SAAS                          ON-PREMISE                  |
|   ==========                          ==========                  |
|                                                                   |
|   +------------------------+          +------------------------+  |
|   | Full Multi-Tenant      |          | Single-Organization    |  |
|   | Platform               |          | Installation           |  |
|   +------------------------+          +------------------------+  |
|   | - All schemas          |          | - Core schemas only    |  |
|   | - RLS enabled          |          | - No RLS               |  |
|   | - Growth/Connect       |          | - No Growth/Connect    |  |
|   | - Federation receiver  |          | - Sync sender          |  |
|   +------------------------+          +------------------------+  |
|            ^                                    |                 |
|            |                                    |                 |
|            +------------------------------------+                 |
|                   Outbound Sync (continuous)                      |
|                   + Appointment bookings (inbound)                |
|                                                                   |
+------------------------------------------------------------------+

On-Premise Schema Relationship

The on-premise database schema is a strict subset of the cloud schema:

SchemaCloud SaaSOn-PremiseNotes
referenceFullFullSame lookup tables
identityFull + tenant_idSimplified (no tenant_id)Single organization
clinicalFull + tenant_idSimplified (no tenant_id)Core clinical functionality
billingFullBasicPayment gateway cloud-only
growthFullNot includedCloud-only marketing
connectFullNot includedCloud-only networking
enterpriseFullNot includedCloud-only employer benefits
integrationFullFullABDM and webhooks
auditFullFullCompliance logging
federationFull (12 tables)Not includedCloud receives sync
syncNot included4 tablesOn-premise sends sync

Code Reuse Strategy

Both deployments use the same Rails application codebase with environment-based configuration:

Same Codebase, Different Configuration
======================================

Cloud:                              On-Premise:
  DEPLOYMENT_MODE=cloud               DEPLOYMENT_MODE=on_premise
  MULTI_TENANT=true                   SYNC_ENABLED=true
  FEDERATION=enabled                  ORGANIZATION_ID=<uuid>

Result:                             Result:
  - Load all parts                    - Load core parts only
  - Enable RLS policies               - Skip RLS policies
  - tenant_id on all tables           - No tenant_id columns
  - Federation receiver active        - Sync sender active

Why On-Premise is a Subset

1. Multi-Tenancy Removal

On-premise installations serve a single organization (possibly with multiple facilities), so tenant isolation is unnecessary:

  • tenant_id columns removed from all tables
  • Row-Level Security (RLS) policies not created
  • Simpler queries without tenant filtering

2. Cloud-Only Features

Certain features only make sense in a cloud context:

FeatureWhy Cloud-Only
Growth (campaigns, leads)Marketing requires cloud analytics
Connect (professional network)Cross-organization by nature
Enterprise (employer benefits)B2B relationships span organizations
Federation receiverOn-premise sends, cloud receives

3. Sync Layer Inversion

The sync direction is inverted between deployments:

DeploymentSync RoleTables
CloudReceiverfederation.* (12 tables)
On-PremiseSendersync.* (4 tables)

On-Premise Sync Tables

On-premise installations have a dedicated sync schema (not part of cloud):

+------------------------------------------------------------------+
|  SYNC SCHEMA (On-Premise Only)                                    |
+------------------------------------------------------------------+
|                                                                   |
|  +------------------------+    +------------------------+         |
|  | sync_configuration     |    | outbound_sync_queue    |         |
|  +------------------------+    +------------------------+         |
|  | cloud_endpoint_url     |    | resource_type          |         |
|  | api_key (encrypted)    |    | resource_id            |         |
|  | api_secret (encrypted) |    | operation_type         |         |
|  | sync_frequency_minutes |    | payload                |         |
|  | last_sync_at           |    | sync_status            |         |
|  | sync_enabled           |    | retry_count            |         |
|  +------------------------+    +------------------------+         |
|                                                                   |
|  +------------------------+    +------------------------+         |
|  | inbound_appointment_   |    | local_feature_flags    |         |
|  | queue                  |    +------------------------+         |
|  +------------------------+    | feature_key            |         |
|  | cloud_booking_id       |    | is_enabled             |         |
|  | slot_id                |    | override_reason        |         |
|  | patient_data           |    | effective_from         |         |
|  | status                 |    | effective_until        |         |
|  +------------------------+    +------------------------+         |
|                                                                   |
+------------------------------------------------------------------+

Data Flow Between Deployments

ON-PREMISE                                CENTRAL CLOUD
==========                                =============

[clinical.patients]                       [federation.master_patient_index]
[clinical.encounters]     --SYNC-->       [federation.federated_clinical_data]
[clinical.prescriptions]                  [federation.sync_data_provenance]
                                          [federation.patient_identity_links]

[sync.outbound_sync_queue]  --POST-->     [federation.inbound_sync_records]

                           <--PUSH--      [federation.appointment_bookings]
[sync.inbound_appointment_queue]          (cloud-proxied online booking)

Source Code Protection

On-premise deployments protect Kulcare intellectual property:

  • Ruby source files encrypted with RubyEncoder (.rbe extension)
  • Decryption keys hardware-locked to licensed servers
  • Configuration files (database.yml, .env) remain editable
  • Database migrations readable for schema transparency

Entities

Facility Registry

Entity: FederatedFacility

Purpose: Registry of all on-premise installations syncing to central cloud

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
facility_codeStringYesUnique facility identifier
facility_nameStringYesDisplay name
facility_typeEnumYeshospital, clinic, diagnostic_center, pharmacy
deployment_modeEnumYeson_premise, cloud, hybrid
organization_nameStringNoParent organization
country_codeStringYesISO country code (IN, US, AE)
stateStringNoState/province
cityStringNoCity
timezoneStringYesFacility timezone (e.g., Asia/Kolkata)
sync_enabledBooleanYesWhether sync is active
sync_frequency_minutesIntegerNoExpected sync interval (default: 15)
last_sync_atTimestampNoLast successful sync
last_heartbeat_atTimestampNoLast connectivity check
sync_statusEnumYesactive, degraded, offline, suspended
registration_dateDateYesWhen facility registered
contract_expiry_dateDateNoLicense expiry
data_retention_daysIntegerNoHow long to retain synced data
settingsJSONBNoFacility-specific configuration
created_atTimestampYesRecord creation
updated_atTimestampYesLast update

Sync Status Values:

StatusDescription
activeSyncing normally within expected frequency
degradedSyncing but with delays or partial failures
offlineNo sync received beyond threshold (e.g., 24 hours)
suspendedAdministratively suspended

Settings Structure:

{
  "multi_facility": true,
  "facility_count": 3,
  "max_patients_sync": 10000,
  "sync_priorities": ["patients", "encounters", "prescriptions"],
  "contact_email": "admin@hospital.com",
  "contact_phone": "+919876543210"
}

Indexes:

  • Unique: facility_code
  • Index: sync_status
  • Index: country_code

Entity: FacilitySyncCredentials

Purpose: Secure credentials for facility-to-cloud authentication

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
federated_facility_idUUIDYesFacility reference
api_key_hashStringYesHashed API key (bcrypt)
api_secret_hashStringYesHashed API secret (bcrypt)
public_keyTextNoRSA public key for signed payloads
issued_atTimestampYesCredential issuance date
expires_atTimestampNoCredential expiry
last_used_atTimestampNoLast successful auth
is_activeBooleanYesActive status
revoked_atTimestampNoWhen revoked
revoked_reasonStringNoRevocation reason
created_atTimestampYesRecord creation

Relationships:

  • Belongs to: FederatedFacility

Security Notes:

  • API keys stored as bcrypt hashes
  • Plain text keys only shown once at creation
  • RSA public key for payload signature verification
  • Automatic revocation on expiry

Patient Identity

Entity: MasterPatientIndex

Purpose: Global patient identity aggregation across all facilities

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier (MPI ID)
first_nameStringNoFirst name (normalized)
last_nameStringNoLast name (normalized)
date_of_birthDateNoDate of birth
genderEnumNomale, female, other, unknown
phone_hashStringNoSHA-256 hashed phone number
email_hashStringNoSHA-256 hashed email
abha_idStringNoIndia ABHA identifier
national_id_hashStringNoHashed Aadhaar/SSN
identity_confidenceDecimalNoOverall match confidence (0-1)
primary_facility_idUUIDNoPrimary care facility
facility_countIntegerNoNumber of facilities visited
first_seen_atTimestampNoFirst record date
last_activity_atTimestampNoMost recent activity
user_account_idUUIDNoLinked Kulcare user account
is_activeBooleanYesActive record
created_atTimestampYesMPI creation
updated_atTimestampYesLast update

Indexes:

  • Unique: abha_id (when not null)
  • Index: phone_hash
  • Index: email_hash
  • Index: (first_name, last_name, date_of_birth)
  • Index: user_account_id

Privacy Notes:

  • PHI stored in hashed form for matching
  • Full demographics come from FederatedClinicalData
  • User account linking enables patient portal access

Purpose: Links facility-local patient records to MPI

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
master_patient_idUUIDYesMPI reference
federated_facility_idUUIDYesFacility reference
facility_patient_idStringYesPatient ID at facility
facility_mrnStringNoMRN at facility
match_methodEnumYesexact, fuzzy, manual, abha
match_confidenceDecimalNoConfidence score (0-1)
verifiedBooleanNoManually verified link
verified_byUUIDNoVerifying user
verified_atTimestampNoVerification timestamp
is_activeBooleanYesActive link
created_atTimestampYesLink creation
updated_atTimestampYesLast update

Match Method Values:

MethodDescriptionAuto-Verified
exactDeterministic match (phone + DOB + name)Yes
fuzzyProbabilistic match (needs verification)No
manualHuman-verified matchYes
abhaMatched via India ABHA IDYes

Unique Constraint: (federated_facility_id, facility_patient_id)

Relationships:

  • Belongs to: MasterPatientIndex
  • Belongs to: FederatedFacility

Sync Tracking

Entity: InboundSyncRecord

Purpose: Track all incoming sync operations from on-premise facilities

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
federated_facility_idUUIDYesSource facility
sync_batch_idStringYesBatch identifier from source
operation_typeEnumYescreate, update, delete
resource_typeStringYesEntity type (patient, encounter, etc.)
facility_resource_idStringYesResource ID at facility
cloud_resource_idUUIDNoMapped ID in cloud (after processing)
payloadJSONBYesFull sync payload
payload_hashStringNoSHA-256 hash for deduplication
facility_timestampTimestampYesWhen created at facility
received_atTimestampYesWhen received by cloud
processed_atTimestampNoWhen processed
sync_statusEnumYesreceived, processing, synced, conflict, failed
conflict_typeEnumNoidentity_mismatch, data_conflict, validation_error
conflict_dataJSONBNoConflict details
error_messageTextNoError details
retry_countIntegerNoProcessing attempts
created_atTimestampYesRecord creation

Sync Status Values:

StatusDescription
receivedPayload received, queued for processing
processingCurrently being processed
syncedSuccessfully merged into cloud data
conflictConflict detected, needs resolution
failedProcessing failed after retries

Conflict Type Values:

TypeDescription
identity_mismatchPatient identity cannot be matched
data_conflictData conflicts with existing cloud data
validation_errorData fails validation rules

Indexes:

  • Index: (federated_facility_id, sync_batch_id)
  • Index: sync_status
  • Index: received_at

Relationships:

  • Belongs to: FederatedFacility

Entity: SyncConflictResolution

Purpose: Track conflict resolution decisions

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
inbound_sync_record_idUUIDYesSync record reference
conflict_typeEnumYesidentity_mismatch, data_conflict, version_conflict
source_dataJSONBNoData from on-premise
cloud_dataJSONBNoExisting cloud data
resolution_strategyEnumYessource_wins, cloud_wins, merged, manual
resolved_dataJSONBNoFinal resolved data
resolved_byUUIDNoResolving user
resolved_atTimestampNoResolution timestamp
auto_resolvedBooleanNoResolved automatically
resolution_notesTextNoHuman notes
created_atTimestampYesRecord creation

Resolution Strategy Values:

StrategyDescription
source_winsOn-premise data takes precedence
cloud_winsCloud data takes precedence
mergedData merged from both sources
manualManually resolved by admin

Relationships:

  • Belongs to: InboundSyncRecord

Clinical Data Aggregation

Entity: FederatedClinicalData

Purpose: Aggregated clinical data from all facilities for patient portal

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
master_patient_idUUIDYesMPI reference
federated_facility_idUUIDYesSource facility
data_typeEnumYesencounter, prescription, diagnosis, vitals, lab_result, imaging, procedure, document
facility_resource_idStringYesOriginal ID at facility
data_dateDateYesClinical event date
dataJSONBYesStructured clinical data
metadataJSONBNoAdditional metadata
practitioner_nameStringNoTreating practitioner
practitioner_specialtyStringNoSpecialty
facility_nameStringNoFacility display name
is_currentBooleanNoCurrent status (for ongoing conditions)
synced_atTimestampYesWhen synced to cloud
created_atTimestampYesRecord creation

Data Type Values:

TypeDescriptionFHIR Equivalent
encounterVisit/consultation recordsEncounter
prescriptionMedication ordersMedicationRequest
diagnosisConditions/diagnosesCondition
vitalsVital signsObservation
lab_resultLaboratory resultsDiagnosticReport
imagingImaging studiesImagingStudy
procedureProcedures performedProcedure
documentClinical documentsDocumentReference

Data Structure Examples:

Encounter:

{
  "encounter_type": "consultation",
  "encounter_date": "2025-12-29",
  "chief_complaint": "Fever, cough for 3 days",
  "notes": "Patient presents with...",
  "diagnoses": [
    { "code": "J06.9", "display": "Acute upper respiratory infection" }
  ]
}

Prescription:

{
  "medications": [
    {
      "drug_name": "Paracetamol 500mg",
      "dosage": "1 tablet",
      "frequency": "TID",
      "duration_days": 5
    }
  ],
  "prescribed_by": "Dr. Smith"
}

Vitals:

{
  "blood_pressure": { "systolic": 120, "diastolic": 80 },
  "pulse": 72,
  "temperature": 98.6,
  "spo2": 98,
  "weight_kg": 70,
  "height_cm": 175
}

Indexes:

  • Index: (master_patient_id, data_type, data_date)
  • Index: (federated_facility_id, facility_resource_id)
  • Index: synced_at

Relationships:

  • Belongs to: MasterPatientIndex
  • Belongs to: FederatedFacility

Entity: SyncDataProvenance

Purpose: Complete audit trail for data provenance

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
federated_clinical_data_idUUIDYesClinical data reference
federated_facility_idUUIDYesOrigin facility
facility_resource_typeStringYesOriginal table/type
facility_resource_idStringYesOriginal ID
original_created_atTimestampYesWhen created at facility
original_created_byStringNoCreator at facility
original_updated_atTimestampNoLast update at facility
sync_versionIntegerYesSync version number
synced_atTimestampYesWhen synced to cloud
inbound_sync_record_idUUIDNoSync record reference
created_atTimestampYesRecord creation

Relationships:

  • Belongs to: FederatedClinicalData
  • Belongs to: FederatedFacility
  • Optionally references: InboundSyncRecord

Feature Configuration

Entity: FeatureConfiguration

Purpose: Control feature availability per deployment mode

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
feature_keyStringYesFeature identifier (snake_case)
feature_nameStringYesDisplay name
feature_categoryEnumYescore, growth, connect, billing, integration, ai
descriptionTextNoFeature description
default_cloud_enabledBooleanYesDefault for cloud deployments
default_onpremise_enabledBooleanYesDefault for on-premise
requires_cloud_proxyBooleanNoNeeds cloud services when on-premise
cloud_proxy_endpointStringNoProxy endpoint for on-premise
created_atTimestampYesRecord creation
updated_atTimestampYesLast update

Feature Category Values:

CategoryDescription
coreCore CMS functionality
growthMarketing/growth features
connectProfessional networking
billingPayment processing
integrationExternal integrations
aiAI-powered features

Example Features:

feature_keycloudon_premiseproxy
patient_queuetruetruefalse
prescriptionstruetruefalse
online_bookingtruetruetrue
patient_portaltruetruetrue
sms_notificationstruefalsetrue
ai_scribetruefalsetrue
analytics_dashboardtruefalsetrue
payment_gatewaytruefalsefalse
growth_campaignstruefalsefalse

Unique Constraint: feature_key


Entity: FacilityFeatureOverride

Purpose: Facility-specific feature overrides

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
federated_facility_idUUIDYesFacility reference
feature_keyStringYesFeature reference
is_enabledBooleanYesOverride value
override_reasonStringNoReason for override
effective_fromDateNoOverride start date
effective_untilDateNoOverride end date
created_byUUIDNoAdmin user
created_atTimestampYesRecord creation
updated_atTimestampYesLast update

Unique Constraint: (federated_facility_id, feature_key)

Relationships:

  • Belongs to: FederatedFacility
  • References: FeatureConfiguration (via feature_key)

Appointment Booking

Entity: AppointmentSlots

Purpose: Available appointment slots synced from on-premise facilities

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
federated_facility_idUUIDYesSource facility
facility_slot_idStringYesSlot ID at facility
practitioner_nameStringYesPractitioner name
practitioner_specialtyStringNoSpecialty
slot_dateDateYesAppointment date
start_timeTimeYesStart time
end_timeTimeYesEnd time
duration_minutesIntegerNoSlot duration
slot_typeEnumNoconsultation, follow_up, procedure
is_availableBooleanYesCurrently available
booked_atTimestampNoWhen booked
synced_atTimestampYesLast sync
created_atTimestampYesRecord creation
updated_atTimestampYesLast update

Unique Constraint: (federated_facility_id, facility_slot_id)

Indexes:

  • Index: (federated_facility_id, slot_date, is_available)
  • Index: practitioner_name

Relationships:

  • Belongs to: FederatedFacility

Entity: AppointmentBookings

Purpose: Bookings made via patient portal (pending on-premise confirmation)

Attributes:

AttributeTypeRequiredDescription
idUUIDYesPrimary identifier
appointment_slot_idUUIDYesSlot reference
federated_facility_idUUIDYesTarget facility
master_patient_idUUIDYesPatient (MPI)
user_account_idUUIDNoBooking user account
booking_statusEnumYespending, confirmed, rejected, cancelled
rejection_reasonStringNoIf rejected
patient_nameStringYesPatient name
patient_phoneStringYesContact phone
patient_emailStringNoContact email
notesTextNoPatient notes
booked_atTimestampYesBooking timestamp
confirmed_atTimestampNoConfirmation timestamp
cancelled_atTimestampNoCancellation timestamp
pushed_to_facility_atTimestampNoWhen sent to on-premise
facility_response_atTimestampNoWhen facility responded
created_atTimestampYesRecord creation
updated_atTimestampYesLast update

Booking Status Values:

StatusDescription
pendingAwaiting on-premise confirmation
confirmedConfirmed by on-premise
rejectedRejected (slot unavailable)
cancelledCancelled by patient

Relationships:

  • Belongs to: AppointmentSlots
  • Belongs to: FederatedFacility
  • Belongs to: MasterPatientIndex

Schema Diagram

+-------------------------------------------------------------------------+
|  FEDERATION SCHEMA                                                       |
+-------------------------------------------------------------------------+
|                                                                         |
|  FACILITY REGISTRY                                                       |
|  +---------------------+    +------------------------+                   |
|  | federated_          |--->| facility_sync_         |                   |
|  | facilities          |    | credentials            |                   |
|  +---------------------+    +------------------------+                   |
|           |                                                              |
|           |                                                              |
|  PATIENT IDENTITY                                                        |
|  +---------------------+    +------------------------+                   |
|  | master_patient_     |<---| patient_identity_      |                   |
|  | index               |    | links                  |                   |
|  +---------------------+    +------------------------+                   |
|           |                          |                                   |
|           |                          |                                   |
|  CLINICAL DATA                       |                                   |
|  +---------------------+    +------------------------+                   |
|  | federated_          |--->| sync_data_             |                   |
|  | clinical_data       |    | provenance             |                   |
|  +---------------------+    +------------------------+                   |
|           ^                          ^                                   |
|           |                          |                                   |
|  SYNC TRACKING                       |                                   |
|  +---------------------+    +------------------------+                   |
|  | inbound_sync_       |--->| sync_conflict_         |                   |
|  | records             |    | resolutions            |                   |
|  +---------------------+    +------------------------+                   |
|                                                                         |
|  FEATURE CONFIGURATION                                                   |
|  +---------------------+    +------------------------+                   |
|  | feature_            |--->| facility_feature_      |                   |
|  | configurations      |    | overrides              |                   |
|  +---------------------+    +------------------------+                   |
|                                                                         |
|  APPOINTMENT BOOKING                                                     |
|  +---------------------+    +------------------------+                   |
|  | appointment_        |--->| appointment_           |                   |
|  | slots               |    | bookings               |                   |
|  +---------------------+    +------------------------+                   |
|                                                                         |
+-------------------------------------------------------------------------+

Entity Summary

EntityPurposeRecords Expected
FederatedFacilityOn-premise registryHundreds
FacilitySyncCredentialsSync auth1-2 per facility
MasterPatientIndexGlobal patient IDMillions
PatientIdentityLinkFacility-MPI linksMillions
InboundSyncRecordSync trackingMillions (pruned)
SyncConflictResolutionConflict auditThousands
FederatedClinicalDataClinical dataTens of millions
SyncDataProvenanceData provenanceTens of millions
FeatureConfigurationFeature matrix~50 features
FacilityFeatureOverrideOverridesHundreds
AppointmentSlotsAvailable slotsMillions
AppointmentBookingsPortal bookingsMillions

Total Tables: 12


Retention Policies

TableRetentionRationale
federated_facilitiesPermanentFacility registry
facility_sync_credentialsUntil revoked + 1 yearSecurity audit
master_patient_indexPermanentPatient identity
patient_identity_linksPermanentMatching history
inbound_sync_records90 daysOperational
sync_conflict_resolutions2 yearsAudit
federated_clinical_dataPer facility contractPatient data
sync_data_provenanceSame as clinical dataAudit
feature_configurationsPermanentConfiguration
facility_feature_overridesPermanentConfiguration
appointment_slots30 days past dateOperational
appointment_bookings2 yearsAudit

On this page