153 lines
4.5 KiB
Python
153 lines
4.5 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from typing import List
|
|
from models import SubjectCreate, SubjectUpdate, SubjectResponse, SubjectInDB, UserInDB
|
|
from database import get_database
|
|
from routes.auth_routes import get_current_user
|
|
from bson import ObjectId
|
|
from datetime import datetime
|
|
|
|
router = APIRouter(prefix="/subjects", tags=["subjects"])
|
|
|
|
|
|
@router.post("", response_model=SubjectResponse, status_code=status.HTTP_201_CREATED)
|
|
async def create_subject(
|
|
subject: SubjectCreate,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Create a new subject"""
|
|
db = get_database()
|
|
|
|
subject_in_db = SubjectInDB(
|
|
**subject.model_dump(),
|
|
user_id=current_user.id
|
|
)
|
|
|
|
subject_dict = subject_in_db.model_dump(by_alias=True)
|
|
subject_dict["_id"] = ObjectId(subject_dict["_id"])
|
|
|
|
result = await db.subjects.insert_one(subject_dict)
|
|
subject_dict["_id"] = str(result.inserted_id)
|
|
|
|
return SubjectResponse(**subject_dict)
|
|
|
|
|
|
@router.get("", response_model=List[SubjectResponse])
|
|
async def get_subjects(current_user: UserInDB = Depends(get_current_user)):
|
|
"""Get all subjects for the current user"""
|
|
db = get_database()
|
|
|
|
cursor = db.subjects.find({"user_id": current_user.id})
|
|
subjects = await cursor.to_list(length=None)
|
|
|
|
for subject in subjects:
|
|
subject["_id"] = str(subject["_id"])
|
|
|
|
return [SubjectResponse(**subject) for subject in subjects]
|
|
|
|
|
|
@router.get("/{subject_id}", response_model=SubjectResponse)
|
|
async def get_subject(
|
|
subject_id: str,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Get a specific subject"""
|
|
db = get_database()
|
|
|
|
if not ObjectId.is_valid(subject_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid subject ID"
|
|
)
|
|
|
|
subject = await db.subjects.find_one({
|
|
"_id": ObjectId(subject_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not subject:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Subject not found"
|
|
)
|
|
|
|
subject["_id"] = str(subject["_id"])
|
|
return SubjectResponse(**subject)
|
|
|
|
|
|
@router.put("/{subject_id}", response_model=SubjectResponse)
|
|
async def update_subject(
|
|
subject_id: str,
|
|
subject_update: SubjectUpdate,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Update a subject"""
|
|
db = get_database()
|
|
|
|
if not ObjectId.is_valid(subject_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid subject ID"
|
|
)
|
|
|
|
# Check if subject exists and belongs to user
|
|
existing_subject = await db.subjects.find_one({
|
|
"_id": ObjectId(subject_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not existing_subject:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Subject not found"
|
|
)
|
|
|
|
# Update only provided fields
|
|
update_data = subject_update.model_dump(exclude_unset=True)
|
|
if update_data:
|
|
update_data["updated_at"] = datetime.utcnow()
|
|
await db.subjects.update_one(
|
|
{"_id": ObjectId(subject_id)},
|
|
{"$set": update_data}
|
|
)
|
|
|
|
# Fetch updated subject
|
|
updated_subject = await db.subjects.find_one({"_id": ObjectId(subject_id)})
|
|
updated_subject["_id"] = str(updated_subject["_id"])
|
|
|
|
return SubjectResponse(**updated_subject)
|
|
|
|
|
|
@router.delete("/{subject_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_subject(
|
|
subject_id: str,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Delete a subject and all associated grades"""
|
|
db = get_database()
|
|
|
|
if not ObjectId.is_valid(subject_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid subject ID"
|
|
)
|
|
|
|
# Check if subject exists and belongs to user
|
|
subject = await db.subjects.find_one({
|
|
"_id": ObjectId(subject_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not subject:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Subject not found"
|
|
)
|
|
|
|
# Delete subject
|
|
await db.subjects.delete_one({"_id": ObjectId(subject_id)})
|
|
|
|
# Delete all grades for this subject
|
|
await db.grades.delete_many({"subject_id": subject_id, "user_id": current_user.id})
|
|
|
|
return None
|