fix: assignments subsequent saves bug

This commit is contained in:
swve 2025-08-12 00:09:50 +02:00
parent 7257222b27
commit ca0a177472
5 changed files with 90 additions and 15 deletions

View file

@ -1,4 +1,4 @@
from fastapi import APIRouter, Depends, Request, UploadFile from fastapi import APIRouter, Depends, Request, UploadFile, HTTPException
from src.db.courses.assignments import ( from src.db.courses.assignments import (
AssignmentCreate, AssignmentCreate,
AssignmentRead, AssignmentRead,
@ -295,9 +295,16 @@ async def api_read_user_assignment_task_submissions_me(
""" """
Read task submissions for an assignment from a user Read task submissions for an assignment from a user
""" """
return await read_user_assignment_task_submissions_me( result = await read_user_assignment_task_submissions_me(
request, assignment_task_uuid, current_user, db_session request, assignment_task_uuid, current_user, db_session
) )
if result is None:
# Return 404 if no submission exists (maintains current frontend behavior)
raise HTTPException(
status_code=404,
detail="Assignment Task Submission not found",
)
return result
@router.get("/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions") @router.get("/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions")

View file

@ -764,9 +764,15 @@ async def handle_assignment_task_submission(
# SECURITY: Instructors/admins need update permission to grade # SECURITY: Instructors/admins need update permission to grade
await courses_rbac_check_for_assignments(request, course.course_uuid, current_user, "update", db_session) await courses_rbac_check_for_assignments(request, course.course_uuid, current_user, "update", db_session)
# Try to find existing submission if UUID is provided # Try to find existing submission by user_id and assignment_task_id first (for save progress functionality)
assignment_task_submission = None statement = select(AssignmentTaskSubmission).where(
if assignment_task_submission_uuid: AssignmentTaskSubmission.assignment_task_id == assignment_task.id,
AssignmentTaskSubmission.user_id == current_user.id,
)
assignment_task_submission = db_session.exec(statement).first()
# If no submission found by user+task, try to find by UUID if provided (for specific submission updates)
if not assignment_task_submission and assignment_task_submission_uuid:
statement = select(AssignmentTaskSubmission).where( statement = select(AssignmentTaskSubmission).where(
AssignmentTaskSubmission.assignment_task_submission_uuid == assignment_task_submission_uuid AssignmentTaskSubmission.assignment_task_submission_uuid == assignment_task_submission_uuid
) )
@ -889,13 +895,54 @@ async def read_user_assignment_task_submissions_me(
current_user: PublicUser | AnonymousUser, current_user: PublicUser | AnonymousUser,
db_session: Session, db_session: Session,
): ):
return await read_user_assignment_task_submissions( # Check if assignment task exists
request, statement = select(AssignmentTask).where(
assignment_task_uuid, AssignmentTask.assignment_task_uuid == assignment_task_uuid
current_user.id,
current_user,
db_session,
) )
assignment_task = db_session.exec(statement).first()
if not assignment_task:
raise HTTPException(
status_code=404,
detail="Assignment Task not found",
)
# Check if assignment task submission exists
statement = select(AssignmentTaskSubmission).where(
AssignmentTaskSubmission.assignment_task_id == assignment_task.id,
AssignmentTaskSubmission.user_id == current_user.id,
)
assignment_task_submission = db_session.exec(statement).first()
if not assignment_task_submission:
# Return None instead of raising an error for cases where no submission exists yet
return None
# Check if assignment exists
statement = select(Assignment).where(Assignment.id == assignment_task.assignment_id)
assignment = db_session.exec(statement).first()
if not assignment:
raise HTTPException(
status_code=404,
detail="Assignment not found",
)
# Check if course exists
statement = select(Course).where(Course.id == assignment.course_id)
course = db_session.exec(statement).first()
if not course:
raise HTTPException(
status_code=404,
detail="Course not found",
)
# RBAC check
await courses_rbac_check_for_assignments(request, course.course_uuid, current_user, "read", db_session)
# return assignment task submission read
return AssignmentTaskSubmissionRead.model_validate(assignment_task_submission)
async def read_assignment_task_submissions( async def read_assignment_task_submissions(

View file

@ -106,9 +106,9 @@ export default function TaskFileObject({ view, user_id, assignmentTaskUUID }: Ta
return; return;
} }
// Save the quiz to the server // Save the file submission to the server
const values = { const values = {
assignment_task_submission_uuid: userSubmissions.assignment_task_submission_uuid, assignment_task_submission_uuid: userSubmissions.assignment_task_submission_uuid || null,
task_submission: userSubmissions, task_submission: userSubmissions,
grade: 0, grade: 0,
task_submission_grade_feedback: '', task_submission_grade_feedback: '',
@ -121,6 +121,13 @@ export default function TaskFileObject({ view, user_id, assignmentTaskUUID }: Ta
}); });
toast.success('Task saved successfully'); toast.success('Task saved successfully');
setShowSavingDisclaimer(false); setShowSavingDisclaimer(false);
// Update userSubmissions with the returned UUID for future updates
const updatedUserSubmissions = {
...userSubmissions,
assignment_task_submission_uuid: res.data?.assignment_task_submission_uuid || userSubmissions.assignment_task_submission_uuid
};
setUserSubmissions(updatedUserSubmissions);
setInitialUserSubmissions(updatedUserSubmissions);
} else { } else {
toast.error('Error saving task, please retry later.'); toast.error('Error saving task, please retry later.');
} }

View file

@ -187,6 +187,7 @@ function TaskFormObject({ view, assignmentTaskUUID, user_id }: TaskFormObjectPro
} }
const values = { const values = {
assignment_task_submission_uuid: userSubmissions.assignment_task_submission_uuid || null,
task_submission: userSubmissions, task_submission: userSubmissions,
grade: 0, grade: 0,
task_submission_grade_feedback: '', task_submission_grade_feedback: '',
@ -201,7 +202,13 @@ function TaskFormObject({ view, assignmentTaskUUID, user_id }: TaskFormObjectPro
if (res) { if (res) {
toast.success('Form submitted successfully!'); toast.success('Form submitted successfully!');
setInitialUserSubmissions(userSubmissions); // Update userSubmissions with the returned UUID for future updates
const updatedUserSubmissions = {
...userSubmissions,
assignment_task_submission_uuid: res.data?.assignment_task_submission_uuid || userSubmissions.assignment_task_submission_uuid
};
setUserSubmissions(updatedUserSubmissions);
setInitialUserSubmissions(updatedUserSubmissions);
setShowSavingDisclaimer(false); setShowSavingDisclaimer(false);
} else { } else {
console.error('Submission error:', res); console.error('Submission error:', res);

View file

@ -221,6 +221,7 @@ function TaskQuizObject({ view, assignmentTaskUUID, user_id }: TaskQuizObjectPro
// Save the quiz to the server // Save the quiz to the server
const values = { const values = {
assignment_task_submission_uuid: userSubmissions.assignment_task_submission_uuid || null,
task_submission: updatedUserSubmissions, task_submission: updatedUserSubmissions,
grade: 0, grade: 0,
task_submission_grade_feedback: '', task_submission_grade_feedback: '',
@ -234,7 +235,13 @@ function TaskQuizObject({ view, assignmentTaskUUID, user_id }: TaskQuizObjectPro
}); });
toast.success('Task saved successfully'); toast.success('Task saved successfully');
setShowSavingDisclaimer(false); setShowSavingDisclaimer(false);
setUserSubmissions(updatedUserSubmissions); // Update userSubmissions with the returned UUID for future updates
const updatedUserSubmissionsWithUUID = {
...updatedUserSubmissions,
assignment_task_submission_uuid: res.data?.assignment_task_submission_uuid || userSubmissions.assignment_task_submission_uuid
};
setUserSubmissions(updatedUserSubmissionsWithUUID);
setInitialUserSubmissions(updatedUserSubmissionsWithUUID);
} else { } else {
toast.error('Error saving task, please retry later.'); toast.error('Error saving task, please retry later.');
} }