from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from typing import List
from app.api.dependencies.database import get_async_session
from app.api.dependencies.auth import get_current_active_user
from app.schemas.medical_record import (
MedicalRecordCreate,
MedicalRecordUpdate,
MedicalRecordResponse,
)
from app.models.medical_record import MedicalRecord
from app.models.patient import Patient
from app.models.doctor import Doctor
from app.models.user import User
router = APIRouter(prefix="/medical-records", tags=["medical-records"])
@router.post("/", response_model=MedicalRecordResponse, operation_id="create_medical_record")
async def create_medical_record(
record_data: MedicalRecordCreate,
db: AsyncSession = Depends(get_async_session),
current_user: User = Depends(get_current_active_user),
):
# Verify patient exists
patient_result = await db.execute(
select(Patient).where(Patient.id == record_data.patient_id)
)
if not patient_result.scalar_one_or_none():
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Patient not found"
)
# Verify doctor exists
doctor_result = await db.execute(
select(Doctor).where(Doctor.id == record_data.doctor_id)
)
if not doctor_result.scalar_one_or_none():
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Doctor not found"
)
record = MedicalRecord(**record_data.model_dump())
db.add(record)
await db.commit()
await db.refresh(record)
return record
@router.get("/", response_model=List[MedicalRecordResponse], operation_id="get_medical_records")
async def get_medical_records(
skip: int = 0,
limit: int = 100,
patient_id: int = None,
db: AsyncSession = Depends(get_async_session),
current_user: User = Depends(get_current_active_user),
):
query = select(MedicalRecord).options(
selectinload(MedicalRecord.patient), selectinload(MedicalRecord.doctor)
)
if patient_id:
query = query.where(MedicalRecord.patient_id == patient_id)
query = query.offset(skip).limit(limit)
result = await db.execute(query)
records = result.scalars().all()
return records
@router.get("/{record_id}", response_model=MedicalRecordResponse, operation_id="get_medical_record")
async def get_medical_record(
record_id: int,
db: AsyncSession = Depends(get_async_session),
current_user: User = Depends(get_current_active_user),
):
result = await db.execute(
select(MedicalRecord)
.options(
selectinload(MedicalRecord.patient), selectinload(MedicalRecord.doctor)
)
.where(MedicalRecord.id == record_id)
)
record = result.scalar_one_or_none()
if not record:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Medical record not found"
)
return record
@router.put("/{record_id}", response_model=MedicalRecordResponse, operation_id="update_medical_record")
async def update_medical_record(
record_id: int,
record_data: MedicalRecordUpdate,
db: AsyncSession = Depends(get_async_session),
current_user: User = Depends(get_current_active_user),
):
result = await db.execute(
select(MedicalRecord).where(MedicalRecord.id == record_id)
)
record = result.scalar_one_or_none()
if not record:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Medical record not found"
)
update_data = record_data.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(record, field, value)
await db.commit()
await db.refresh(record)
return record
@router.delete("/{record_id}", operation_id="delete_medical_record")
async def delete_medical_record(
record_id: int,
db: AsyncSession = Depends(get_async_session),
current_user: User = Depends(get_current_active_user),
):
result = await db.execute(
select(MedicalRecord).where(MedicalRecord.id == record_id)
)
record = result.scalar_one_or_none()
if not record:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Medical record not found"
)
await db.delete(record)
await db.commit()
return {"message": "Medical record deleted successfully"}