Spaces:
Sleeping
Sleeping
teest
Browse files- models/entities.py +8 -57
- routes/patients.py +49 -170
models/entities.py
CHANGED
|
@@ -3,78 +3,36 @@ from typing import List, Optional
|
|
| 3 |
from datetime import datetime
|
| 4 |
|
| 5 |
class Condition(BaseModel):
|
| 6 |
-
id:
|
| 7 |
code: str
|
| 8 |
status: Optional[str] = ""
|
| 9 |
onset_date: Optional[str] = None
|
| 10 |
recorded_date: Optional[str] = None
|
| 11 |
verification_status: Optional[str] = ""
|
| 12 |
-
category: Optional[str] = ""
|
| 13 |
|
| 14 |
class Medication(BaseModel):
|
| 15 |
-
id:
|
| 16 |
name: str
|
| 17 |
status: str
|
| 18 |
prescribed_date: Optional[str] = None
|
| 19 |
requester: Optional[str] = ""
|
| 20 |
dosage: Optional[str] = ""
|
| 21 |
-
intent: Optional[str] = ""
|
| 22 |
-
priority: Optional[str] = ""
|
| 23 |
|
| 24 |
class Encounter(BaseModel):
|
| 25 |
-
id:
|
| 26 |
type: str
|
| 27 |
status: str
|
| 28 |
-
period:
|
| 29 |
service_provider: Optional[str] = ""
|
| 30 |
-
class_type: Optional[str] = ""
|
| 31 |
-
reason: Optional[str] = ""
|
| 32 |
-
|
| 33 |
-
class Observation(BaseModel):
|
| 34 |
-
id: Optional[str] = None
|
| 35 |
-
code: str
|
| 36 |
-
value: Optional[str] = ""
|
| 37 |
-
unit: Optional[str] = ""
|
| 38 |
-
status: Optional[str] = ""
|
| 39 |
-
effective_date: Optional[str] = None
|
| 40 |
-
category: Optional[str] = ""
|
| 41 |
-
|
| 42 |
-
class Procedure(BaseModel):
|
| 43 |
-
id: Optional[str] = None
|
| 44 |
-
code: str
|
| 45 |
-
status: str
|
| 46 |
-
performed_date: Optional[str] = None
|
| 47 |
-
performer: Optional[str] = ""
|
| 48 |
-
reason: Optional[str] = ""
|
| 49 |
-
|
| 50 |
-
class Immunization(BaseModel):
|
| 51 |
-
id: Optional[str] = None
|
| 52 |
-
vaccine: str
|
| 53 |
-
status: str
|
| 54 |
-
date: Optional[str] = None
|
| 55 |
-
lot_number: Optional[str] = ""
|
| 56 |
-
expiration_date: Optional[str] = ""
|
| 57 |
-
manufacturer: Optional[str] = ""
|
| 58 |
-
|
| 59 |
-
class Allergy(BaseModel):
|
| 60 |
-
id: Optional[str] = None
|
| 61 |
-
substance: str
|
| 62 |
-
status: Optional[str] = ""
|
| 63 |
-
severity: Optional[str] = ""
|
| 64 |
-
onset_date: Optional[str] = None
|
| 65 |
-
reaction: Optional[str] = ""
|
| 66 |
|
| 67 |
class Note(BaseModel):
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
author: Optional[str] = "System"
|
| 72 |
-
content: str
|
| 73 |
-
type: Optional[str] = ""
|
| 74 |
context: Optional[str] = ""
|
|
|
|
| 75 |
|
| 76 |
class PatientCreate(BaseModel):
|
| 77 |
-
fhir_id: Optional[str] = None
|
| 78 |
full_name: str
|
| 79 |
gender: str
|
| 80 |
date_of_birth: str
|
|
@@ -85,14 +43,7 @@ class PatientCreate(BaseModel):
|
|
| 85 |
country: Optional[str] = "US"
|
| 86 |
marital_status: Optional[str] = "Never Married"
|
| 87 |
language: Optional[str] = "en"
|
| 88 |
-
source: Optional[str] = "appointment_booking"
|
| 89 |
-
import_date: Optional[str] = None
|
| 90 |
-
last_updated: Optional[str] = None
|
| 91 |
conditions: Optional[List[Condition]] = []
|
| 92 |
medications: Optional[List[Medication]] = []
|
| 93 |
encounters: Optional[List[Encounter]] = []
|
| 94 |
-
observations: Optional[List[Observation]] = []
|
| 95 |
-
procedures: Optional[List[Procedure]] = []
|
| 96 |
-
immunizations: Optional[List[Immunization]] = []
|
| 97 |
-
allergies: Optional[List[Allergy]] = []
|
| 98 |
notes: Optional[List[Note]] = []
|
|
|
|
| 3 |
from datetime import datetime
|
| 4 |
|
| 5 |
class Condition(BaseModel):
|
| 6 |
+
id: str
|
| 7 |
code: str
|
| 8 |
status: Optional[str] = ""
|
| 9 |
onset_date: Optional[str] = None
|
| 10 |
recorded_date: Optional[str] = None
|
| 11 |
verification_status: Optional[str] = ""
|
|
|
|
| 12 |
|
| 13 |
class Medication(BaseModel):
|
| 14 |
+
id: str
|
| 15 |
name: str
|
| 16 |
status: str
|
| 17 |
prescribed_date: Optional[str] = None
|
| 18 |
requester: Optional[str] = ""
|
| 19 |
dosage: Optional[str] = ""
|
|
|
|
|
|
|
| 20 |
|
| 21 |
class Encounter(BaseModel):
|
| 22 |
+
id: str
|
| 23 |
type: str
|
| 24 |
status: str
|
| 25 |
+
period: dict
|
| 26 |
service_provider: Optional[str] = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
class Note(BaseModel):
|
| 29 |
+
date: str
|
| 30 |
+
type: str
|
| 31 |
+
text: str
|
|
|
|
|
|
|
|
|
|
| 32 |
context: Optional[str] = ""
|
| 33 |
+
author: Optional[str] = "System"
|
| 34 |
|
| 35 |
class PatientCreate(BaseModel):
|
|
|
|
| 36 |
full_name: str
|
| 37 |
gender: str
|
| 38 |
date_of_birth: str
|
|
|
|
| 43 |
country: Optional[str] = "US"
|
| 44 |
marital_status: Optional[str] = "Never Married"
|
| 45 |
language: Optional[str] = "en"
|
|
|
|
|
|
|
|
|
|
| 46 |
conditions: Optional[List[Condition]] = []
|
| 47 |
medications: Optional[List[Medication]] = []
|
| 48 |
encounters: Optional[List[Encounter]] = []
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
notes: Optional[List[Note]] = []
|
routes/patients.py
CHANGED
|
@@ -45,77 +45,6 @@ except PermissionError:
|
|
| 45 |
os.makedirs(SYNTHEA_DATA_DIR, exist_ok=True)
|
| 46 |
|
| 47 |
# Pydantic models for update validation
|
| 48 |
-
class ConditionUpdate(BaseModel):
|
| 49 |
-
id: Optional[str] = None
|
| 50 |
-
code: Optional[str] = None
|
| 51 |
-
status: Optional[str] = None
|
| 52 |
-
onset_date: Optional[str] = None
|
| 53 |
-
recorded_date: Optional[str] = None
|
| 54 |
-
verification_status: Optional[str] = None
|
| 55 |
-
category: Optional[str] = None
|
| 56 |
-
|
| 57 |
-
class MedicationUpdate(BaseModel):
|
| 58 |
-
id: Optional[str] = None
|
| 59 |
-
name: Optional[str] = None
|
| 60 |
-
status: Optional[str] = None
|
| 61 |
-
prescribed_date: Optional[str] = None
|
| 62 |
-
requester: Optional[str] = None
|
| 63 |
-
dosage: Optional[str] = None
|
| 64 |
-
intent: Optional[str] = None
|
| 65 |
-
priority: Optional[str] = None
|
| 66 |
-
|
| 67 |
-
class EncounterUpdate(BaseModel):
|
| 68 |
-
id: Optional[str] = None
|
| 69 |
-
type: Optional[str] = None
|
| 70 |
-
status: Optional[str] = None
|
| 71 |
-
period: Optional[Dict[str, str]] = None
|
| 72 |
-
service_provider: Optional[str] = None
|
| 73 |
-
class_type: Optional[str] = None
|
| 74 |
-
reason: Optional[str] = None
|
| 75 |
-
|
| 76 |
-
class ObservationUpdate(BaseModel):
|
| 77 |
-
id: Optional[str] = None
|
| 78 |
-
code: Optional[str] = None
|
| 79 |
-
value: Optional[str] = None
|
| 80 |
-
unit: Optional[str] = None
|
| 81 |
-
status: Optional[str] = None
|
| 82 |
-
effective_date: Optional[str] = None
|
| 83 |
-
category: Optional[str] = None
|
| 84 |
-
|
| 85 |
-
class ProcedureUpdate(BaseModel):
|
| 86 |
-
id: Optional[str] = None
|
| 87 |
-
code: Optional[str] = None
|
| 88 |
-
status: Optional[str] = None
|
| 89 |
-
performed_date: Optional[str] = None
|
| 90 |
-
performer: Optional[str] = None
|
| 91 |
-
reason: Optional[str] = None
|
| 92 |
-
|
| 93 |
-
class ImmunizationUpdate(BaseModel):
|
| 94 |
-
id: Optional[str] = None
|
| 95 |
-
vaccine: Optional[str] = None
|
| 96 |
-
status: Optional[str] = None
|
| 97 |
-
date: Optional[str] = None
|
| 98 |
-
lot_number: Optional[str] = None
|
| 99 |
-
expiration_date: Optional[str] = None
|
| 100 |
-
manufacturer: Optional[str] = None
|
| 101 |
-
|
| 102 |
-
class AllergyUpdate(BaseModel):
|
| 103 |
-
id: Optional[str] = None
|
| 104 |
-
substance: Optional[str] = None
|
| 105 |
-
status: Optional[str] = None
|
| 106 |
-
severity: Optional[str] = None
|
| 107 |
-
onset_date: Optional[str] = None
|
| 108 |
-
reaction: Optional[str] = None
|
| 109 |
-
|
| 110 |
-
class NoteUpdate(BaseModel):
|
| 111 |
-
id: Optional[str] = None
|
| 112 |
-
title: Optional[str] = None
|
| 113 |
-
date: Optional[str] = None
|
| 114 |
-
author: Optional[str] = None
|
| 115 |
-
content: Optional[str] = None
|
| 116 |
-
type: Optional[str] = None
|
| 117 |
-
context: Optional[str] = None
|
| 118 |
-
|
| 119 |
class PatientUpdate(BaseModel):
|
| 120 |
full_name: Optional[str] = None
|
| 121 |
gender: Optional[str] = None
|
|
@@ -125,16 +54,21 @@ class PatientUpdate(BaseModel):
|
|
| 125 |
state: Optional[str] = None
|
| 126 |
postal_code: Optional[str] = None
|
| 127 |
country: Optional[str] = None
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
|
| 139 |
@router.get("/debug/count")
|
| 140 |
async def debug_patient_count():
|
|
@@ -177,21 +111,18 @@ async def create_patient(
|
|
| 177 |
now = datetime.utcnow().isoformat()
|
| 178 |
|
| 179 |
# Add system-generated fields if not provided
|
| 180 |
-
if not patient_doc.get('fhir_id'):
|
| 181 |
-
patient_doc['fhir_id'] = str(uuid.uuid4())
|
| 182 |
-
if not patient_doc.get('import_date'):
|
| 183 |
-
patient_doc['import_date'] = now
|
| 184 |
-
if not patient_doc.get('last_updated'):
|
| 185 |
-
patient_doc['last_updated'] = now
|
| 186 |
if not patient_doc.get('source'):
|
| 187 |
patient_doc['source'] = 'appointment_booking'
|
|
|
|
|
|
|
| 188 |
|
| 189 |
patient_doc['created_by'] = current_user.get('email')
|
|
|
|
|
|
|
| 190 |
|
| 191 |
# Ensure all array fields exist even if empty
|
| 192 |
array_fields = [
|
| 193 |
-
'
|
| 194 |
-
'procedures', 'immunizations', 'allergies', 'notes'
|
| 195 |
]
|
| 196 |
for field in array_fields:
|
| 197 |
if field not in patient_doc or patient_doc[field] is None:
|
|
@@ -932,86 +863,34 @@ async def update_patient(
|
|
| 932 |
"state": update_data.state,
|
| 933 |
"postal_code": update_data.postal_code,
|
| 934 |
"country": update_data.country,
|
| 935 |
-
"
|
| 936 |
-
"
|
| 937 |
}
|
| 938 |
for key, value in demographics.items():
|
| 939 |
if value is not None:
|
| 940 |
update_ops["$set"][key] = value
|
| 941 |
|
| 942 |
-
# Handle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 943 |
array_fields = {
|
| 944 |
-
"conditions": update_data.conditions,
|
| 945 |
-
"medications": update_data.medications,
|
| 946 |
-
"encounters": update_data.encounters,
|
| 947 |
-
"observations": update_data.observations,
|
| 948 |
-
"procedures": update_data.procedures,
|
| 949 |
-
"immunizations": update_data.immunizations,
|
| 950 |
"allergies": update_data.allergies,
|
| 951 |
-
"
|
|
|
|
| 952 |
}
|
| 953 |
|
| 954 |
for field, items in array_fields.items():
|
| 955 |
if items is not None:
|
| 956 |
-
|
| 957 |
-
existing_items = patient.get(field, [])
|
| 958 |
-
updated_items = []
|
| 959 |
-
|
| 960 |
-
for item in items:
|
| 961 |
-
item_dict = item.dict(exclude_unset=True)
|
| 962 |
-
if not item_dict:
|
| 963 |
-
continue
|
| 964 |
-
|
| 965 |
-
# Generate ID for new items
|
| 966 |
-
if not item_dict.get("id"):
|
| 967 |
-
item_dict["id"] = str(uuid.uuid4())
|
| 968 |
-
|
| 969 |
-
# Validate required fields
|
| 970 |
-
if field == "conditions" and not item_dict.get("code"):
|
| 971 |
-
raise HTTPException(
|
| 972 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 973 |
-
detail=f"Condition code is required for {field}"
|
| 974 |
-
)
|
| 975 |
-
if field == "medications" and not item_dict.get("name"):
|
| 976 |
-
raise HTTPException(
|
| 977 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 978 |
-
detail=f"Medication name is required for {field}"
|
| 979 |
-
)
|
| 980 |
-
if field == "encounters" and not item_dict.get("type"):
|
| 981 |
-
raise HTTPException(
|
| 982 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 983 |
-
detail=f"Encounter type is required for {field}"
|
| 984 |
-
)
|
| 985 |
-
if field == "observations" and not item_dict.get("code"):
|
| 986 |
-
raise HTTPException(
|
| 987 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 988 |
-
detail=f"Observation code is required for {field}"
|
| 989 |
-
)
|
| 990 |
-
if field == "procedures" and not item_dict.get("code"):
|
| 991 |
-
raise HTTPException(
|
| 992 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 993 |
-
detail=f"Procedure code is required for {field}"
|
| 994 |
-
)
|
| 995 |
-
if field == "immunizations" and not item_dict.get("vaccine"):
|
| 996 |
-
raise HTTPException(
|
| 997 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 998 |
-
detail=f"Immunization vaccine is required for {field}"
|
| 999 |
-
)
|
| 1000 |
-
if field == "allergies" and not item_dict.get("substance"):
|
| 1001 |
-
raise HTTPException(
|
| 1002 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 1003 |
-
detail=f"Allergy substance is required for {field}"
|
| 1004 |
-
)
|
| 1005 |
-
if field == "notes" and not item_dict.get("content"):
|
| 1006 |
-
raise HTTPException(
|
| 1007 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
| 1008 |
-
detail=f"Note content is required for {field}"
|
| 1009 |
-
)
|
| 1010 |
-
|
| 1011 |
-
updated_items.append(item_dict)
|
| 1012 |
-
|
| 1013 |
-
# Replace the entire array
|
| 1014 |
-
update_ops["$set"][field] = updated_items
|
| 1015 |
|
| 1016 |
# Perform the update
|
| 1017 |
result = await patients_collection.update_one(query, update_ops)
|
|
@@ -1034,7 +913,6 @@ async def update_patient(
|
|
| 1034 |
|
| 1035 |
response = {
|
| 1036 |
"id": str(updated_patient["_id"]),
|
| 1037 |
-
"fhir_id": updated_patient.get("fhir_id"),
|
| 1038 |
"full_name": updated_patient.get("full_name"),
|
| 1039 |
"gender": updated_patient.get("gender"),
|
| 1040 |
"date_of_birth": updated_patient.get("date_of_birth"),
|
|
@@ -1043,19 +921,20 @@ async def update_patient(
|
|
| 1043 |
"state": updated_patient.get("state"),
|
| 1044 |
"postal_code": updated_patient.get("postal_code"),
|
| 1045 |
"country": updated_patient.get("country"),
|
| 1046 |
-
"
|
| 1047 |
-
"
|
| 1048 |
-
"conditions": updated_patient.get("conditions", []),
|
| 1049 |
-
"medications": updated_patient.get("medications", []),
|
| 1050 |
-
"encounters": updated_patient.get("encounters", []),
|
| 1051 |
-
"observations": updated_patient.get("observations", []),
|
| 1052 |
-
"procedures": updated_patient.get("procedures", []),
|
| 1053 |
-
"immunizations": updated_patient.get("immunizations", []),
|
| 1054 |
"allergies": updated_patient.get("allergies", []),
|
| 1055 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1056 |
"source": updated_patient.get("source"),
|
| 1057 |
-
"
|
| 1058 |
-
"
|
|
|
|
|
|
|
| 1059 |
}
|
| 1060 |
|
| 1061 |
logger.info(f"Successfully updated patient {patient_id}")
|
|
|
|
| 45 |
os.makedirs(SYNTHEA_DATA_DIR, exist_ok=True)
|
| 46 |
|
| 47 |
# Pydantic models for update validation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
class PatientUpdate(BaseModel):
|
| 49 |
full_name: Optional[str] = None
|
| 50 |
gender: Optional[str] = None
|
|
|
|
| 54 |
state: Optional[str] = None
|
| 55 |
postal_code: Optional[str] = None
|
| 56 |
country: Optional[str] = None
|
| 57 |
+
national_id: Optional[str] = None
|
| 58 |
+
blood_type: Optional[str] = None
|
| 59 |
+
allergies: Optional[List[str]] = None
|
| 60 |
+
chronic_conditions: Optional[List[str]] = None
|
| 61 |
+
medications: Optional[List[str]] = None
|
| 62 |
+
emergency_contact_name: Optional[str] = None
|
| 63 |
+
emergency_contact_phone: Optional[str] = None
|
| 64 |
+
insurance_provider: Optional[str] = None
|
| 65 |
+
insurance_policy_number: Optional[str] = None
|
| 66 |
+
source: Optional[str] = None
|
| 67 |
+
status: Optional[str] = None
|
| 68 |
+
assigned_doctor_id: Optional[str] = None
|
| 69 |
+
registration_date: Optional[datetime] = None
|
| 70 |
+
created_at: Optional[datetime] = None
|
| 71 |
+
updated_at: Optional[datetime] = None
|
| 72 |
|
| 73 |
@router.get("/debug/count")
|
| 74 |
async def debug_patient_count():
|
|
|
|
| 111 |
now = datetime.utcnow().isoformat()
|
| 112 |
|
| 113 |
# Add system-generated fields if not provided
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
if not patient_doc.get('source'):
|
| 115 |
patient_doc['source'] = 'appointment_booking'
|
| 116 |
+
if not patient_doc.get('status'):
|
| 117 |
+
patient_doc['status'] = 'active'
|
| 118 |
|
| 119 |
patient_doc['created_by'] = current_user.get('email')
|
| 120 |
+
patient_doc['created_at'] = datetime.utcnow()
|
| 121 |
+
patient_doc['updated_at'] = datetime.utcnow()
|
| 122 |
|
| 123 |
# Ensure all array fields exist even if empty
|
| 124 |
array_fields = [
|
| 125 |
+
'allergies', 'chronic_conditions', 'medications'
|
|
|
|
| 126 |
]
|
| 127 |
for field in array_fields:
|
| 128 |
if field not in patient_doc or patient_doc[field] is None:
|
|
|
|
| 863 |
"state": update_data.state,
|
| 864 |
"postal_code": update_data.postal_code,
|
| 865 |
"country": update_data.country,
|
| 866 |
+
"national_id": update_data.national_id,
|
| 867 |
+
"blood_type": update_data.blood_type
|
| 868 |
}
|
| 869 |
for key, value in demographics.items():
|
| 870 |
if value is not None:
|
| 871 |
update_ops["$set"][key] = value
|
| 872 |
|
| 873 |
+
# Handle contact and insurance updates
|
| 874 |
+
contact_fields = {
|
| 875 |
+
"emergency_contact_name": update_data.emergency_contact_name,
|
| 876 |
+
"emergency_contact_phone": update_data.emergency_contact_phone,
|
| 877 |
+
"insurance_provider": update_data.insurance_provider,
|
| 878 |
+
"insurance_policy_number": update_data.insurance_policy_number
|
| 879 |
+
}
|
| 880 |
+
for key, value in contact_fields.items():
|
| 881 |
+
if value is not None:
|
| 882 |
+
update_ops["$set"][key] = value
|
| 883 |
+
|
| 884 |
+
# Handle array updates (simple string arrays)
|
| 885 |
array_fields = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 886 |
"allergies": update_data.allergies,
|
| 887 |
+
"chronic_conditions": update_data.chronic_conditions,
|
| 888 |
+
"medications": update_data.medications
|
| 889 |
}
|
| 890 |
|
| 891 |
for field, items in array_fields.items():
|
| 892 |
if items is not None:
|
| 893 |
+
update_ops["$set"][field] = items
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 894 |
|
| 895 |
# Perform the update
|
| 896 |
result = await patients_collection.update_one(query, update_ops)
|
|
|
|
| 913 |
|
| 914 |
response = {
|
| 915 |
"id": str(updated_patient["_id"]),
|
|
|
|
| 916 |
"full_name": updated_patient.get("full_name"),
|
| 917 |
"gender": updated_patient.get("gender"),
|
| 918 |
"date_of_birth": updated_patient.get("date_of_birth"),
|
|
|
|
| 921 |
"state": updated_patient.get("state"),
|
| 922 |
"postal_code": updated_patient.get("postal_code"),
|
| 923 |
"country": updated_patient.get("country"),
|
| 924 |
+
"national_id": updated_patient.get("national_id"),
|
| 925 |
+
"blood_type": updated_patient.get("blood_type"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 926 |
"allergies": updated_patient.get("allergies", []),
|
| 927 |
+
"chronic_conditions": updated_patient.get("chronic_conditions", []),
|
| 928 |
+
"medications": updated_patient.get("medications", []),
|
| 929 |
+
"emergency_contact_name": updated_patient.get("emergency_contact_name"),
|
| 930 |
+
"emergency_contact_phone": updated_patient.get("emergency_contact_phone"),
|
| 931 |
+
"insurance_provider": updated_patient.get("insurance_provider"),
|
| 932 |
+
"insurance_policy_number": updated_patient.get("insurance_policy_number"),
|
| 933 |
"source": updated_patient.get("source"),
|
| 934 |
+
"status": updated_patient.get("status"),
|
| 935 |
+
"assigned_doctor_id": updated_patient.get("assigned_doctor_id"),
|
| 936 |
+
"created_at": updated_patient.get("created_at"),
|
| 937 |
+
"updated_at": updated_patient.get("updated_at")
|
| 938 |
}
|
| 939 |
|
| 940 |
logger.info(f"Successfully updated patient {patient_id}")
|