Ali2206 commited on
Commit
128a31b
·
1 Parent(s): be490cc
Files changed (1) hide show
  1. api/routes/patients.py +108 -112
api/routes/patients.py CHANGED
@@ -130,14 +130,15 @@ async def create_patient(
130
  # Add system-generated fields
131
  patient_doc.update({
132
  "fhir_id": str(uuid.uuid4()),
133
- "import_date": now,
134
- "last_updated": now,
135
  "source": "manual",
136
- "created_by": current_user.get('email')
 
 
 
137
  })
138
 
139
  # Ensure arrays exist even if empty
140
- for field in ['conditions', 'medications', 'encounters', 'notes']:
141
  if field not in patient_doc:
142
  patient_doc[field] = []
143
 
@@ -257,21 +258,21 @@ async def process_synthea_patient(bundle: dict, file_path: str) -> Optional[dict
257
  raw_full_name = f"{' '.join(name.get('given', ['']))} {name.get('family', '')}".strip()
258
  clean_full_name = re.sub(r'\d+', '', raw_full_name).strip()
259
 
260
- patient_data = {
261
- 'fhir_id': resource.get('id'),
262
- 'full_name': clean_full_name,
263
- 'gender': resource.get('gender', 'unknown'),
264
- 'date_of_birth': resource.get('birthDate', ''),
265
- 'address': ' '.join(address.get('line', [''])),
266
- 'city': address.get('city', ''),
267
- 'state': address.get('state', ''),
268
- 'postal_code': address.get('postalCode', ''),
269
- 'country': address.get('country', ''),
270
- 'marital_status': resource.get('maritalStatus', {}).get('text', ''),
271
- 'language': standardize_language(resource.get('communication', [{}])[0].get('language', {}).get('text', '')),
272
- 'source': 'synthea',
273
- 'last_updated': datetime.utcnow().isoformat()
274
- }
275
 
276
  elif resource_type == 'Encounter':
277
  encounter = {
@@ -317,18 +318,25 @@ async def process_synthea_patient(bundle: dict, file_path: str) -> Optional[dict
317
  logger.error(f"Error processing {resource_type} in {file_path}: {str(e)}")
318
  continue
319
 
320
- if patient_data:
321
- patient_data.update({
322
- 'notes': notes,
323
- 'conditions': conditions,
324
- 'medications': medications,
325
- 'encounters': encounters,
326
- 'import_date': datetime.utcnow().isoformat()
327
- })
328
- logger.info(f"Successfully processed patient {patient_data.get('fhir_id')} from {file_path}")
329
- return patient_data
330
- logger.warning(f"No valid patient data found in {file_path}")
331
- return None
 
 
 
 
 
 
 
332
 
333
  @router.post("/import", status_code=status.HTTP_201_CREATED)
334
  async def import_patients(
@@ -894,34 +902,32 @@ async def get_patient(patient_id: str):
894
  )
895
 
896
  response = {
897
- "demographics": {
898
- "id": str(patient["_id"]),
899
- "fhir_id": patient.get("fhir_id"),
900
- "full_name": patient.get("full_name"),
901
- "gender": patient.get("gender"),
902
- "date_of_birth": patient.get("date_of_birth"),
903
- "age": calculate_age(patient.get("date_of_birth")),
904
- "address": {
905
- "line": patient.get("address"),
906
- "city": patient.get("city"),
907
- "state": patient.get("state"),
908
- "postal_code": patient.get("postal_code"),
909
- "country": patient.get("country")
910
- },
911
- "marital_status": patient.get("marital_status"),
912
- "language": patient.get("language")
913
- },
914
- "clinical_data": {
915
- "notes": patient.get("notes", []),
916
- "conditions": patient.get("conditions", []),
917
- "medications": patient.get("medications", []),
918
- "encounters": patient.get("encounters", [])
919
- },
920
- "metadata": {
921
- "source": patient.get("source"),
922
- "import_date": patient.get("import_date"),
923
- "last_updated": patient.get("last_updated")
924
- }
925
  }
926
 
927
  logger.info(f"Successfully retrieved patient: {patient_id}")
@@ -991,62 +997,44 @@ async def update_patient(
991
  "state": update_data.state,
992
  "postal_code": update_data.postal_code,
993
  "country": update_data.country,
994
- "marital_status": update_data.marital_status,
995
- "language": update_data.language
996
  }
997
  for key, value in demographics.items():
998
  if value is not None:
999
  update_ops["$set"][key] = value
1000
 
1001
- # Handle array updates (conditions, medications, encounters, notes)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1002
  array_fields = {
1003
- "conditions": update_data.conditions,
1004
- "medications": update_data.medications,
1005
- "encounters": update_data.encounters,
1006
- "notes": update_data.notes
1007
  }
1008
 
1009
  for field, items in array_fields.items():
1010
  if items is not None:
1011
- # Fetch existing items
1012
- existing_items = patient.get(field, [])
1013
- updated_items = []
1014
-
1015
- for item in items:
1016
- item_dict = item.dict(exclude_unset=True)
1017
- if not item_dict:
1018
- continue
1019
-
1020
- # Generate ID for new items
1021
- if not item_dict.get("id"):
1022
- item_dict["id"] = str(uuid.uuid4())
1023
-
1024
- # Validate required fields
1025
- if field == "conditions" and not item_dict.get("code"):
1026
- raise HTTPException(
1027
- status_code=status.HTTP_400_BAD_REQUEST,
1028
- detail=f"Condition code is required for {field}"
1029
- )
1030
- if field == "medications" and not item_dict.get("name"):
1031
- raise HTTPException(
1032
- status_code=status.HTTP_400_BAD_REQUEST,
1033
- detail=f"Medication name is required for {field}"
1034
- )
1035
- if field == "encounters" and not item_dict.get("type"):
1036
- raise HTTPException(
1037
- status_code=status.HTTP_400_BAD_REQUEST,
1038
- detail=f"Encounter type is required for {field}"
1039
- )
1040
- if field == "notes" and not item_dict.get("content"):
1041
- raise HTTPException(
1042
- status_code=status.HTTP_400_BAD_REQUEST,
1043
- detail=f"Note content is required for {field}"
1044
- )
1045
-
1046
- updated_items.append(item_dict)
1047
-
1048
- # Replace the entire array
1049
- update_ops["$set"][field] = updated_items
1050
 
1051
  # Perform the update
1052
  result = await patients_collection.update_one(query, update_ops)
@@ -1078,15 +1066,23 @@ async def update_patient(
1078
  "state": updated_patient.get("state"),
1079
  "postal_code": updated_patient.get("postal_code"),
1080
  "country": updated_patient.get("country"),
1081
- "marital_status": updated_patient.get("marital_status"),
1082
- "language": updated_patient.get("language"),
1083
- "conditions": updated_patient.get("conditions", []),
 
1084
  "medications": updated_patient.get("medications", []),
1085
- "encounters": updated_patient.get("encounters", []),
1086
- "notes": updated_patient.get("notes", []),
 
 
 
 
 
1087
  "source": updated_patient.get("source"),
1088
- "import_date": updated_patient.get("import_date"),
1089
- "last_updated": updated_patient.get("last_updated")
 
 
1090
  }
1091
 
1092
  logger.info(f"Successfully updated patient {patient_id}")
 
130
  # Add system-generated fields
131
  patient_doc.update({
132
  "fhir_id": str(uuid.uuid4()),
 
 
133
  "source": "manual",
134
+ "status": "active",
135
+ "created_by": current_user.get('email'),
136
+ "created_at": datetime.utcnow(),
137
+ "updated_at": datetime.utcnow()
138
  })
139
 
140
  # Ensure arrays exist even if empty
141
+ for field in ['allergies', 'chronic_conditions', 'medications']:
142
  if field not in patient_doc:
143
  patient_doc[field] = []
144
 
 
258
  raw_full_name = f"{' '.join(name.get('given', ['']))} {name.get('family', '')}".strip()
259
  clean_full_name = re.sub(r'\d+', '', raw_full_name).strip()
260
 
261
+ patient_data = {
262
+ 'fhir_id': resource.get('id'),
263
+ 'full_name': clean_full_name,
264
+ 'gender': resource.get('gender', 'unknown'),
265
+ 'date_of_birth': resource.get('birthDate', ''),
266
+ 'address': ' '.join(address.get('line', [''])),
267
+ 'city': address.get('city', ''),
268
+ 'state': address.get('state', ''),
269
+ 'postal_code': address.get('postalCode', ''),
270
+ 'country': address.get('country', ''),
271
+ 'source': 'synthea',
272
+ 'status': 'active',
273
+ 'created_at': datetime.utcnow(),
274
+ 'updated_at': datetime.utcnow()
275
+ }
276
 
277
  elif resource_type == 'Encounter':
278
  encounter = {
 
318
  logger.error(f"Error processing {resource_type} in {file_path}: {str(e)}")
319
  continue
320
 
321
+ if patient_data:
322
+ patient_data.update({
323
+ 'allergies': [], # Convert conditions to allergies if needed
324
+ 'chronic_conditions': conditions,
325
+ 'medications': medications,
326
+ 'symptoms': [],
327
+ 'vital_signs': {},
328
+ 'medical_notes': '',
329
+ 'emergency_contact_name': '',
330
+ 'emergency_contact_phone': '',
331
+ 'insurance_provider': '',
332
+ 'insurance_policy_number': '',
333
+ 'national_id': '',
334
+ 'blood_type': ''
335
+ })
336
+ logger.info(f"Successfully processed patient {patient_data.get('fhir_id')} from {file_path}")
337
+ return patient_data
338
+ logger.warning(f"No valid patient data found in {file_path}")
339
+ return None
340
 
341
  @router.post("/import", status_code=status.HTTP_201_CREATED)
342
  async def import_patients(
 
902
  )
903
 
904
  response = {
905
+ "id": str(patient["_id"]),
906
+ "full_name": patient.get("full_name"),
907
+ "gender": patient.get("gender"),
908
+ "date_of_birth": patient.get("date_of_birth"),
909
+ "address": patient.get("address"),
910
+ "city": patient.get("city"),
911
+ "state": patient.get("state"),
912
+ "postal_code": patient.get("postal_code"),
913
+ "country": patient.get("country"),
914
+ "national_id": patient.get("national_id"),
915
+ "blood_type": patient.get("blood_type"),
916
+ "allergies": patient.get("allergies", []),
917
+ "chronic_conditions": patient.get("chronic_conditions", []),
918
+ "medications": patient.get("medications", []),
919
+ "emergency_contact_name": patient.get("emergency_contact_name"),
920
+ "emergency_contact_phone": patient.get("emergency_contact_phone"),
921
+ "insurance_provider": patient.get("insurance_provider"),
922
+ "insurance_policy_number": patient.get("insurance_policy_number"),
923
+ "medical_notes": patient.get("medical_notes"),
924
+ "symptoms": patient.get("symptoms", []),
925
+ "vital_signs": patient.get("vital_signs", {}),
926
+ "source": patient.get("source"),
927
+ "status": patient.get("status"),
928
+ "assigned_doctor_id": patient.get("assigned_doctor_id"),
929
+ "created_at": patient.get("created_at"),
930
+ "updated_at": patient.get("updated_at")
 
 
931
  }
932
 
933
  logger.info(f"Successfully retrieved patient: {patient_id}")
 
997
  "state": update_data.state,
998
  "postal_code": update_data.postal_code,
999
  "country": update_data.country,
1000
+ "national_id": update_data.national_id,
1001
+ "blood_type": update_data.blood_type
1002
  }
1003
  for key, value in demographics.items():
1004
  if value is not None:
1005
  update_ops["$set"][key] = value
1006
 
1007
+ # Handle contact and insurance updates
1008
+ contact_fields = {
1009
+ "emergency_contact_name": update_data.emergency_contact_name,
1010
+ "emergency_contact_phone": update_data.emergency_contact_phone,
1011
+ "insurance_provider": update_data.insurance_provider,
1012
+ "insurance_policy_number": update_data.insurance_policy_number
1013
+ }
1014
+ for key, value in contact_fields.items():
1015
+ if value is not None:
1016
+ update_ops["$set"][key] = value
1017
+
1018
+ # Handle medical information updates
1019
+ medical_fields = {
1020
+ "medical_notes": update_data.medical_notes,
1021
+ "symptoms": update_data.symptoms,
1022
+ "vital_signs": update_data.vital_signs
1023
+ }
1024
+ for key, value in medical_fields.items():
1025
+ if value is not None:
1026
+ update_ops["$set"][key] = value
1027
+
1028
+ # Handle array updates (simple string arrays)
1029
  array_fields = {
1030
+ "allergies": update_data.allergies,
1031
+ "chronic_conditions": update_data.chronic_conditions,
1032
+ "medications": update_data.medications
 
1033
  }
1034
 
1035
  for field, items in array_fields.items():
1036
  if items is not None:
1037
+ update_ops["$set"][field] = items
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1038
 
1039
  # Perform the update
1040
  result = await patients_collection.update_one(query, update_ops)
 
1066
  "state": updated_patient.get("state"),
1067
  "postal_code": updated_patient.get("postal_code"),
1068
  "country": updated_patient.get("country"),
1069
+ "national_id": updated_patient.get("national_id"),
1070
+ "blood_type": updated_patient.get("blood_type"),
1071
+ "allergies": updated_patient.get("allergies", []),
1072
+ "chronic_conditions": updated_patient.get("chronic_conditions", []),
1073
  "medications": updated_patient.get("medications", []),
1074
+ "emergency_contact_name": updated_patient.get("emergency_contact_name"),
1075
+ "emergency_contact_phone": updated_patient.get("emergency_contact_phone"),
1076
+ "insurance_provider": updated_patient.get("insurance_provider"),
1077
+ "insurance_policy_number": updated_patient.get("insurance_policy_number"),
1078
+ "medical_notes": updated_patient.get("medical_notes"),
1079
+ "symptoms": updated_patient.get("symptoms", []),
1080
+ "vital_signs": updated_patient.get("vital_signs", {}),
1081
  "source": updated_patient.get("source"),
1082
+ "status": updated_patient.get("status"),
1083
+ "assigned_doctor_id": updated_patient.get("assigned_doctor_id"),
1084
+ "created_at": updated_patient.get("created_at"),
1085
+ "updated_at": updated_patient.get("updated_at")
1086
  }
1087
 
1088
  logger.info(f"Successfully updated patient {patient_id}")