diff --git a/care/facility/admin.py b/care/facility/admin.py
index 945bbfab8a..ee73ef2139 100644
--- a/care/facility/admin.py
+++ b/care/facility/admin.py
@@ -11,7 +11,7 @@
 
 from .models import (
     Building,
-    Disease,
+    Diseases,
     Facility,
     FacilityCapacity,
     FacilityInventoryItem,
@@ -201,7 +201,7 @@ class FacilityUserAdmin(DjangoQLSearchMixin, admin.ModelAdmin, ExportCsvMixin):
 admin.site.register(PatientRegistration, PatientAdmin)
 admin.site.register(PatientTeleConsultation)
 admin.site.register(PatientSample, PatientSampleAdmin)
-admin.site.register(Disease)
+admin.site.register(Diseases)
 admin.site.register(FacilityInventoryUnit)
 admin.site.register(FacilityInventoryUnitConverter)
 admin.site.register(FacilityInventoryItem)
diff --git a/care/facility/api/serializers/medical_history.py b/care/facility/api/serializers/medical_history.py
new file mode 100644
index 0000000000..802e8cf0c6
--- /dev/null
+++ b/care/facility/api/serializers/medical_history.py
@@ -0,0 +1,79 @@
+from django.db import transaction
+from rest_framework import serializers
+
+from care.facility.models import MedicalHistory, PatientRegistration
+from care.facility.models.patient import Diseases
+from care.facility.models.patient_consultation import PatientConsultation
+from care.utils.serializer.external_id_field import ExternalIdSerializerField
+
+
+class DiseaseSerializer(serializers.ModelSerializer):
+    date = serializers.DateField()
+
+    class Meta:
+        model = Diseases
+        fields = (
+            "disease",
+            "details",
+            "date",
+            "precision",
+        )
+
+
+class MedicalHistorySerializer(serializers.ModelSerializer):
+    id = serializers.CharField(source="external_id", read_only=True)
+
+    patient = ExternalIdSerializerField(
+        queryset=PatientRegistration.objects.all(), required=False
+    )
+
+    consultation = ExternalIdSerializerField(
+        queryset=PatientConsultation.objects.all(), required=False
+    )
+
+    patient_diseases = serializers.ListSerializer(
+        child=DiseaseSerializer(),
+        required=False,
+    )
+
+    class Meta:
+        model = MedicalHistory
+        exclude = ("deleted", "external_id")
+
+    def create(self, validated_data):
+        with transaction.atomic():
+            consultation = validated_data["consultation"]
+            patient_diseases = validated_data.pop("patient_diseases", [])
+            medical_history = super().create(validated_data)
+            diseases = []
+            for disease in patient_diseases:
+                diseases.append(
+                    Diseases(
+                        medical_history=medical_history,
+                        **disease,
+                    )
+                )
+            if diseases:
+                Diseases.objects.bulk_create(diseases, ignore_conflicts=True)
+            consultation.last_medical_history = medical_history
+            consultation.save(update_fields=["last_medical_history"])
+            return medical_history
+
+    def update(self, instance, validated_data):
+        with transaction.atomic():
+            patient_diseases = validated_data.pop("patient_diseases", [])
+            medical_history = super().update(instance, validated_data)
+            Diseases.objects.filter(medical_history=medical_history).update(
+                deleted=True
+            )
+            diseases = []
+            for disease in patient_diseases:
+                diseases.append(
+                    Diseases(
+                        medical_history=medical_history,
+                        **disease,
+                    )
+                )
+            if diseases:
+                Diseases.objects.bulk_create(diseases, ignore_conflicts=True)
+            return medical_history
diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py
index da2be7bdaa..80b983f3bc 100644
--- a/care/facility/api/serializers/patient.py
+++ b/care/facility/api/serializers/patient.py
@@ -15,7 +15,7 @@
 from care.facility.models import (
     DISEASE_CHOICES,
     GENDER_CHOICES,
-    Disease,
+    Diseases,
     Facility,
     FacilityPatientStatsHistory,
     PatientContactDetails,
@@ -259,9 +259,9 @@ def create(self, validated_data):
             diseases = []
 
             for disease in medical_history:
-                diseases.append(Disease(patient=patient, **disease))
+                diseases.append(Diseases(patient=patient, **disease))
             if diseases:
-                Disease.objects.bulk_create(diseases, ignore_conflicts=True)
+                Diseases.objects.bulk_create(diseases, ignore_conflicts=True)
 
             if meta_info:
                 meta_info_obj = PatientMetaInfo.objects.create(**meta_info)
@@ -305,12 +305,12 @@ def update(self, instance, validated_data):
                     self.check_external_entry(validated_data["srf_id"])
 
             patient = super().update(instance, validated_data)
-            Disease.objects.filter(patient=patient).update(deleted=True)
+            Diseases.objects.filter(patient=patient).update(deleted=True)
             diseases = []
             for disease in medical_history:
-                diseases.append(Disease(patient=patient, **disease))
+                diseases.append(Diseases(patient=patient, **disease))
             if diseases:
-                Disease.objects.bulk_create(diseases, ignore_conflicts=True)
+                Diseases.objects.bulk_create(diseases, ignore_conflicts=True)
 
             if meta_info:
                 for key, value in meta_info.items():
diff --git a/care/facility/api/serializers/patient_consultation.py b/care/facility/api/serializers/patient_consultation.py
index 6bead9ea92..87bba3baa3 100644
--- a/care/facility/api/serializers/patient_consultation.py
+++ b/care/facility/api/serializers/patient_consultation.py
@@ -8,6 +8,7 @@
 from care.facility.api.serializers.bed import ConsultationBedSerializer
 from care.facility.api.serializers.daily_round import DailyRoundSerializer
 from care.facility.api.serializers.facility import FacilityBasicInfoSerializer
+from care.facility.api.serializers.medical_history import MedicalHistorySerializer
 from care.facility.api.serializers.patient_health_details import (
     PatientHealthDetailsSerializer,
 )
@@ -19,7 +20,7 @@
 )
 from care.facility.models.bed import Bed, ConsultationBed
 from care.facility.models.notification import Notification
-from care.facility.models.patient import PatientHealthDetails
+from care.facility.models.patient import MedicalHistory, PatientHealthDetails
 from care.facility.models.patient_base import (
     DISCHARGE_REASON_CHOICES,
     SYMPTOM_CHOICES,
@@ -39,9 +40,7 @@
 
 class PatientConsultationSerializer(serializers.ModelSerializer):
     id = serializers.CharField(source="external_id", read_only=True)
-    facility_name = serializers.CharField(
-        source="facility.name", read_only=True
-    )
+    facility_name = serializers.CharField(source="facility.name", read_only=True)
     suggestion_text = ChoiceField(
         choices=PatientConsultation.SUGGESTION_CHOICES,
         read_only=True,
@@ -60,14 +59,10 @@ class PatientConsultationSerializer(serializers.ModelSerializer):
     referred_to = ExternalIdSerializerField(
         queryset=Facility.objects.all(), required=False
     )
-    patient = ExternalIdSerializerField(
-        queryset=PatientRegistration.objects.all()
-    )
+    patient = ExternalIdSerializerField(queryset=PatientRegistration.objects.all())
     facility = ExternalIdSerializerField(read_only=True)
 
-    assigned_to_object = UserAssignedSerializer(
-        source="assigned_to", read_only=True
-    )
+    assigned_to_object = UserAssignedSerializer(source="assigned_to", read_only=True)
 
     assigned_to = serializers.PrimaryKeyRelatedField(
         queryset=User.objects.all(), required=False, allow_null=True
@@ -84,16 +79,13 @@ class PatientConsultationSerializer(serializers.ModelSerializer):
         required=False,
     )
 
-    review_time = serializers.IntegerField(
-        default=-1, write_only=True, required=False
-    )
+    review_time = serializers.IntegerField(default=-1, write_only=True, required=False)
 
     last_edited_by = UserBaseMinimumSerializer(read_only=True)
     created_by = UserBaseMinimumSerializer(read_only=True)
     last_daily_round = DailyRoundSerializer(read_only=True)
-    health_details = ExternalIdSerializerField(
+    last_health_details = ExternalIdSerializerField(
         queryset=PatientHealthDetails.objects.all(),
-        source="last_health_details",
         required=False,
     )
 
@@ -104,6 +96,18 @@ class PatientConsultationSerializer(serializers.ModelSerializer):
 
     new_health_details = PatientHealthDetailsSerializer(required=False)
 
+    last_medical_history = ExternalIdSerializerField(
+        queryset=MedicalHistory.objects.all(),
+        required=False,
+    )
+
+    medical_history_object = MedicalHistorySerializer(
+        source="last_medical_history",
+        read_only=True,
+    )
+
+    new_medical_history = MedicalHistorySerializer(required=False)
+
     current_bed = ConsultationBedSerializer(read_only=True)
 
     bed = ExternalIdSerializerField(queryset=Bed.objects.all(), required=False)
@@ -127,9 +131,7 @@ def get_icd11_diagnoses_objects_by_ids(self, diagnoses_ids):
         return diagnosis_objects
 
     def get_icd11_diagnoses_object(self, consultation):
-        return self.get_icd11_diagnoses_objects_by_ids(
-            consultation.icd11_diagnoses
-        )
+        return self.get_icd11_diagnoses_objects_by_ids(consultation.icd11_diagnoses)
 
     def get_icd11_provisional_diagnoses_object(self, consultation):
         return self.get_icd11_diagnoses_objects_by_ids(
@@ -145,7 +147,10 @@ class Meta:
             "created_by",
             "kasp_enabled_date",
         )
-        exclude = ("deleted", "external_id", "last_health_details")
+        exclude = (
+            "deleted",
+            "external_id",
+        )
 
     def validate_bed_number(self, bed_number):
         try:
@@ -160,11 +165,7 @@ def update(self, instance, validated_data):
 
         if instance.discharge_date:
             raise ValidationError(
-                {
-                    "consultation": [
-                        "Discharged Consultation data cannot be updated"
-                    ]
-                }
+                {"consultation": ["Discharged Consultation data cannot be updated"]}
             )
 
         if instance.suggestion == SuggestionChoices.OP:
@@ -196,6 +197,7 @@ def update(self, instance, validated_data):
 
         _temp = instance.assigned_to
         health_details_data = validated_data.pop("new_health_details", None)
+        medical_history_data = validated_data.pop("new_medical_history", None)
 
         consultation = super().update(instance, validated_data)
 
@@ -204,7 +206,7 @@ def update(self, instance, validated_data):
                 consultation=consultation
             )
 
-            serializer = PatientHealthDetailsSerializer(
+            health_details_serializer = PatientHealthDetailsSerializer(
                 last_health_details_object,
                 data={
                     "patient": consultation.patient.external_id.hex,
@@ -216,17 +218,32 @@ def update(self, instance, validated_data):
                     "request": self.context["request"],
                 },
             )
-            serializer.is_valid(raise_exception=True)
-            serializer.save()
+            health_details_serializer.is_valid(raise_exception=True)
+            health_details_serializer.save()
+
+            last_medical_history_object = MedicalHistory.objects.get(
+                consultation=consultation
+            )
+
+            medical_history_serializer = MedicalHistorySerializer(
+                last_medical_history_object,
+                data={
+                    "patient": consultation.patient.external_id.hex,
+                    "consultation": consultation.external_id.hex,
+                    **medical_history_data,
+                },
+                context={
+                    "request": self.context["request"],
+                },
+            )
+            medical_history_serializer.is_valid(raise_exception=True)
+            medical_history_serializer.save()
 
         except KeyError:
             pass
 
         if "assigned_to" in validated_data:
-            if (
-                validated_data["assigned_to"] != _temp
-                and validated_data["assigned_to"]
-            ):
+            if validated_data["assigned_to"] != _temp and validated_data["assigned_to"]:
                 NotificationGenerator(
                     event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT,
                     caused_by=self.context["request"].user,
@@ -258,16 +275,12 @@ def create(self, validated_data):
 
         # Authorisation Check
 
-        allowed_facilities = get_home_facility_queryset(
-            self.context["request"].user
-        )
+        allowed_facilities = get_home_facility_queryset(self.context["request"].user)
         if not allowed_facilities.filter(
             id=self.validated_data["patient"].facility.id
         ).exists():
             raise ValidationError(
-                {
-                    "facility": "Consultation creates are only allowed in home facility"
-                }
+                {"facility": "Consultation creates are only allowed in home facility"}
             )
 
         # End Authorisation Checks
@@ -286,9 +299,7 @@ def create(self, validated_data):
         if validated_data["patient"].last_consultation:
             if not validated_data["patient"].last_consultation.discharge_date:
                 raise ValidationError(
-                    {
-                        "consultation": "Exists please Edit Existing Consultation"
-                    }
+                    {"consultation": "Exists please Edit Existing Consultation"}
                 )
 
         if "is_kasp" in validated_data:
@@ -296,8 +307,9 @@ def create(self, validated_data):
                 validated_data["kasp_enabled_date"] = localtime(now())
 
         bed = validated_data.pop("bed", None)
-        health_details_data = validated_data.pop("new_health_details", None)
-
+        print(validated_data)
+        health_details_data = validated_data.pop("new_health_details", [])
+        medical_history_data = validated_data.pop("new_medical_history", [])
         validated_data["facility_id"] = validated_data[
             "patient"
         ].facility_id  # Coercing facility as the patient's facility
@@ -307,7 +319,7 @@ def create(self, validated_data):
         consultation.save()
 
         try:
-            serializer = PatientHealthDetailsSerializer(
+            health_details_serializer = PatientHealthDetailsSerializer(
                 data={
                     "patient": consultation.patient.external_id.hex,
                     "facility": consultation.facility.external_id.hex,
@@ -318,9 +330,20 @@ def create(self, validated_data):
                     "request": self.context["request"],
                 },
             )
-            serializer.is_valid(raise_exception=True)
-            health_details = serializer.save()
-            consultation.health_details = health_details.external_id.hex
+            health_details_serializer.is_valid(raise_exception=True)
+            health_details = health_details_serializer.save()
+            consultation.last_health_details = health_details
+
+            medical_history_serializer = MedicalHistorySerializer(
+                data={
+                    "patient": consultation.patient.external_id.hex,
+                    "consultation": consultation.external_id.hex,
+                    **medical_history_data,
+                }
+            )
+            medical_history_serializer.is_valid(raise_exception=True)
+            medical_history = medical_history_serializer.save()
+            consultation.last_medical_history = medical_history
 
         except KeyError as error:
             if consultation.patient.last_consultation is None:
@@ -328,14 +351,24 @@ def create(self, validated_data):
                     {
                         "health_details": [
                             "Please provide the health details of the patient"
+                        ],
+                    },
+                    {
+                        "medical_history": [
+                            "Please provide the medical history of the patient"
                         ]
-                    }
+                    },
                 ) from error
 
             consultation.last_health_details = (
                 consultation.patient.last_consultation.last_health_details
             )
-            consultation.save(update_fields=["last_health_details"])
+            consultation.last_medical_history = (
+                consultation.patient.last_consultation.last_medical_history
+            )
+            consultation.save(
+                update_fields=["last_health_details", "last_medical_history"]
+            )
 
         if bed:
             consultation_bed = ConsultationBed(
@@ -360,9 +393,7 @@ def create(self, validated_data):
         if action != -1:
             patient.action = action
         if review_time > 0:
-            patient.review_time = localtime(now()) + timedelta(
-                minutes=review_time
-            )
+            patient.review_time = localtime(now()) + timedelta(minutes=review_time)
 
         patient.save()
         NotificationGenerator(
@@ -391,9 +422,9 @@ def validate(self, attrs):
         # TODO Add Bed Authorisation Validation
 
         if "suggestion" in validated:
-            if validated[
-                "suggestion"
-            ] is SuggestionChoices.R and not validated.get("referred_to"):
+            if validated["suggestion"] is SuggestionChoices.R and not validated.get(
+                "referred_to"
+            ):
                 raise ValidationError(
                     {
                         "referred_to": [
@@ -426,11 +457,7 @@ def validate(self, attrs):
                     )
                 if validated["review_time"] <= 0:
                     raise ValidationError(
-                        {
-                            "review_time": [
-                                "This field value is must be greater than 0."
-                            ]
-                        }
+                        {"review_time": ["This field value is must be greater than 0."]}
                     )
         from care.facility.static_data.icd11 import ICDDiseases
 
@@ -464,12 +491,8 @@ def validate(self, attrs):
 
 
 class PatientConsultationIDSerializer(serializers.ModelSerializer):
-    consultation_id = serializers.UUIDField(
-        source="external_id", read_only=True
-    )
-    patient_id = serializers.UUIDField(
-        source="patient.external_id", read_only=True
-    )
+    consultation_id = serializers.UUIDField(source="external_id", read_only=True)
+    patient_id = serializers.UUIDField(source="patient.external_id", read_only=True)
 
     class Meta:
         model = PatientConsultation
diff --git a/care/facility/api/serializers/patient_health_details.py b/care/facility/api/serializers/patient_health_details.py
index c8fdd7534a..360bc00eea 100644
--- a/care/facility/api/serializers/patient_health_details.py
+++ b/care/facility/api/serializers/patient_health_details.py
@@ -1,3 +1,4 @@
+from django.db import transaction
 from django.forms import ChoiceField
 from rest_framework import serializers
 
@@ -7,11 +8,22 @@
     PatientRegistration,
 )
 from care.facility.models.facility import Facility
-from care.facility.models.patient_base import BLOOD_GROUP_CHOICES
+from care.facility.models.patient import VaccinationHistory
+from care.facility.models.patient_base import BLOOD_GROUP_CHOICES, VACCINE_CHOICES
 from care.utils.queryset.facility import get_home_facility_queryset
 from care.utils.serializer.external_id_field import ExternalIdSerializerField
 
 
+class VaccinationHistorySerializer(serializers.ModelSerializer):
+    vaccine = serializers.ChoiceField(choices=VACCINE_CHOICES)
+    doses = serializers.IntegerField(required=False, default=0)
+    date = serializers.DateField()
+
+    class Meta:
+        model = VaccinationHistory
+        fields = ("vaccine", "doses", "date", "precision")
+
+
 class PatientHealthDetailsSerializer(serializers.ModelSerializer):
 
     id = serializers.CharField(source="external_id", read_only=True)
@@ -27,30 +39,60 @@ class PatientHealthDetailsSerializer(serializers.ModelSerializer):
     )
     blood_group = ChoiceField(choices=BLOOD_GROUP_CHOICES, required=True)
 
+    vaccination_history = serializers.ListSerializer(
+        child=VaccinationHistorySerializer(), required=False
+    )
+
     class Meta:
         model = PatientHealthDetails
         exclude = ("deleted", "external_id")
 
     def create(self, validated_data):
-        consultation = validated_data["consultation"]
-        allowed_facilities = get_home_facility_queryset(self.context["request"].user)
-        if not allowed_facilities.filter(
-            id=self.validated_data["patient"].facility.id
-        ).exists():
-            raise serializers.ValidationError(
-                {
-                    "patient": "Patient Health Details creates are only allowed in home facility"
-                }
+        with transaction.atomic():
+            consultation = validated_data["consultation"]
+            vaccination_history = validated_data.pop("vaccination_history", [])
+            allowed_facilities = get_home_facility_queryset(
+                self.context["request"].user
             )
+            if not allowed_facilities.filter(
+                id=self.validated_data["patient"].facility.id
+            ).exists():
+                raise serializers.ValidationError(
+                    {
+                        "patient": "Patient Health Details creates are only allowed in home facility"
+                    }
+                )
 
-        health_details = super().create(validated_data)
-        consultation.last_health_details = health_details
-        consultation.save(update_fields=["last_health_details"])
-        return health_details
+            health_details = super().create(validated_data)
+            vaccines = []
+            for vaccine in vaccination_history:
+                vaccines.append(
+                    VaccinationHistory(
+                        health_details=consultation.last_health_details,
+                        **vaccine,
+                    )
+                )
+            if vaccines:
+                VaccinationHistory.objects.bulk_create(vaccines, ignore_conflicts=True)
+            consultation.last_health_details = health_details
+            consultation.save(update_fields=["last_health_details"])
+            return health_details
 
     def update(self, instance, validated_data):
-        consultation = validated_data["consultation"]
-        health_details = super().update(instance, validated_data)
-        consultation.last_health_details = health_details
-        consultation.save(update_fields=["last_health_details"])
-        return health_details
+        with transaction.atomic():
+            vaccination_history = validated_data.pop("vaccination_history", [])
+            health_details = super().update(instance, validated_data)
+            VaccinationHistory.objects.filter(health_details=health_details).update(
+                deleted=True
+            )
+            vaccines = []
+            for vaccine in vaccination_history:
+                vaccines.append(
+                    VaccinationHistory(
+                        health_details=health_details,
+                        **vaccine,
+                    )
+                )
+            if vaccines:
+                VaccinationHistory.objects.bulk_create(vaccines, ignore_conflicts=True)
+            return health_details
diff --git a/care/facility/migrations/0322_patienthealthdetails.py b/care/facility/migrations/0322_patienthealthdetails.py
index 8667516ab0..afaf8f7fc2 100644
--- a/care/facility/migrations/0322_patienthealthdetails.py
+++ b/care/facility/migrations/0322_patienthealthdetails.py
@@ -2,12 +2,12 @@
 from django.db import migrations, models
 import django.db.models.deletion
 import django.core.validators
+import partial_index
 import care.facility.models.mixins.permissions.patient
-import django.contrib.postgres.fields.jsonb
 import care.utils.models.validators
 
 
-def populate_data(apps, schema_editor):
+def create_health_details(apps, schema_editor):
     health_details = apps.get_model("facility", "PatientHealthDetails")
     patient_registration = apps.get_model("facility", "PatientRegistration")
     patients = patient_registration.objects.all()
@@ -47,13 +47,6 @@ def populate_data(apps, schema_editor):
             has_allergy=has_allergy,
             allergies=allergies,
             blood_group=blood_group,
-            vaccination_history=[
-                {
-                    "vaccine": patient.vaccine_name,
-                    "doses": patient.number_of_doses,
-                    "last_vaccinated_date": patient.last_vaccinated_date,
-                }
-            ],
         )
 
         health_details_objs.append(health_details_obj)
@@ -73,6 +66,30 @@ def link_data(apps, schema_editor):
         patient_cons.save(update_fields=["last_health_details"])
 
 
+def create_vaccination_history(apps, schema_editor):
+    vaccination_history = apps.get_model("facility", "VaccinationHistory")
+    patient_registration = apps.get_model("facility", "PatientRegistration")
+    patients = patient_registration.objects.all()
+
+    vaccine_objs = []
+    for patient in patients:
+        if (
+            patient.vaccine_name
+            and patient.last_consultation.last_health_details
+        ):
+            vaccine_objs.append(
+                vaccination_history(
+                    health_details=patient.last_consultation.last_health_details,
+                    vaccine=patient.vaccine_name,
+                    doses=patient.number_of_doses,
+                    date=patient.last_vaccinated_date,
+                    precision=0,
+                )
+            )
+
+    vaccination_history.objects.bulk_create(vaccine_objs)
+
+
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -196,41 +213,6 @@ class Migration(migrations.Migration):
                         verbose_name="Patient's Height in CM",
                     ),
                 ),
-                (
-                    "vaccination_history",
-                    django.contrib.postgres.fields.jsonb.JSONField(
-                        default=list,
-                        validators=[
-                            care.utils.models.validators.JSONFieldSchemaValidator(
-                                {
-                                    "$schema": "http://json-schema.org/draft-07/schema#",
-                                    "items": [
-                                        {
-                                            "additionalProperties": False,
-                                            "properties": {
-                                                "doses": {
-                                                    "default": 0,
-                                                    "type": "number",
-                                                },
-                                                "last_vaccinated_date": {
-                                                    "type": "string"
-                                                },
-                                                "vaccine": {"type": "string"},
-                                            },
-                                            "required": [
-                                                "vaccine",
-                                                "doses",
-                                                "last_vaccinated_date",
-                                            ],
-                                            "type": "object",
-                                        }
-                                    ],
-                                    "type": "array",
-                                }
-                            )
-                        ],
-                    ),
-                ),
             ],
             options={
                 "abstract": False,
@@ -240,6 +222,33 @@ class Migration(migrations.Migration):
                 care.facility.models.mixins.permissions.patient.PatientRelatedPermissionMixin,
             ),
         ),
+        migrations.CreateModel(
+            name="VaccinationHistory",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("vaccine", models.CharField(max_length=100)),
+                ("doses", models.IntegerField(default=0)),
+                ("date", models.DateField(blank=True, null=True)),
+                ("precision", models.IntegerField(default=0)),
+                ("deleted", models.BooleanField(default=False)),
+                (
+                    "health_details",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="vaccination_history",
+                        to="facility.PatientHealthDetails",
+                    ),
+                ),
+            ],
+        ),
         migrations.AddField(
             model_name="patientconsultation",
             name="last_health_details",
@@ -250,6 +259,18 @@ class Migration(migrations.Migration):
                 to="facility.PatientHealthDetails",
             ),
         ),
