Ali2206 commited on
Commit
eb29208
·
verified ·
1 Parent(s): b553899

Update api/routes/patients.py

Browse files
Files changed (1) hide show
  1. api/routes/patients.py +75 -53
api/routes/patients.py CHANGED
@@ -8,7 +8,7 @@ from datetime import datetime
8
  from bson import ObjectId
9
  from bson.errors import InvalidId
10
  from typing import Optional, List, Dict
11
- from pymongo import UpdateOne
12
  from pymongo.errors import BulkWriteError
13
  import json
14
  from pathlib import Path
@@ -115,6 +115,78 @@ async def create_patient(
115
  detail=f"Failed to create patient: {str(e)}"
116
  )
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  async def process_synthea_patient(bundle: dict, file_path: str) -> Optional[dict]:
119
  logger.debug(f"Processing patient from file: {file_path}")
120
  patient_data = {}
@@ -367,7 +439,7 @@ async def list_patients(
367
  skip: int = Query(0, ge=0)
368
  ):
369
  logger.info(f"Listing patients with search: {search}, limit: {limit}, skip: {skip}")
370
- query = {}
371
 
372
  if search:
373
  query["$or"] = [
@@ -392,7 +464,7 @@ async def list_patients(
392
  "medications": 1,
393
  "encounters": 1,
394
  "notes": 1,
395
- "source": 1
396
  }
397
 
398
  try:
@@ -551,55 +623,5 @@ async def add_note(
551
  detail=f"Failed to add note: {str(e)}"
552
  )
553
 
554
- @router.delete("/patients/{patient_id}", status_code=status.HTTP_200_OK)
555
- async def delete_patient(
556
- patient_id: str,
557
- current_user: dict = Depends(get_current_user)
558
- ):
559
- """Delete a patient from the database"""
560
- logger.info(f"Attempting to delete patient {patient_id} by user {current_user.get('email')}")
561
-
562
- if current_user.get('role') not in ['admin', 'doctor']:
563
- logger.warning(f"Unauthorized delete attempt by {current_user.get('email')}")
564
- raise HTTPException(
565
- status_code=status.HTTP_403_FORBIDDEN,
566
- detail="Only administrators and doctors can delete patients"
567
- )
568
-
569
- try:
570
- # Attempt to delete patient by either _id or fhir_id
571
- result = await patients_collection.delete_one({
572
- "$or": [
573
- {"_id": ObjectId(patient_id)},
574
- {"fhir_id": patient_id}
575
- ]
576
- })
577
-
578
- if result.deleted_count == 0:
579
- logger.warning(f"Patient not found for deletion: {patient_id}")
580
- raise HTTPException(
581
- status_code=status.HTTP_404_NOT_FOUND,
582
- detail="Patient not found"
583
- )
584
-
585
- logger.info(f"Successfully deleted patient {patient_id}")
586
- return {
587
- "status": "success",
588
- "message": f"Patient {patient_id} deleted successfully"
589
- }
590
-
591
- except ValueError as ve:
592
- logger.error(f"Invalid patient ID format: {patient_id}, error: {str(ve)}")
593
- raise HTTPException(
594
- status_code=status.HTTP_400_BAD_REQUEST,
595
- detail="Invalid patient ID format"
596
- )
597
- except Exception as e:
598
- logger.error(f"Failed to delete patient {patient_id}: {str(e)}")
599
- raise HTTPException(
600
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
601
- detail=f"Failed to delete patient: {str(e)}"
602
- )
603
-
604
  # Export the router as 'patients' for api.__init__.py
605
  patients = router
 
8
  from bson import ObjectId
9
  from bson.errors import InvalidId
10
  from typing import Optional, List, Dict
11
+ from pymongo import UpdateOne, DeleteOne
12
  from pymongo.errors import BulkWriteError
13
  import json
14
  from pathlib import Path
 
115
  detail=f"Failed to create patient: {str(e)}"
116
  )
117
 
118
+ @router.delete("/patients/{patient_id}", status_code=status.HTTP_204_NO_CONTENT)
119
+ async def delete_patient(
120
+ patient_id: str,
121
+ current_user: dict = Depends(get_current_user)
122
+ ):
123
+ """Delete a patient from the database"""
124
+ logger.info(f"Deleting patient {patient_id} by user {current_user.get('email')}")
125
+
126
+ if current_user.get('role') not in ['admin']:
127
+ logger.warning(f"Unauthorized delete attempt by {current_user.get('email')}")
128
+ raise HTTPException(
129
+ status_code=status.HTTP_403_FORBIDDEN,
130
+ detail="Only administrators can delete patients"
131
+ )
132
+
133
+ try:
134
+ # First check if patient exists
135
+ patient = await patients_collection.find_one({
136
+ "$or": [
137
+ {"_id": ObjectId(patient_id)},
138
+ {"fhir_id": patient_id}
139
+ ]
140
+ })
141
+
142
+ if not patient:
143
+ logger.warning(f"Patient not found for deletion: {patient_id}")
144
+ raise HTTPException(
145
+ status_code=status.HTTP_404_NOT_FOUND,
146
+ detail="Patient not found"
147
+ )
148
+
149
+ # Prevent deletion of Synthea-generated patients
150
+ if patient.get('source') == 'synthea':
151
+ logger.warning(f"Attempt to delete Synthea patient: {patient_id}")
152
+ raise HTTPException(
153
+ status_code=status.HTTP_403_FORBIDDEN,
154
+ detail="Cannot delete Synthea-generated patients"
155
+ )
156
+
157
+ # Perform deletion
158
+ result = await patients_collection.delete_one({
159
+ "$or": [
160
+ {"_id": ObjectId(patient_id)},
161
+ {"fhir_id": patient_id}
162
+ ]
163
+ })
164
+
165
+ if result.deleted_count == 0:
166
+ logger.error(f"Failed to delete patient {patient_id}")
167
+ raise HTTPException(
168
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
169
+ detail="Failed to delete patient"
170
+ )
171
+
172
+ logger.info(f"Successfully deleted patient {patient_id}")
173
+ return None
174
+
175
+ except ValueError as ve:
176
+ logger.error(f"Invalid patient ID format: {patient_id}, error: {str(ve)}")
177
+ raise HTTPException(
178
+ status_code=status.HTTP_400_BAD_REQUEST,
179
+ detail="Invalid patient ID format"
180
+ )
181
+ except HTTPException:
182
+ raise
183
+ except Exception as e:
184
+ logger.error(f"Failed to delete patient {patient_id}: {str(e)}")
185
+ raise HTTPException(
186
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
187
+ detail=f"Failed to delete patient: {str(e)}"
188
+ )
189
+
190
  async def process_synthea_patient(bundle: dict, file_path: str) -> Optional[dict]:
191
  logger.debug(f"Processing patient from file: {file_path}")
192
  patient_data = {}
 
439
  skip: int = Query(0, ge=0)
440
  ):
441
  logger.info(f"Listing patients with search: {search}, limit: {limit}, skip: {skip}")
442
+ query = {} # Removed the default "source": "synthea" filter
443
 
444
  if search:
445
  query["$or"] = [
 
464
  "medications": 1,
465
  "encounters": 1,
466
  "notes": 1,
467
+ "source": 1 # Added source to projection
468
  }
469
 
470
  try:
 
623
  detail=f"Failed to add note: {str(e)}"
624
  )
625
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
626
  # Export the router as 'patients' for api.__init__.py
627
  patients = router