Ali2206 commited on
Commit
885fe30
·
verified ·
1 Parent(s): bbc0423

Update api/routes/patients.py

Browse files
Files changed (1) hide show
  1. api/routes/patients.py +114 -39
api/routes/patients.py CHANGED
@@ -338,66 +338,141 @@ async def import_patients(
338
  detail=f"Import failed: {str(e)}"
339
  )
340
 
341
- @router.get("/", response_model=List[dict])
342
  async def list_patients(
343
  search: Optional[str] = Query(None),
344
- skip: int = Query(0, ge=0),
 
345
  limit: int = Query(100, ge=1, le=500),
346
- current_user: dict = Depends(get_current_user)
347
  ):
348
- """List all patients with optional search and pagination"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  try:
350
- query = {}
351
- if search:
352
- query["$or"] = [
353
- {"full_name": {"$regex": search, "$options": "i"}},
354
- {"fhir_id": search},
355
- {"_id": search}
356
- ]
357
-
358
- cursor = patients_collection.find(query).skip(skip).limit(limit)
359
  patients = []
360
 
361
  async for patient in cursor:
362
- patient["id"] = str(patient["_id"])
363
- patient["age"] = calculate_age(patient.get("date_of_birth"))
364
- patients.append(patient)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
 
 
366
  return patients
367
-
368
  except Exception as e:
369
  logger.error(f"Failed to list patients: {str(e)}")
370
  raise HTTPException(
371
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
372
- detail="Failed to retrieve patients"
373
  )
374
 
375
- @router.get("/{patient_id}", response_model=dict)
376
- async def get_patient(
377
- patient_id: str,
378
- current_user: dict = Depends(get_current_user)
379
- ):
380
- """Get a specific patient by ID or FHIR ID"""
381
  try:
382
- # Try as ObjectId first
383
- try:
384
- patient = await patients_collection.find_one({"_id": ObjectId(patient_id)})
385
- except:
386
- # Fall back to FHIR ID
387
- patient = await patients_collection.find_one({"fhir_id": patient_id})
388
-
389
  if not patient:
390
- raise HTTPException(status_code=404, detail="Patient not found")
391
-
392
- patient["id"] = str(patient["_id"])
393
- patient["age"] = calculate_age(patient.get("date_of_birth"))
394
- return patient
395
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  except Exception as e:
397
- logger.error(f"Failed to get patient {patient_id}: {str(e)}")
398
  raise HTTPException(
399
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
400
- detail="Failed to retrieve patient"
401
  )
402
 
403
  @router.post("/{patient_id}/notes", status_code=status.HTTP_201_CREATED)
 
338
  detail=f"Import failed: {str(e)}"
339
  )
340
 
341
+ @router.get("/patients", response_model=List[dict])
342
  async def list_patients(
343
  search: Optional[str] = Query(None),
344
+ min_notes: int = Query(0, ge=0),
345
+ min_conditions: int = Query(0, ge=0),
346
  limit: int = Query(100, ge=1, le=500),
347
+ skip: int = Query(0, ge=0)
348
  ):
349
+ logger.info(f"Listing patients with search: {search}, limit: {limit}, skip: {skip}")
350
+ query = {"source": "synthea"}
351
+
352
+ if search:
353
+ query["$or"] = [
354
+ {"full_name": {"$regex": search, "$options": "i"}},
355
+ {"fhir_id": search}
356
+ ]
357
+
358
+ if min_notes > 0:
359
+ query[f"notes.{min_notes-1}"] = {"$exists": True}
360
+
361
+ if min_conditions > 0:
362
+ query[f"conditions.{min_conditions-1}"] = {"$exists": True}
363
+
364
+ # Removed $slice to return full arrays for the frontend
365
+ projection = {
366
+ "fhir_id": 1,
367
+ "full_name": 1,
368
+ "gender": 1,
369
+ "date_of_birth": 1,
370
+ "city": 1,
371
+ "state": 1,
372
+ "conditions": 1,
373
+ "medications": 1,
374
+ "encounters": 1,
375
+ "notes": 1
376
+ }
377
+
378
  try:
379
+ cursor = patients_collection.find(query, projection).skip(skip).limit(limit)
 
 
 
 
 
 
 
 
380
  patients = []
381
 
382
  async for patient in cursor:
383
+ patients.append({
384
+ "id": str(patient["_id"]),
385
+ "fhir_id": patient.get("fhir_id"),
386
+ "full_name": patient.get("full_name"),
387
+ "gender": patient.get("gender"),
388
+ "date_of_birth": patient.get("date_of_birth"),
389
+ "city": patient.get("city"),
390
+ "state": patient.get("state"),
391
+ "conditions": patient.get("conditions", []),
392
+ "medications": patient.get("medications", []),
393
+ "encounters": patient.get("encounters", []),
394
+ "notes": patient.get("notes", []),
395
+ "age": calculate_age(patient.get("date_of_birth")),
396
+ "stats": {
397
+ "notes": len(patient.get("notes", [])),
398
+ "conditions": len(patient.get("conditions", [])),
399
+ "medications": len(patient.get("medications", []))
400
+ }
401
+ })
402
 
403
+ logger.info(f"Retrieved {len(patients)} patients")
404
  return patients
405
+
406
  except Exception as e:
407
  logger.error(f"Failed to list patients: {str(e)}")
408
  raise HTTPException(
409
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
410
+ detail=f"Failed to retrieve patients: {str(e)}"
411
  )
412
 
413
+ @router.get("/patients/{patient_id}", response_model=dict)
414
+ async def get_patient(patient_id: str):
415
+ logger.info(f"Retrieving patient: {patient_id}")
 
 
 
416
  try:
417
+ patient = await patients_collection.find_one({
418
+ "$or": [
419
+ {"_id": ObjectId(patient_id)},
420
+ {"fhir_id": patient_id}
421
+ ]
422
+ })
423
+
424
  if not patient:
425
+ logger.warning(f"Patient not found: {patient_id}")
426
+ raise HTTPException(
427
+ status_code=status.HTTP_404_NOT_FOUND,
428
+ detail="Patient not found"
429
+ )
430
+
431
+ response = {
432
+ "demographics": {
433
+ "id": str(patient["_id"]),
434
+ "fhir_id": patient.get("fhir_id"),
435
+ "full_name": patient.get("full_name"),
436
+ "gender": patient.get("gender"),
437
+ "date_of_birth": patient.get("date_of_birth"),
438
+ "age": calculate_age(patient.get("date_of_birth")),
439
+ "address": {
440
+ "line": patient.get("address"),
441
+ "city": patient.get("city"),
442
+ "state": patient.get("state"),
443
+ "postal_code": patient.get("postal_code"),
444
+ "country": patient.get("country")
445
+ },
446
+ "marital_status": patient.get("marital_status"),
447
+ "language": patient.get("language")
448
+ },
449
+ "clinical_data": {
450
+ "notes": patient.get("notes", []),
451
+ "conditions": patient.get("conditions", []),
452
+ "medications": patient.get("medications", []),
453
+ "encounters": patient.get("encounters", [])
454
+ },
455
+ "metadata": {
456
+ "source": patient.get("source"),
457
+ "import_date": patient.get("import_date"),
458
+ "last_updated": patient.get("last_updated")
459
+ }
460
+ }
461
+
462
+ logger.info(f"Successfully retrieved patient: {patient_id}")
463
+ return response
464
+
465
+ except ValueError as ve:
466
+ logger.error(f"Invalid patient ID format: {patient_id}, error: {str(ve)}")
467
+ raise HTTPException(
468
+ status_code=status.HTTP_400_BAD_REQUEST,
469
+ detail="Invalid patient ID format"
470
+ )
471
  except Exception as e:
472
+ logger.error(f"Failed to retrieve patient {patient_id}: {str(e)}")
473
  raise HTTPException(
474
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
475
+ detail=f"Failed to retrieve patient: {str(e)}"
476
  )
477
 
478
  @router.post("/{patient_id}/notes", status_code=status.HTTP_201_CREATED)