-        migrations.RunPython(populate_data, migrations.RunPython.noop),
+        migrations.AddIndex(
+            model_name="vaccinationhistory",
+            index=partial_index.PartialIndex(
+                fields=["health_details", "vaccine"],
+                name="facility_va_health__5bb62d_partial",
+                unique=True,
+                where=partial_index.PQ(deleted=False),
+            ),
+        ),
+        migrations.RunPython(create_health_details, migrations.RunPython.noop),
         migrations.RunPython(link_data, migrations.RunPython.noop),
+        migrations.RunPython(
+            create_vaccination_history, migrations.RunPython.noop
+        ),
     ]
diff --git a/care/facility/migrations/0324_auto_20221014_1535.py b/care/facility/migrations/0324_auto_20221014_1535.py
new file mode 100644
index 0000000000..658d3736cc
--- /dev/null
+++ b/care/facility/migrations/0324_auto_20221014_1535.py
@@ -0,0 +1,187 @@
+# Generated by Django 2.2.11 on 2022-10-14 10:05
+
+import datetime
+from django.db import migrations, models
+import django.db.models.deletion
+import partial_index
+import uuid
+import care.facility.models.mixins.permissions.patient
+from care.facility.models.patient_base import DISEASE_CHOICES
+
+
+def create_medical_history(apps, schema_editor):
+    patient_registration = apps.get_model("facility", "PatientRegistration")
+    patients = patient_registration.objects.all()
+
+    medical_history = apps.get_model("facility", "MedicalHistory")
+    medical_history_objs = []
+    for patient in patients:
+        medical_history_objs.append(
+            medical_history(
+                patient=patient,
+                ongoing_medication=patient.ongoing_medication,
+                present_health=patient.present_health,
+            )
+        )
+
+    medical_history.objects.bulk_create(medical_history_objs)
+
+
+def link_data(apps, schema_editor):
+    patient_consultation = apps.get_model("facility", "PatientConsultation")
+    medical_history = apps.get_model("facility", "MedicalHistory")
+    patient_cons_objs = patient_consultation.objects.all()
+
+    for patient_cons in patient_cons_objs:
+        patient_cons.last_medical_history = medical_history.objects.get(
+            id=patient_cons.patient.id
+        )
+        patient_cons.save(update_fields=["last_medical_history"])
+
+
+def create_disease_history(apps, schema_editor):
+    disease_history = apps.get_model("facility", "Diseases")
+    disease_model = apps.get_model("facility", "Disease")
+    diseases = disease_model.objects.filter(deleted=False)
+
+    disease_objs = []
+    for disease in diseases:
+        disease_objs.append(
+            disease_history(
+                patient=disease.patient,
+                disease=DISEASE_CHOICES[disease.disease],
+                details=disease.details,
+                date=datetime.date.today(),
+            )
+        )
+
+    disease_history.objects.bulk_create(disease_objs)
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("facility", "0323_merge_20221005_1742"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="MedicalHistory",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "external_id",
+                    models.UUIDField(
+                        db_index=True, default=uuid.uuid4, unique=True
+                    ),
+                ),
+                (
+                    "created_date",
+                    models.DateTimeField(
+                        auto_now_add=True, db_index=True, null=True
+                    ),
+                ),
+                (
+                    "modified_date",
+                    models.DateTimeField(
+                        auto_now=True, db_index=True, null=True
+                    ),
+                ),
+                ("deleted", models.BooleanField(db_index=True, default=False)),
+                (
+                    "ongoing_medication",
+                    models.TextField(
+                        blank=True,
+                        default="",
+                        verbose_name="Already pescribed medication if any",
+                    ),
+                ),
+                (
+                    "present_health",
+                    models.TextField(
+                        blank=True,
+                        default="",
+                        verbose_name="Patient's Current Health Details",
+                    ),
+                ),
+                (
+                    "patient",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="facility.PatientRegistration",
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+            bases=(
+                models.Model,
+                care.facility.models.mixins.permissions.patient.PatientRelatedPermissionMixin,
+            ),
+        ),
+        migrations.CreateModel(
+            name="Diseases",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("disease", models.CharField(max_length=100)),
+                ("details", models.TextField(blank=True, null=True)),
+                ("date", models.DateField(blank=True, null=True)),
+                ("precision", models.IntegerField(default=0)),
+                ("deleted", models.BooleanField(default=False)),
+                (
+                    "medical_history",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="patient_diseases",
+                        to="facility.MedicalHistory",
+                    ),
+                ),
+            ],
+        ),
+        migrations.AddField(
+            model_name="patientconsultation",
+            name="last_medical_history",
+            field=models.ForeignKey(
+                default=None,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                to="facility.MedicalHistory",
+            ),
+        ),
+        migrations.RunPython(
+            create_medical_history, migrations.RunPython.noop
+        ),
+        migrations.RunPython(link_data, migrations.RunPython.noop),
+        migrations.RunPython(
+            create_disease_history, migrations.RunPython.noop
+        ),
+        migrations.DeleteModel(
+            name="Disease",
+        ),
+        migrations.AddIndex(
+            model_name="diseases",
+            index=partial_index.PartialIndex(
+                fields=["medical_history", "disease"],
+                name="facility_di_medical_1af9d2_partial",
+                unique=True,
+                where=partial_index.PQ(deleted=False),
+            ),
+        ),
+    ]
diff --git a/care/facility/migrations/0325_medicalhistory_consultation.py b/care/facility/migrations/0325_medicalhistory_consultation.py
new file mode 100644
index 0000000000..cb7e413668
--- /dev/null
+++ b/care/facility/migrations/0325_medicalhistory_consultation.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.2.11 on 2022-10-18 04:05
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('facility', '0324_auto_20221014_1535'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='medicalhistory',
+            name='consultation',
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='facility.PatientConsultation'),
+        ),
+    ]
diff --git a/care/facility/models/json_schema/consultation.py b/care/facility/models/json_schema/consultation.py
index 812e252956..91e68402c2 100644
--- a/care/facility/models/json_schema/consultation.py
+++ b/care/facility/models/json_schema/consultation.py
@@ -17,24 +17,3 @@
         }
     ],
 }
-
-VACCINATION = {
-    "$schema": "http://json-schema.org/draft-07/schema#",
-    "type": "array",
-    "items": [
-        {
-            "type": "object",
-            "properties": {
-                "vaccine": {"type": "string"},
-                "doses": {"type": "number", "default": 0},
-                "last_vaccinated_date": {"type": "string"},
-            },
-            "additionalProperties": False,
-            "required": [
-                "vaccine",
-                "doses",
-                "last_vaccinated_date",
-            ],
-        }
-    ],
-}
diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py
index 26e9398004..cd0772a6e0 100644
--- a/care/facility/models/patient.py
+++ b/care/facility/models/patient.py
@@ -1,7 +1,6 @@
 import datetime
 import enum
 
-from django.contrib.postgres.fields import JSONField as JsonField
 from django.core.validators import MaxValueValidator, MinValueValidator
 from django.db import models
 from fernet_fields import EncryptedCharField, EncryptedIntegerField
@@ -9,7 +8,6 @@
 from simple_history.models import HistoricalRecords
 
 from care.facility.models import (
-    DISEASE_CHOICES,
     DiseaseStatusEnum,
     District,
     Facility,
@@ -20,7 +18,6 @@
     Ward,
     pretty_boolean,
 )
-from care.facility.models.json_schema.consultation import VACCINATION
 from care.facility.models.mixins.permissions.facility import (
     FacilityRelatedPermissionMixin,
 )
@@ -47,7 +44,6 @@
 )
 from care.utils.models.base import BaseManager, BaseModel
 from care.utils.models.jsonfield import JSONField
-from care.utils.models.validators import JSONFieldSchemaValidator
 
 
 class PatientRegistration(PatientBaseModel, PatientPermissionMixin):
@@ -187,13 +183,13 @@ class TestTypeEnum(enum.Enum):
         default="",
         blank=True,
         verbose_name="Patient's Current Health Details",
-    )
+    )  # deprecated
 
     ongoing_medication = models.TextField(
         default="",
         blank=True,
         verbose_name="Already pescribed medication if any",
-    )
+    )  # deprecated
 
     has_SARI = models.BooleanField(
         default=False, verbose_name="Does the Patient Suffer from SARI"
@@ -549,12 +545,12 @@ def save(self, *args, **kwargs) -> None:
         "countries_travelled": "Countries Patient has Travelled to",
         "date_of_return": "Return Date from the Last Country if Travelled",
         "is_migrant_worker": "Is the Patient a Migrant Worker",
-        "present_health": "Patient's Current Health Details",
-        "ongoing_medication": "Already pescribed medication if any",
         "has_SARI": "Does the Patient Suffer from SARI",
         "date_of_receipt_of_information": "Patient's information received date",
         "will_donate_blood": "Will Patient Donate Blood?",
         "fit_for_blood_donation": "Is Patient Fit for Blood Donation?",
+        # "present_health": "Patient's Current Health Details",
+        # "ongoing_medication": "Already pescribed medication if any",
         "date_of_test": "Date of Sample Test",
         "srf_id": "SRF Test Id",
         # IDSP Data
@@ -726,34 +722,6 @@ class ModeOfContactEnum(enum.IntEnum):
     objects = BaseManager()
 
 
-class Disease(models.Model):
-    patient = models.ForeignKey(
-        PatientRegistration,
-        on_delete=models.CASCADE,
-        related_name="medical_history",
-    )
-    disease = models.IntegerField(choices=DISEASE_CHOICES)
-    details = models.TextField(blank=True, null=True)
-    deleted = models.BooleanField(default=False)
-
-    objects = BaseManager()
-
-    class Meta:
-        indexes = [
-            PartialIndex(
-                fields=["patient", "disease"],
-                unique=True,
-                where=PQ(deleted=False),
-            )
-        ]
-
-    def __str__(self):
-        return self.patient.name + " - " + self.get_disease_display()
-
-    def get_disease_display(self):
-        return DISEASE_CHOICES[self.disease - 1][1]
-
-
 class FacilityPatientStatsHistory(FacilityBaseModel, FacilityRelatedPermissionMixin):
     facility = models.ForeignKey("Facility", on_delete=models.PROTECT)
     entry_date = models.DateField()
@@ -812,6 +780,12 @@ class PatientHealthDetails(PatientBaseModel, PatientRelatedPermissionMixin):
         Facility, on_delete=models.CASCADE, related_name="health_details"
     )
 
+    consultation = models.ForeignKey(
+        PatientConsultation,
+        on_delete=models.CASCADE,
+        null=True,
+    )
+
     family_details = models.TextField(
         default="", blank=True, verbose_name="Patient's Family Details"
     )
@@ -829,16 +803,6 @@ class PatientHealthDetails(PatientBaseModel, PatientRelatedPermissionMixin):
         verbose_name="Blood Group of Patient",
     )
 
-    consultation = models.ForeignKey(
-        PatientConsultation,
-        on_delete=models.CASCADE,
-        null=True,
-    )
-
-    vaccination_history = JsonField(
-        default=dict, validators=[JSONFieldSchemaValidator(VACCINATION)]
-    )
-
     height = models.FloatField(
         default=None,
         null=True,
@@ -852,3 +816,82 @@ class PatientHealthDetails(PatientBaseModel, PatientRelatedPermissionMixin):
         verbose_name="Patient's Weight in KG",
         validators=[MinValueValidator(0)],
     )
+
+
+class VaccinationHistory(models.Model):
+    health_details = models.ForeignKey(
+        PatientHealthDetails,
+        on_delete=models.CASCADE,
+        related_name="vaccination_history",
+    )
+    vaccine = models.CharField(max_length=100)
+    doses = models.IntegerField(default=0)
+    date = models.DateField(null=True, blank=True)
+    precision = models.IntegerField(default=0)
+
+    deleted = models.BooleanField(default=False)
+    objects = BaseManager()
+
+    class Meta:
+        indexes = [
+            PartialIndex(
+                fields=["health_details", "vaccine"],
+                unique=True,
+                where=PQ(deleted=False),
+            )
+        ]
+
+    def __str__(self):
+        return self.vaccine + " " + self.doses
+
+
+class MedicalHistory(PatientBaseModel, PatientRelatedPermissionMixin):
+    patient = models.ForeignKey(
+        PatientRegistration,
+        on_delete=models.CASCADE,
+    )
+
+    consultation = models.ForeignKey(
+        PatientConsultation,
+        on_delete=models.CASCADE,
+        null=True,
+    )
+
+    ongoing_medication = models.TextField(
+        default="",
+        blank=True,
+        verbose_name="Already pescribed medication if any",
+    )
+
+    present_health = models.TextField(
+        default="",
+        blank=True,
+        verbose_name="Patient's Current Health Details",
+    )
+
+
+class Diseases(models.Model):
+    medical_history = models.ForeignKey(
+        MedicalHistory,
+        on_delete=models.CASCADE,
+        related_name="patient_diseases",
+    )
+    disease = models.CharField(max_length=100)
+    details = models.TextField(null=True, blank=True)
+    date = models.DateField(null=True, blank=True)
+    precision = models.IntegerField(default=0)
+
+    deleted = models.BooleanField(default=False)
+    objects = BaseManager()
+
+    class Meta:
+        indexes = [
+            PartialIndex(
+                fields=["medical_history", "disease"],
+                unique=True,
+                where=PQ(deleted=False),
+            )
+        ]
+
+    def __str__(self):
+        return self.patient.name + " " + self.disease
diff --git a/care/facility/models/patient_consultation.py b/care/facility/models/patient_consultation.py
index b2dae4df96..ec17b7786f 100644
--- a/care/facility/models/patient_consultation.py
+++ b/care/facility/models/patient_consultation.py
@@ -143,6 +143,14 @@ class PatientConsultation(PatientBaseModel, PatientRelatedPermissionMixin):
         null=True,
         default=None,
     )
+
+    last_medical_history = models.ForeignKey(
+        "MedicalHistory",
+        on_delete=models.SET_NULL,
+        null=True,
+        default=None,
+    )
+
     # Physical Information
 
     height = models.FloatField(
diff --git a/care/facility/tasks/patient/discharge_report.py b/care/facility/tasks/patient/discharge_report.py
index 0000760c8b..8ca3149532 100644
--- a/care/facility/tasks/patient/discharge_report.py
+++ b/care/facility/tasks/patient/discharge_report.py
@@ -1,5 +1,4 @@
 import datetime
-import logging
 import random
 import string
 import time
@@ -14,12 +13,12 @@
 
 from care.facility.models import (
     DailyRound,
+    Diseases,
+    DiseaseStatusEnum,
+    InvestigationValue,
     PatientConsultation,
     PatientRegistration,
     PatientSample,
-    Disease,
-    InvestigationValue,
-    DiseaseStatusEnum,
 )
 
 
@@ -34,7 +33,7 @@ def generate_discharge_report(patient_id, email):
     consultations = PatientConsultation.objects.filter(patient=patient).order_by(
         "-created_date"
     )
-    diseases = Disease.objects.filter(patient=patient)
+    diseases = Diseases.objects.filter(patient=patient)
     if consultations.exists():
         consultation = consultations.first()
         samples = PatientSample.objects.filter(
diff --git a/care/utils/tests/test_base.py b/care/utils/tests/test_base.py
index bc160026b1..276b9d2323 100644
--- a/care/utils/tests/test_base.py
+++ b/care/utils/tests/test_base.py
@@ -14,7 +14,7 @@
     COVID_CATEGORY_CHOICES,
     DISEASE_CHOICES_MAP,
     SYMPTOM_CHOICES,
-    Disease,
+    Diseases,
     DiseaseStatusEnum,
     Facility,
     LocalBody,
@@ -109,7 +109,7 @@ def create_patient(cls, **kwargs):
 
         patient = PatientRegistration.objects.create(**patient_data)
         diseases = [
-            Disease.objects.create(
+            Diseases.objects.create(
                 patient=patient,
                 disease=DISEASE_CHOICES_MAP[mh["disease"]],
                 details=mh["details"],
@@ -325,7 +325,10 @@ def get_district_representation(self, district: District):
     def get_state_representation(self, state: State):
         if state is None:
             return {"state": None, "state_object": None}
-        return {"state": state.id, "state_object": {"id": state.id, "name": state.name}}
+        return {
+            "state": state.id,
+            "state_object": {"id": state.id, "name": state.name},
+        }
 
     def _convert_to_matchable_types(self, d):
         def dict_to_matching_type(d: dict):