mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: add Assignments, Tasks, Submissions CRUD
This commit is contained in:
parent
cd2397f4f7
commit
47782b57bc
32 changed files with 1719 additions and 218 deletions
|
|
@ -1,133 +0,0 @@
|
|||
from typing import Optional
|
||||
from openai import BaseModel
|
||||
from sqlalchemy import JSON, Column, ForeignKey
|
||||
from sqlmodel import Field, SQLModel
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class AssignmentTypeEnum(str, Enum):
|
||||
FILE_SUBMISSION = "FILE_SUBMISSION"
|
||||
QUIZ = "QUIZ"
|
||||
OTHER = "OTHER"
|
||||
|
||||
|
||||
class Assignment(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
assignment_uuid: str
|
||||
title: str
|
||||
description: str
|
||||
due_date: str
|
||||
|
||||
org_id: int = Field(
|
||||
sa_column=Column("org_id", ForeignKey("organization.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_id: int = Field(
|
||||
sa_column=Column("course_id", ForeignKey("course.id", ondelete="CASCADE"))
|
||||
)
|
||||
chapter_id: int = Field(
|
||||
sa_column=Column("chapter_id", ForeignKey("chapter.id", ondelete="CASCADE"))
|
||||
)
|
||||
activity_id: int = Field(
|
||||
sa_column=Column("activity_id", ForeignKey("activity.id", ondelete="CASCADE"))
|
||||
)
|
||||
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
|
||||
class AssignmentTask(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
assignment_task_uuid: str = ""
|
||||
title: str = ""
|
||||
description: str = ""
|
||||
hint: str = ""
|
||||
assignment_type: AssignmentTypeEnum
|
||||
contents: dict = Field(default={}, sa_column=Column(JSON))
|
||||
max_grade_value: int = (
|
||||
0 # Value is always between 0-100 and is used as the maximum grade for the task
|
||||
)
|
||||
|
||||
# Foreign keys
|
||||
assignment_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_id", ForeignKey("assignment.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
org_id: int = Field(
|
||||
sa_column=Column("org_id", ForeignKey("organization.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_id: int = Field(
|
||||
sa_column=Column("course_id", ForeignKey("course.id", ondelete="CASCADE"))
|
||||
)
|
||||
chapter_id: int = Field(
|
||||
sa_column=Column("chapter_id", ForeignKey("chapter.id", ondelete="CASCADE"))
|
||||
)
|
||||
activity_id: int = Field(
|
||||
sa_column=Column("activity_id", ForeignKey("activity.id", ondelete="CASCADE"))
|
||||
)
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
|
||||
class AssignmentTaskSubmission(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
assignment_task_submission_uuid: str = ""
|
||||
task_submission: dict = Field(default={}, sa_column=Column(JSON))
|
||||
grade: int = (
|
||||
0 # Value is always between 0-100 depending on the questions, this is used to calculate the final grade on the AssignmentUser model
|
||||
)
|
||||
task_submission_grade_feedback: str = "" # Feedback given by the teacher
|
||||
|
||||
# Foreign keys
|
||||
user_id: int = Field(
|
||||
sa_column=Column("user_id", ForeignKey("user.id", ondelete="CASCADE"))
|
||||
)
|
||||
activity_id: int = Field(
|
||||
sa_column=Column("activity_id", ForeignKey("activity.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_id: int = Field(
|
||||
sa_column=Column("course_id", ForeignKey("course.id", ondelete="CASCADE"))
|
||||
)
|
||||
chapter_id: int = Field(
|
||||
sa_column=Column("chapter_id", ForeignKey("chapter.id", ondelete="CASCADE"))
|
||||
)
|
||||
assignment_task_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_task_id", ForeignKey("assignment_task.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
creation_date: str = ""
|
||||
update_date: str = ""
|
||||
|
||||
|
||||
# Note on grading :
|
||||
# To calculate the final grade :
|
||||
|
||||
|
||||
|
||||
|
||||
class AssignmentUserSubmissionStatus(str, Enum):
|
||||
PENDING = "PENDING"
|
||||
SUBMITTED = "SUBMITTED"
|
||||
GRADED = "GRADED"
|
||||
LATE = "LATE"
|
||||
NOT_SUBMITTED = "NOT_SUBMITTED"
|
||||
|
||||
|
||||
class AssignmentUserSubmission(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
assignment_user_uuid: str = ""
|
||||
submission_status: AssignmentUserSubmissionStatus = (
|
||||
AssignmentUserSubmissionStatus.PENDING
|
||||
)
|
||||
grading: str = ""
|
||||
user_id: int = Field(
|
||||
sa_column=Column("user_id", ForeignKey("user.id", ondelete="CASCADE"))
|
||||
)
|
||||
assignment_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_id", ForeignKey("assignment.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
creation_date: str = ""
|
||||
update_date: str = ""
|
||||
317
apps/api/src/db/courses/assignments.py
Normal file
317
apps/api/src/db/courses/assignments.py
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
from typing import Optional, Dict
|
||||
from sqlalchemy import JSON, Column, ForeignKey
|
||||
from sqlmodel import Field, SQLModel
|
||||
from enum import Enum
|
||||
|
||||
|
||||
|
||||
## Assignment ##
|
||||
class GradingTypeEnum(str, Enum):
|
||||
ALPHABET = "ALPHABET"
|
||||
NUMERIC = "NUMERIC"
|
||||
PERCENTAGE = "PERCENTAGE"
|
||||
|
||||
|
||||
class AssignmentBase(SQLModel):
|
||||
"""Represents the common fields for an assignment."""
|
||||
|
||||
title: str
|
||||
description: str
|
||||
due_date: str
|
||||
published: Optional[bool] = False
|
||||
grading_type: GradingTypeEnum
|
||||
|
||||
org_id: int
|
||||
course_id: int
|
||||
chapter_id: int
|
||||
activity_id: int
|
||||
|
||||
|
||||
class AssignmentCreate(AssignmentBase):
|
||||
"""Model for creating a new assignment."""
|
||||
|
||||
pass # Inherits all fields from AssignmentBase
|
||||
|
||||
|
||||
class AssignmentRead(AssignmentBase):
|
||||
"""Model for reading an assignment."""
|
||||
|
||||
id: int
|
||||
assignment_uuid: str
|
||||
creation_date: Optional[str]
|
||||
update_date: Optional[str]
|
||||
|
||||
|
||||
class AssignmentUpdate(SQLModel):
|
||||
"""Model for updating an assignment."""
|
||||
|
||||
title: Optional[str]
|
||||
description: Optional[str]
|
||||
due_date: Optional[str]
|
||||
published: Optional[bool]
|
||||
grading_type: Optional[GradingTypeEnum]
|
||||
org_id: Optional[int]
|
||||
course_id: Optional[int]
|
||||
chapter_id: Optional[int]
|
||||
activity_id: Optional[int]
|
||||
update_date: Optional[str]
|
||||
|
||||
|
||||
class Assignment(AssignmentBase, table=True):
|
||||
"""Represents an assignment with relevant details and foreign keys."""
|
||||
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
creation_date: Optional[str]
|
||||
update_date: Optional[str]
|
||||
assignment_uuid: str
|
||||
|
||||
org_id: int = Field(
|
||||
sa_column=Column("org_id", ForeignKey("organization.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_id: int = Field(
|
||||
sa_column=Column("course_id", ForeignKey("course.id", ondelete="CASCADE"))
|
||||
)
|
||||
chapter_id: int = Field(
|
||||
sa_column=Column("chapter_id", ForeignKey("chapter.id", ondelete="CASCADE"))
|
||||
)
|
||||
activity_id: int = Field(
|
||||
sa_column=Column("activity_id", ForeignKey("activity.id", ondelete="CASCADE"))
|
||||
)
|
||||
|
||||
|
||||
## Assignment ##
|
||||
|
||||
## AssignmentTask ##
|
||||
|
||||
|
||||
class AssignmentTaskTypeEnum(str, Enum):
|
||||
FILE_SUBMISSION = "FILE_SUBMISSION"
|
||||
QUIZ = "QUIZ"
|
||||
FORM = "FORM" # soon to be implemented
|
||||
OTHER = "OTHER"
|
||||
|
||||
|
||||
class AssignmentTaskBase(SQLModel):
|
||||
"""Represents the common fields for an assignment task."""
|
||||
|
||||
title: str
|
||||
description: str
|
||||
hint: str
|
||||
assignment_type: AssignmentTaskTypeEnum
|
||||
contents: Dict = Field(default={}, sa_column=Column(JSON))
|
||||
max_grade_value: int = 0 # Value is always between 0-100
|
||||
|
||||
assignment_id: int
|
||||
org_id: int
|
||||
course_id: int
|
||||
chapter_id: int
|
||||
activity_id: int
|
||||
|
||||
|
||||
class AssignmentTaskCreate(AssignmentTaskBase ):
|
||||
"""Model for creating a new assignment task."""
|
||||
|
||||
pass # Inherits all fields from AssignmentTaskBase
|
||||
|
||||
|
||||
class AssignmentTaskRead(AssignmentTaskBase):
|
||||
"""Model for reading an assignment task."""
|
||||
|
||||
id: int
|
||||
assignment_task_uuid: str
|
||||
|
||||
|
||||
class AssignmentTaskUpdate(SQLModel):
|
||||
"""Model for updating an assignment task."""
|
||||
|
||||
title: Optional[str]
|
||||
description: Optional[str]
|
||||
hint: Optional[str]
|
||||
assignment_type: Optional[AssignmentTaskTypeEnum]
|
||||
contents: Optional[Dict] = Field(default={}, sa_column=Column(JSON))
|
||||
max_grade_value: Optional[int]
|
||||
assignment_id: Optional[int]
|
||||
org_id: Optional[int]
|
||||
course_id: Optional[int]
|
||||
chapter_id: Optional[int]
|
||||
activity_id: Optional[int]
|
||||
|
||||
|
||||
class AssignmentTask(AssignmentTaskBase, table=True):
|
||||
"""Represents a task within an assignment with various attributes and foreign keys."""
|
||||
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
|
||||
assignment_task_uuid: str
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
assignment_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_id", ForeignKey("assignment.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
org_id: int = Field(
|
||||
sa_column=Column("org_id", ForeignKey("organization.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_id: int = Field(
|
||||
sa_column=Column("course_id", ForeignKey("course.id", ondelete="CASCADE"))
|
||||
)
|
||||
chapter_id: int = Field(
|
||||
sa_column=Column("chapter_id", ForeignKey("chapter.id", ondelete="CASCADE"))
|
||||
)
|
||||
activity_id: int = Field(
|
||||
sa_column=Column("activity_id", ForeignKey("activity.id", ondelete="CASCADE"))
|
||||
)
|
||||
|
||||
|
||||
## AssignmentTask ##
|
||||
|
||||
|
||||
## AssignmentTaskSubmission ##
|
||||
|
||||
|
||||
class AssignmentTaskSubmissionBase(SQLModel):
|
||||
"""Represents the common fields for an assignment task submission."""
|
||||
|
||||
task_submission: Dict = Field(default={}, sa_column=Column(JSON))
|
||||
grade: int = 0 # Value is always between 0-100
|
||||
task_submission_grade_feedback: str
|
||||
assignment_type: AssignmentTaskTypeEnum
|
||||
|
||||
user_id: int
|
||||
activity_id: int
|
||||
course_id: int
|
||||
chapter_id: int
|
||||
assignment_task_id: int
|
||||
|
||||
|
||||
class AssignmentTaskSubmissionCreate(AssignmentTaskSubmissionBase):
|
||||
"""Model for creating a new assignment task submission."""
|
||||
|
||||
pass # Inherits all fields from AssignmentTaskSubmissionBase
|
||||
|
||||
|
||||
class AssignmentTaskSubmissionRead(AssignmentTaskSubmissionBase):
|
||||
"""Model for reading an assignment task submission."""
|
||||
|
||||
id: int
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
|
||||
class AssignmentTaskSubmissionUpdate(SQLModel):
|
||||
"""Model for updating an assignment task submission."""
|
||||
|
||||
assignment_task_submission_uuid: Optional[str]
|
||||
task_submission: Optional[Dict] = Field(default={}, sa_column=Column(JSON))
|
||||
grade: Optional[int]
|
||||
task_submission_grade_feedback: Optional[str]
|
||||
assignment_type: Optional[AssignmentTaskTypeEnum]
|
||||
user_id: Optional[int]
|
||||
activity_id: Optional[int]
|
||||
course_id: Optional[int]
|
||||
chapter_id: Optional[int]
|
||||
assignment_task_id: Optional[int]
|
||||
|
||||
|
||||
class AssignmentTaskSubmission(AssignmentTaskSubmissionBase, table=True):
|
||||
"""Represents a submission for a specific assignment task with grade and feedback."""
|
||||
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
assignment_task_submission_uuid: str
|
||||
task_submission: Dict = Field(default={}, sa_column=Column(JSON))
|
||||
grade: int = 0 # Value is always between 0-100
|
||||
task_submission_grade_feedback: str
|
||||
assignment_type: AssignmentTaskTypeEnum
|
||||
|
||||
user_id: int = Field(
|
||||
sa_column=Column("user_id", ForeignKey("user.id", ondelete="CASCADE"))
|
||||
)
|
||||
activity_id: int = Field(
|
||||
sa_column=Column("activity_id", ForeignKey("activity.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_id: int = Field(
|
||||
sa_column=Column("course_id", ForeignKey("course.id", ondelete="CASCADE"))
|
||||
)
|
||||
chapter_id: int = Field(
|
||||
sa_column=Column("chapter_id", ForeignKey("chapter.id", ondelete="CASCADE"))
|
||||
)
|
||||
assignment_task_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_task_id", ForeignKey("assignmenttask.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
## AssignmentTaskSubmission ##
|
||||
|
||||
## AssignmentUserSubmission ##
|
||||
|
||||
class AssignmentUserSubmissionStatus(str, Enum):
|
||||
PENDING = "PENDING"
|
||||
SUBMITTED = "SUBMITTED"
|
||||
GRADED = "GRADED"
|
||||
LATE = "LATE"
|
||||
NOT_SUBMITTED = "NOT_SUBMITTED"
|
||||
|
||||
|
||||
class AssignmentUserSubmissionBase(SQLModel):
|
||||
"""Represents the submission status of an assignment for a user."""
|
||||
|
||||
|
||||
submission_status: AssignmentUserSubmissionStatus = (
|
||||
AssignmentUserSubmissionStatus.PENDING
|
||||
)
|
||||
grade: str
|
||||
user_id: int = Field(
|
||||
sa_column=Column("user_id", ForeignKey("user.id", ondelete="CASCADE"))
|
||||
)
|
||||
assignment_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_id", ForeignKey("assignment.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
|
||||
class AssignmentUserSubmissionCreate(AssignmentUserSubmissionBase):
|
||||
"""Model for creating a new assignment user submission."""
|
||||
|
||||
pass # Inherits all fields from AssignmentUserSubmissionBase
|
||||
|
||||
class AssignmentUserSubmissionRead(AssignmentUserSubmissionBase):
|
||||
"""Model for reading an assignment user submission."""
|
||||
|
||||
id: int
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
class AssignmentUserSubmissionUpdate(SQLModel):
|
||||
"""Model for updating an assignment user submission."""
|
||||
|
||||
submission_status: Optional[AssignmentUserSubmissionStatus]
|
||||
grade: Optional[str]
|
||||
user_id: Optional[int]
|
||||
assignment_id: Optional[int]
|
||||
|
||||
class AssignmentUserSubmission(AssignmentUserSubmissionBase, table=True):
|
||||
"""Represents the submission status of an assignment for a user."""
|
||||
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
creation_date: str
|
||||
update_date: str
|
||||
|
||||
submission_status: AssignmentUserSubmissionStatus = (
|
||||
AssignmentUserSubmissionStatus.PENDING
|
||||
)
|
||||
grade: str
|
||||
user_id: int = Field(
|
||||
sa_column=Column("user_id", ForeignKey("user.id", ondelete="CASCADE"))
|
||||
)
|
||||
assignment_id: int = Field(
|
||||
sa_column=Column(
|
||||
"assignment_id", ForeignKey("assignment.id", ondelete="CASCADE")
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ class BlockCreate(BlockBase):
|
|||
|
||||
|
||||
class BlockRead(BlockBase):
|
||||
id: int
|
||||
id: int = Field(default=None, primary_key=True)
|
||||
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||
course_id: int = Field(default=None, foreign_key="course.id")
|
||||
chapter_id: int = Field(default=None, foreign_key="chapter.id")
|
||||
|
|
@ -2,7 +2,7 @@ from typing import Any, List, Optional
|
|||
from pydantic import BaseModel
|
||||
from sqlalchemy import Column, ForeignKey
|
||||
from sqlmodel import Field, SQLModel
|
||||
from src.db.activities import ActivityRead
|
||||
from src.db.courses.activities import ActivityRead
|
||||
|
||||
|
||||
class ChapterBase(SQLModel):
|
||||
|
|
@ -33,10 +33,10 @@ class ChapterCreate(ChapterBase):
|
|||
|
||||
class ChapterUpdate(ChapterBase):
|
||||
name: Optional[str]
|
||||
description: Optional[str]
|
||||
thumbnail_image: Optional[str]
|
||||
description: Optional[str] = ""
|
||||
thumbnail_image: Optional[str] = ""
|
||||
course_id: Optional[int]
|
||||
org_id: Optional[int]
|
||||
org_id: Optional[int] # type: ignore
|
||||
|
||||
|
||||
class ChapterRead(ChapterBase):
|
||||
|
|
@ -3,7 +3,7 @@ from sqlalchemy import Column, ForeignKey, Integer
|
|||
from sqlmodel import Field, SQLModel
|
||||
from src.db.users import UserRead
|
||||
from src.db.trails import TrailRead
|
||||
from src.db.chapters import ChapterRead
|
||||
from src.db.courses.chapters import ChapterRead
|
||||
|
||||
|
||||
class CourseBase(SQLModel):
|
||||
|
|
@ -21,7 +21,7 @@ class Course(CourseBase, table=True):
|
|||
org_id: int = Field(
|
||||
sa_column=Column(Integer, ForeignKey("organization.id", ondelete="CASCADE"))
|
||||
)
|
||||
course_uuid: str = ""
|
||||
course_uuid: str = ""
|
||||
creation_date: str = ""
|
||||
update_date: str = ""
|
||||
|
||||
|
|
@ -6,8 +6,12 @@ from src.db.trail_runs import TrailRunRead
|
|||
|
||||
|
||||
class TrailBase(SQLModel):
|
||||
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||
user_id: int = Field(default=None, foreign_key="user.id")
|
||||
org_id: int = Field(
|
||||
sa_column=Column(Integer, ForeignKey("organization.id", ondelete="CASCADE"))
|
||||
)
|
||||
user_id: int = Field(
|
||||
sa_column=Column(Integer, ForeignKey("user.id", ondelete="CASCADE"))
|
||||
)
|
||||
|
||||
|
||||
class Trail(TrailBase, table=True):
|
||||
|
|
@ -20,6 +24,7 @@ class Trail(TrailBase, table=True):
|
|||
class TrailCreate(TrailBase):
|
||||
pass
|
||||
|
||||
|
||||
# TODO: This is a hacky way to get around the list[TrailRun] issue, find a better way to do this
|
||||
class TrailRead(BaseModel):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from src.routers import usergroups
|
||||
from src.routers import blocks, dev, trail, users, auth, orgs, roles
|
||||
from src.routers import dev, trail, users, auth, orgs, roles
|
||||
from src.routers.ai import ai
|
||||
from src.routers.courses import chapters, collections, courses, activities
|
||||
from src.routers.courses import chapters, collections, courses, assignments
|
||||
from src.routers.courses.activities import activities, blocks
|
||||
from src.routers.install import install
|
||||
from src.services.dev.dev import isDevModeEnabledOrRaise
|
||||
from src.services.install.install import isInstallModeEnabled
|
||||
|
|
@ -19,6 +20,7 @@ v1_router.include_router(orgs.router, prefix="/orgs", tags=["orgs"])
|
|||
v1_router.include_router(roles.router, prefix="/roles", tags=["roles"])
|
||||
v1_router.include_router(blocks.router, prefix="/blocks", tags=["blocks"])
|
||||
v1_router.include_router(courses.router, prefix="/courses", tags=["courses"])
|
||||
v1_router.include_router(assignments.router, prefix="/assignments", tags=["assignments"])
|
||||
v1_router.include_router(chapters.router, prefix="/chapters", tags=["chapters"])
|
||||
v1_router.include_router(activities.router, prefix="/activities", tags=["activities"])
|
||||
v1_router.include_router(collections.router, prefix="/collections", tags=["collections"])
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from typing import List
|
||||
from fastapi import APIRouter, Depends, UploadFile, Form, Request
|
||||
from src.db.activities import ActivityCreate, ActivityRead, ActivityUpdate
|
||||
from src.db.courses.activities import ActivityCreate, ActivityRead, ActivityUpdate
|
||||
from src.db.users import PublicUser
|
||||
from src.core.events.database import get_db_session
|
||||
from src.services.courses.activities.activities import (
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
from fastapi import APIRouter, Depends, UploadFile, Form, Request
|
||||
from src.db.blocks import BlockRead
|
||||
from src.db.courses.blocks import BlockRead
|
||||
from src.core.events.database import get_db_session
|
||||
from src.security.auth import get_current_user
|
||||
from src.services.blocks.block_types.imageBlock.imageBlock import (
|
||||
310
apps/api/src/routers/courses/assignments.py
Normal file
310
apps/api/src/routers/courses/assignments.py
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
from fastapi import APIRouter, Depends, Request
|
||||
from src.db.courses.assignments import (
|
||||
AssignmentCreate,
|
||||
AssignmentRead,
|
||||
AssignmentTaskCreate,
|
||||
AssignmentTaskSubmissionCreate,
|
||||
AssignmentTaskUpdate,
|
||||
AssignmentUpdate,
|
||||
AssignmentUserSubmissionCreate,
|
||||
)
|
||||
from src.db.users import PublicUser
|
||||
from src.core.events.database import get_db_session
|
||||
from src.security.auth import get_current_user
|
||||
from src.services.courses.activities.assignments import (
|
||||
create_assignment,
|
||||
create_assignment_submission,
|
||||
create_assignment_task,
|
||||
create_assignment_task_submission,
|
||||
delete_assignment,
|
||||
delete_assignment_submission,
|
||||
delete_assignment_task,
|
||||
delete_assignment_task_submission,
|
||||
read_assignment,
|
||||
read_assignment_submissions,
|
||||
read_assignment_task_submissions,
|
||||
read_assignment_tasks,
|
||||
read_user_assignment_submissions,
|
||||
read_user_assignment_task_submissions,
|
||||
update_assignment,
|
||||
update_assignment_submission,
|
||||
update_assignment_task,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
## ASSIGNMENTS ##
|
||||
|
||||
|
||||
@router.post("/")
|
||||
async def api_create_assignments(
|
||||
request: Request,
|
||||
assignment_object: AssignmentCreate,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
) -> AssignmentRead:
|
||||
"""
|
||||
Create new activity
|
||||
"""
|
||||
return await create_assignment(request, assignment_object, current_user, db_session)
|
||||
|
||||
|
||||
@router.get("/{assignment_uuid}")
|
||||
async def api_read_assignment(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
) -> AssignmentRead:
|
||||
"""
|
||||
Read an assignment
|
||||
"""
|
||||
return await read_assignment(request, assignment_uuid, current_user, db_session)
|
||||
|
||||
|
||||
@router.put("/{assignment_uuid}")
|
||||
async def api_update_assignment(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
assignment_object: AssignmentUpdate,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
) -> AssignmentRead:
|
||||
"""
|
||||
Update an assignment
|
||||
"""
|
||||
return await update_assignment(
|
||||
request, assignment_uuid, assignment_object, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/{assignment_uuid}")
|
||||
async def api_delete_assignment(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Delete an assignment
|
||||
"""
|
||||
return await delete_assignment(request, assignment_uuid, current_user, db_session)
|
||||
|
||||
|
||||
## ASSIGNMENTS Tasks ##
|
||||
|
||||
|
||||
@router.post("/{assignment_uuid}/tasks")
|
||||
async def api_create_assignment_tasks(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
assignment_task_object: AssignmentTaskCreate,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Create new tasks for an assignment
|
||||
"""
|
||||
return await create_assignment_task(
|
||||
request, assignment_uuid, assignment_task_object, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{assignment_uuid}/tasks")
|
||||
async def api_read_assignment_tasks(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Read tasks for an assignment
|
||||
"""
|
||||
return await read_assignment_tasks(
|
||||
request, assignment_uuid, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.put("/{assignment_uuid}/tasks/{task_uuid}")
|
||||
async def api_update_assignment_tasks(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
assignment_task_object: AssignmentTaskUpdate,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Update tasks for an assignment
|
||||
"""
|
||||
return await update_assignment_task(
|
||||
request, assignment_task_uuid, assignment_task_object, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/{assignment_uuid}/tasks/{task_uuid}")
|
||||
async def api_delete_assignment_tasks(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Delete tasks for an assignment
|
||||
"""
|
||||
return await delete_assignment_task(
|
||||
request, assignment_task_uuid, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
## ASSIGNMENTS Tasks Submissions ##
|
||||
|
||||
|
||||
@router.post("/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions")
|
||||
async def api_create_assignment_task_submissions(
|
||||
request: Request,
|
||||
assignment_task_submission_object: AssignmentTaskSubmissionCreate,
|
||||
assignment_task_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Create new task submissions for an assignment
|
||||
"""
|
||||
return await create_assignment_task_submission(
|
||||
request,
|
||||
assignment_task_uuid,
|
||||
assignment_task_submission_object,
|
||||
current_user,
|
||||
db_session,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions/{user_id}")
|
||||
async def api_read_user_assignment_task_submissions(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
user_id: int,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Read task submissions for an assignment from a user
|
||||
"""
|
||||
return await read_user_assignment_task_submissions(
|
||||
request, assignment_task_uuid, user_id, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions")
|
||||
async def api_read_assignment_task_submissions(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Read task submissions for an assignment from a user
|
||||
"""
|
||||
return await read_assignment_task_submissions(
|
||||
request, assignment_task_uuid, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.delete(
|
||||
"/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions/{assignment_task_submission_uuid}"
|
||||
)
|
||||
async def api_delete_assignment_task_submissions(
|
||||
request: Request,
|
||||
assignment_task_submission_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Delete task submissions for an assignment from a user
|
||||
"""
|
||||
return await delete_assignment_task_submission(
|
||||
request, assignment_task_submission_uuid, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
## ASSIGNMENTS Submissions ##
|
||||
|
||||
|
||||
@router.post("/{assignment_uuid}/submissions")
|
||||
async def api_create_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
assignment_submission: AssignmentUserSubmissionCreate,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Create new submissions for an assignment
|
||||
"""
|
||||
return await create_assignment_submission(
|
||||
request, assignment_uuid, assignment_submission, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{assignment_uuid}/submissions")
|
||||
async def api_read_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Read submissions for an assignment
|
||||
"""
|
||||
return await read_assignment_submissions(
|
||||
request, assignment_uuid, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{assignment_uuid}/submissions/{user_id}")
|
||||
async def api_read_user_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
user_id: int,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Read submissions for an assignment from a user
|
||||
"""
|
||||
return await read_user_assignment_submissions(
|
||||
request, assignment_uuid, user_id, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.put("/{assignment_uuid}/submissions/{user_id}")
|
||||
async def api_update_user_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
user_id: str,
|
||||
assignment_submission: AssignmentUserSubmissionCreate,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Update submissions for an assignment from a user
|
||||
"""
|
||||
return await update_assignment_submission(
|
||||
request, user_id, assignment_submission, current_user, db_session
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/{assignment_uuid}/submissions/{user_id}")
|
||||
async def api_delete_user_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_id: str,
|
||||
user_id: str,
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
db_session=Depends(get_db_session),
|
||||
):
|
||||
"""
|
||||
Delete submissions for an assignment from a user
|
||||
"""
|
||||
return await delete_assignment_submission(
|
||||
request, assignment_id, user_id, current_user, db_session
|
||||
)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
from typing import List
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from src.core.events.database import get_db_session
|
||||
from src.db.chapters import (
|
||||
from src.db.courses.chapters import (
|
||||
ChapterCreate,
|
||||
ChapterRead,
|
||||
ChapterUpdate,
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from typing import List
|
|||
from fastapi import APIRouter, Depends, UploadFile, Form, Request
|
||||
from sqlmodel import Session
|
||||
from src.core.events.database import get_db_session
|
||||
from src.db.course_updates import (
|
||||
from src.db.courses.course_updates import (
|
||||
CourseUpdateCreate,
|
||||
CourseUpdateRead,
|
||||
CourseUpdateUpdate,
|
||||
)
|
||||
from src.db.users import PublicUser
|
||||
from src.db.courses import (
|
||||
from src.db.courses.courses import (
|
||||
CourseCreate,
|
||||
CourseRead,
|
||||
CourseUpdate,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from fastapi import HTTPException, status, Request
|
|||
from sqlalchemy import null
|
||||
from sqlmodel import Session, select
|
||||
from src.db.collections import Collection
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.resource_authors import ResourceAuthor, ResourceAuthorshipEnum
|
||||
from src.db.roles import Role
|
||||
from src.db.user_organizations import UserOrganization
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ from sqlmodel import Session, select
|
|||
from src.db.organization_config import OrganizationConfig
|
||||
from src.db.organizations import Organization
|
||||
from src.services.ai.utils import check_limits_and_config, count_ai_ask
|
||||
from src.db.courses import Course, CourseRead
|
||||
from src.db.courses.courses import Course, CourseRead
|
||||
from src.core.events.database import get_db_session
|
||||
from src.db.users import PublicUser
|
||||
from src.db.activities import Activity, ActivityRead
|
||||
from src.db.courses.activities import Activity, ActivityRead
|
||||
from src.security.auth import get_current_user
|
||||
from src.services.ai.base import ask_ai, get_chat_session_history
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ from uuid import uuid4
|
|||
from src.db.organizations import Organization
|
||||
from fastapi import HTTPException, status, UploadFile, Request
|
||||
from sqlmodel import Session, select
|
||||
from src.db.activities import Activity
|
||||
from src.db.blocks import Block, BlockRead, BlockTypeEnum
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.activities import Activity
|
||||
from src.db.courses.blocks import Block, BlockRead, BlockTypeEnum
|
||||
from src.db.courses.courses import Course
|
||||
from src.services.blocks.utils.upload_files import upload_file_and_return_file_object
|
||||
from src.services.users.users import PublicUser
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ from uuid import uuid4
|
|||
from src.db.organizations import Organization
|
||||
from fastapi import HTTPException, status, UploadFile, Request
|
||||
from sqlmodel import Session, select
|
||||
from src.db.activities import Activity
|
||||
from src.db.blocks import Block, BlockRead, BlockTypeEnum
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.activities import Activity
|
||||
from src.db.courses.blocks import Block, BlockRead, BlockTypeEnum
|
||||
from src.db.courses.courses import Course
|
||||
from src.services.blocks.utils.upload_files import upload_file_and_return_file_object
|
||||
|
||||
from src.services.users.users import PublicUser
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ from uuid import uuid4
|
|||
from src.db.organizations import Organization
|
||||
from fastapi import HTTPException, status, UploadFile, Request
|
||||
from sqlmodel import Session, select
|
||||
from src.db.activities import Activity
|
||||
from src.db.blocks import Block, BlockRead, BlockTypeEnum
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.activities import Activity
|
||||
from src.db.courses.blocks import Block, BlockRead, BlockTypeEnum
|
||||
from src.db.courses.courses import Course
|
||||
from src.services.blocks.utils.upload_files import upload_file_and_return_file_object
|
||||
|
||||
from src.services.users.users import PublicUser
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
from typing import Literal
|
||||
from sqlmodel import Session, select
|
||||
from src.db.courses import Course
|
||||
from src.db.chapters import Chapter
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.courses.chapters import Chapter
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship_and_usergroups,
|
||||
authorization_verify_if_element_is_public,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
|
||||
from src.db.chapter_activities import ChapterActivity
|
||||
from src.db.courses.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
|
||||
from src.db.courses.chapter_activities import ChapterActivity
|
||||
from src.db.users import AnonymousUser, PublicUser
|
||||
from fastapi import HTTPException, Request
|
||||
from uuid import uuid4
|
||||
|
|
@ -58,7 +58,7 @@ async def create_activity(
|
|||
statement = (
|
||||
select(ChapterActivity)
|
||||
.where(ChapterActivity.chapter_id == activity_object.chapter_id)
|
||||
.order_by(ChapterActivity.order)
|
||||
.order_by(ChapterActivity.order) # type: ignore
|
||||
)
|
||||
chapter_activities = db_session.exec(statement).all()
|
||||
|
||||
|
|
|
|||
997
apps/api/src/services/courses/activities/assignments.py
Normal file
997
apps/api/src/services/courses/activities/assignments.py
Normal file
|
|
@ -0,0 +1,997 @@
|
|||
####################################################
|
||||
# CRUD
|
||||
####################################################
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Literal
|
||||
from uuid import uuid4
|
||||
from fastapi import HTTPException, Request
|
||||
from sqlmodel import Session, select
|
||||
|
||||
from src.db.courses.assignments import (
|
||||
Assignment,
|
||||
AssignmentCreate,
|
||||
AssignmentRead,
|
||||
AssignmentTask,
|
||||
AssignmentTaskCreate,
|
||||
AssignmentTaskRead,
|
||||
AssignmentTaskSubmission,
|
||||
AssignmentTaskSubmissionCreate,
|
||||
AssignmentTaskSubmissionRead,
|
||||
AssignmentTaskUpdate,
|
||||
AssignmentUpdate,
|
||||
AssignmentUserSubmission,
|
||||
AssignmentUserSubmissionCreate,
|
||||
AssignmentUserSubmissionRead,
|
||||
)
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.users import AnonymousUser, PublicUser
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship_and_usergroups,
|
||||
authorization_verify_if_element_is_public,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
|
||||
## > Assignments CRUD
|
||||
|
||||
|
||||
async def create_assignment(
|
||||
request: Request,
|
||||
assignment_object: AssignmentCreate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if org exists
|
||||
statement = select(Course).where(Course.id == assignment_object.course_id)
|
||||
course = db_session.exec(statement).first()
|
||||
|
||||
if not course:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Course not found",
|
||||
)
|
||||
|
||||
# RBAC check
|
||||
await rbac_check(request, course.course_uuid, current_user, "create", db_session)
|
||||
|
||||
# Create Assignment
|
||||
assignment = Assignment(**assignment_object.model_dump())
|
||||
|
||||
assignment.assignment_uuid = str(f"assignment_{uuid4()}")
|
||||
assignment.creation_date = str(datetime.now())
|
||||
assignment.update_date = str(datetime.now())
|
||||
assignment.org_id = course.org_id
|
||||
|
||||
# Insert Assignment in DB
|
||||
db_session.add(assignment)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment)
|
||||
|
||||
# return assignment read
|
||||
return AssignmentRead.model_validate(assignment)
|
||||
|
||||
|
||||
async def read_assignment(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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 rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||
|
||||
# return assignment read
|
||||
return AssignmentRead.model_validate(assignment)
|
||||
|
||||
|
||||
async def update_assignment(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
assignment_object: AssignmentUpdate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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 rbac_check(request, course.course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Update only the fields that were passed in
|
||||
for var, value in vars(assignment_object).items():
|
||||
if value is not None:
|
||||
setattr(assignment, var, value)
|
||||
assignment.update_date = str(datetime.now())
|
||||
|
||||
# Insert Assignment in DB
|
||||
db_session.add(assignment)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment)
|
||||
|
||||
# return assignment read
|
||||
return AssignmentRead.model_validate(assignment)
|
||||
|
||||
|
||||
async def delete_assignment(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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 rbac_check(request, course.course_uuid, current_user, "delete", db_session)
|
||||
|
||||
# Delete Assignment
|
||||
db_session.delete(assignment)
|
||||
db_session.commit()
|
||||
|
||||
return {"message": "Assignment deleted"}
|
||||
|
||||
|
||||
## > Assignments Tasks CRUD
|
||||
|
||||
|
||||
async def create_assignment_task(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
assignment_task_object: AssignmentTaskCreate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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 rbac_check(request, course.course_uuid, current_user, "create", db_session)
|
||||
|
||||
# Create Assignment Task
|
||||
assignment_task = AssignmentTask(**assignment_task_object.model_dump())
|
||||
|
||||
assignment_task.assignment_task_uuid = str(f"assignmenttask_{uuid4()}")
|
||||
assignment_task.creation_date = str(datetime.now())
|
||||
assignment_task.update_date = str(datetime.now())
|
||||
assignment_task.org_id = course.org_id
|
||||
|
||||
# Insert Assignment Task in DB
|
||||
db_session.add(assignment_task)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment_task)
|
||||
|
||||
# return assignment task read
|
||||
return AssignmentTaskRead.model_validate(assignment_task)
|
||||
|
||||
|
||||
async def read_assignment_tasks(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Find assignment
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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",
|
||||
)
|
||||
|
||||
# Find assignments tasks for an assignment
|
||||
statement = select(AssignmentTask).where(
|
||||
assignment.assignment_uuid == assignment_uuid
|
||||
)
|
||||
|
||||
# RBAC check
|
||||
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||
|
||||
# return assignment tasks read
|
||||
return [
|
||||
AssignmentTaskRead.model_validate(assignment_task)
|
||||
for assignment_task in db_session.exec(statement).all()
|
||||
]
|
||||
|
||||
|
||||
async def update_assignment_task(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
assignment_task_object: AssignmentTaskUpdate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.assignment_task_uuid == assignment_task_uuid
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Update only the fields that were passed in
|
||||
for var, value in vars(assignment_task_object).items():
|
||||
if value is not None:
|
||||
setattr(assignment_task, var, value)
|
||||
assignment_task.update_date = str(datetime.now())
|
||||
|
||||
# Insert Assignment Task in DB
|
||||
db_session.add(assignment_task)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment_task)
|
||||
|
||||
# return assignment task read
|
||||
return AssignmentTaskRead.model_validate(assignment_task)
|
||||
|
||||
|
||||
async def delete_assignment_task(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.assignment_task_uuid == assignment_task_uuid
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "delete", db_session)
|
||||
|
||||
# Delete Assignment Task
|
||||
db_session.delete(assignment_task)
|
||||
db_session.commit()
|
||||
|
||||
return {"message": "Assignment Task deleted"}
|
||||
|
||||
|
||||
## > Assignments Tasks Submissions CRUD
|
||||
|
||||
|
||||
async def create_assignment_task_submission(
|
||||
request: Request,
|
||||
assignment_task_uuid: str,
|
||||
assignment_task_submission_object: AssignmentTaskSubmissionCreate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.assignment_task_uuid == assignment_task_uuid
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "create", db_session)
|
||||
|
||||
# Create Assignment Task Submission
|
||||
assignment_task_submission = AssignmentTaskSubmission(
|
||||
**assignment_task_submission_object.model_dump()
|
||||
)
|
||||
|
||||
assignment_task_submission.assignment_task_submission_uuid = str(
|
||||
f"assignmenttasksubmission_{uuid4()}"
|
||||
)
|
||||
assignment_task_submission.creation_date = str(datetime.now())
|
||||
assignment_task_submission.update_date = str(datetime.now())
|
||||
assignment_task_submission.org_id = course.org_id
|
||||
|
||||
# Insert Assignment Task Submission in DB
|
||||
db_session.add(assignment_task_submission)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment_task_submission)
|
||||
|
||||
# return assignment task submission read
|
||||
return AssignmentTaskSubmissionRead.model_validate(assignment_task_submission)
|
||||
|
||||
|
||||
async def read_user_assignment_task_submissions(
|
||||
request: Request,
|
||||
assignment_task_submission_uuid: str,
|
||||
user_id: int,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task submission exists
|
||||
statement = select(AssignmentTaskSubmission).where(
|
||||
AssignmentTaskSubmission.assignment_task_submission_uuid
|
||||
== assignment_task_submission_uuid,
|
||||
AssignmentTaskSubmission.user_id == user_id,
|
||||
)
|
||||
assignment_task_submission = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task_submission:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task Submission not found",
|
||||
)
|
||||
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.id == assignment_task_submission.assignment_task_id
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(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(
|
||||
request: Request,
|
||||
assignment_task_submission_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task submission exists
|
||||
statement = select(AssignmentTaskSubmission).where(
|
||||
AssignmentTaskSubmission.assignment_task_submission_uuid
|
||||
== assignment_task_submission_uuid,
|
||||
)
|
||||
assignment_task_submission = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task_submission:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task Submission not found",
|
||||
)
|
||||
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.id == assignment_task_submission.assignment_task_id
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||
|
||||
# return assignment task submission read
|
||||
return AssignmentTaskSubmissionRead.model_validate(assignment_task_submission)
|
||||
|
||||
|
||||
async def update_assignment_task_submission(
|
||||
request: Request,
|
||||
assignment_task_submission_uuid: str,
|
||||
assignment_task_submission_object: AssignmentTaskSubmissionCreate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task submission exists
|
||||
statement = select(AssignmentTaskSubmission).where(
|
||||
AssignmentTaskSubmission.assignment_task_submission_uuid
|
||||
== assignment_task_submission_uuid
|
||||
)
|
||||
assignment_task_submission = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task_submission:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task Submission not found",
|
||||
)
|
||||
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.id == assignment_task_submission.assignment_task_id
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Update only the fields that were passed in
|
||||
for var, value in vars(assignment_task_submission_object).items():
|
||||
if value is not None:
|
||||
setattr(assignment_task_submission, var, value)
|
||||
assignment_task_submission.update_date = str(datetime.now())
|
||||
|
||||
# Insert Assignment Task Submission in DB
|
||||
db_session.add(assignment_task_submission)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment_task_submission)
|
||||
|
||||
# return assignment task submission read
|
||||
return AssignmentTaskSubmissionRead.model_validate(assignment_task_submission)
|
||||
|
||||
|
||||
async def delete_assignment_task_submission(
|
||||
request: Request,
|
||||
assignment_task_submission_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment task submission exists
|
||||
statement = select(AssignmentTaskSubmission).where(
|
||||
AssignmentTaskSubmission.assignment_task_submission_uuid
|
||||
== assignment_task_submission_uuid
|
||||
)
|
||||
assignment_task_submission = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task_submission:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task Submission not found",
|
||||
)
|
||||
|
||||
# Check if assignment task exists
|
||||
statement = select(AssignmentTask).where(
|
||||
AssignmentTask.id == assignment_task_submission.assignment_task_id
|
||||
)
|
||||
assignment_task = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_task:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment Task not found",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "delete", db_session)
|
||||
|
||||
# Delete Assignment Task Submission
|
||||
db_session.delete(assignment_task_submission)
|
||||
db_session.commit()
|
||||
|
||||
return {"message": "Assignment Task Submission deleted"}
|
||||
|
||||
|
||||
## > Assignments Submissions CRUD
|
||||
|
||||
|
||||
async def create_assignment_submission(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
assignment_user_submission_object: AssignmentUserSubmissionCreate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
assignment = db_session.exec(statement).first()
|
||||
|
||||
if not assignment:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment not found",
|
||||
)
|
||||
|
||||
# Check if the submission has already been made
|
||||
statement = select(AssignmentUserSubmission).where(
|
||||
AssignmentUserSubmission.assignment_id == assignment.id,
|
||||
AssignmentUserSubmission.user_id == assignment_user_submission_object.user_id,
|
||||
)
|
||||
|
||||
assignment_user_submission = db_session.exec(statement).first()
|
||||
|
||||
if assignment_user_submission:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Assignment User Submission already exists",
|
||||
)
|
||||
|
||||
# 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 rbac_check(request, course.course_uuid, current_user, "create", db_session)
|
||||
|
||||
# Create Assignment User Submission
|
||||
assignment_user_submission = AssignmentUserSubmission(
|
||||
**assignment_user_submission_object.model_dump()
|
||||
)
|
||||
|
||||
assignment_user_submission.assignment_user_submission_uuid = str(
|
||||
f"assignmentusersubmission_{uuid4()}"
|
||||
)
|
||||
assignment_user_submission.creation_date = str(datetime.now())
|
||||
assignment_user_submission.update_date = str(datetime.now())
|
||||
assignment_user_submission.org_id = course.org_id
|
||||
|
||||
# Insert Assignment User Submission in DB
|
||||
db_session.add(assignment_user_submission)
|
||||
db_session.commit()
|
||||
|
||||
# return assignment user submission read
|
||||
return AssignmentUserSubmissionRead.model_validate(assignment_user_submission)
|
||||
|
||||
|
||||
async def read_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Find assignment
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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",
|
||||
)
|
||||
|
||||
# Find assignments tasks for an assignment
|
||||
statement = select(AssignmentUserSubmission).where(
|
||||
assignment.assignment_uuid == assignment_uuid
|
||||
)
|
||||
|
||||
# RBAC check
|
||||
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||
|
||||
# return assignment tasks read
|
||||
return [
|
||||
AssignmentUserSubmissionRead.model_validate(assignment_user_submission)
|
||||
for assignment_user_submission in db_session.exec(statement).all()
|
||||
]
|
||||
|
||||
|
||||
async def read_user_assignment_submissions(
|
||||
request: Request,
|
||||
assignment_uuid: str,
|
||||
user_id: int,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Find assignment
|
||||
statement = select(Assignment).where(Assignment.assignment_uuid == assignment_uuid)
|
||||
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",
|
||||
)
|
||||
|
||||
# Find assignments tasks for an assignment
|
||||
statement = select(AssignmentUserSubmission).where(
|
||||
assignment.assignment_uuid == assignment_uuid,
|
||||
AssignmentUserSubmission.user_id == user_id,
|
||||
)
|
||||
|
||||
# RBAC check
|
||||
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||
|
||||
# return assignment tasks read
|
||||
return [
|
||||
AssignmentUserSubmissionRead.model_validate(assignment_user_submission)
|
||||
for assignment_user_submission in db_session.exec(statement).all()
|
||||
]
|
||||
|
||||
|
||||
async def update_assignment_submission(
|
||||
request: Request,
|
||||
user_id: str,
|
||||
assignment_user_submission_object: AssignmentUserSubmissionCreate,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment user submission exists
|
||||
statement = select(AssignmentUserSubmission).where(
|
||||
AssignmentUserSubmission.user_id == user_id
|
||||
)
|
||||
assignment_user_submission = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_user_submission:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment User Submission not found",
|
||||
)
|
||||
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(
|
||||
Assignment.id == assignment_user_submission.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 rbac_check(request, course.course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Update only the fields that were passed in
|
||||
for var, value in vars(assignment_user_submission_object).items():
|
||||
if value is not None:
|
||||
setattr(assignment_user_submission, var, value)
|
||||
assignment_user_submission.update_date = str(datetime.now())
|
||||
|
||||
# Insert Assignment User Submission in DB
|
||||
db_session.add(assignment_user_submission)
|
||||
db_session.commit()
|
||||
db_session.refresh(assignment_user_submission)
|
||||
|
||||
# return assignment user submission read
|
||||
return AssignmentUserSubmissionRead.model_validate(assignment_user_submission)
|
||||
|
||||
|
||||
async def delete_assignment_submission(
|
||||
request: Request,
|
||||
user_id: str,
|
||||
assignment_id: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
# Check if assignment user submission exists
|
||||
statement = select(AssignmentUserSubmission).where(
|
||||
AssignmentUserSubmission.user_id == user_id,
|
||||
AssignmentUserSubmission.assignment_id == assignment_id,
|
||||
)
|
||||
assignment_user_submission = db_session.exec(statement).first()
|
||||
|
||||
if not assignment_user_submission:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Assignment User Submission not found",
|
||||
)
|
||||
|
||||
# Check if assignment exists
|
||||
statement = select(Assignment).where(
|
||||
Assignment.id == assignment_user_submission.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 rbac_check(request, course.course_uuid, current_user, "delete", db_session)
|
||||
|
||||
# Delete Assignment User Submission
|
||||
db_session.delete(assignment_user_submission)
|
||||
db_session.commit()
|
||||
|
||||
return {"message": "Assignment User Submission deleted"}
|
||||
|
||||
|
||||
## 🔒 RBAC Utils ##
|
||||
|
||||
|
||||
async def rbac_check(
|
||||
request: Request,
|
||||
course_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
action: Literal["create", "read", "update", "delete"],
|
||||
db_session: Session,
|
||||
):
|
||||
|
||||
if action == "read":
|
||||
if current_user.id == 0: # Anonymous user
|
||||
res = await authorization_verify_if_element_is_public(
|
||||
request, course_uuid, action, db_session
|
||||
)
|
||||
return res
|
||||
else:
|
||||
res = (
|
||||
await authorization_verify_based_on_roles_and_authorship_and_usergroups(
|
||||
request, current_user.id, action, course_uuid, db_session
|
||||
)
|
||||
)
|
||||
return res
|
||||
else:
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
await authorization_verify_based_on_roles_and_authorship_and_usergroups(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
course_uuid,
|
||||
db_session,
|
||||
)
|
||||
|
||||
|
||||
## 🔒 RBAC Utils ##
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
from typing import Literal
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.organizations import Organization
|
||||
from sqlmodel import Session, select
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship_and_usergroups,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.chapters import Chapter
|
||||
from src.db.activities import (
|
||||
from src.db.courses.chapters import Chapter
|
||||
from src.db.courses.activities import (
|
||||
Activity,
|
||||
ActivityRead,
|
||||
ActivitySubTypeEnum,
|
||||
ActivityTypeEnum,
|
||||
)
|
||||
from src.db.chapter_activities import ChapterActivity
|
||||
from src.db.course_chapters import CourseChapter
|
||||
from src.db.courses.chapter_activities import ChapterActivity
|
||||
from src.db.courses.course_chapters import CourseChapter
|
||||
from src.db.users import AnonymousUser, PublicUser
|
||||
from src.services.courses.activities.uploads.pdfs import upload_pdf
|
||||
from fastapi import HTTPException, status, UploadFile, Request
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from src.db.activities import ActivityRead
|
||||
from src.db.courses import CourseRead
|
||||
from src.db.courses.activities import ActivityRead
|
||||
from src.db.courses.courses import CourseRead
|
||||
|
||||
|
||||
def structure_activity_content_by_type(activity):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from typing import Literal
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.organizations import Organization
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
|
@ -8,15 +8,15 @@ from src.security.rbac.rbac import (
|
|||
authorization_verify_based_on_roles_and_authorship_and_usergroups,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.chapters import Chapter
|
||||
from src.db.activities import (
|
||||
from src.db.courses.chapters import Chapter
|
||||
from src.db.courses.activities import (
|
||||
Activity,
|
||||
ActivityRead,
|
||||
ActivitySubTypeEnum,
|
||||
ActivityTypeEnum,
|
||||
)
|
||||
from src.db.chapter_activities import ChapterActivity
|
||||
from src.db.course_chapters import CourseChapter
|
||||
from src.db.courses.chapter_activities import ChapterActivity
|
||||
from src.db.courses.course_chapters import CourseChapter
|
||||
from src.db.users import AnonymousUser, PublicUser
|
||||
from src.services.courses.activities.uploads.videos import upload_video
|
||||
from fastapi import HTTPException, status, UploadFile, Request
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ from src.security.rbac.rbac import (
|
|||
authorization_verify_if_element_is_public,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.course_chapters import CourseChapter
|
||||
from src.db.activities import Activity, ActivityRead
|
||||
from src.db.chapter_activities import ChapterActivity
|
||||
from src.db.chapters import (
|
||||
from src.db.courses.course_chapters import CourseChapter
|
||||
from src.db.courses.activities import Activity, ActivityRead
|
||||
from src.db.courses.chapter_activities import ChapterActivity
|
||||
from src.db.courses.chapters import (
|
||||
Chapter,
|
||||
ChapterCreate,
|
||||
ChapterRead,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from src.db.collections import (
|
|||
CollectionUpdate,
|
||||
)
|
||||
from src.db.collections_courses import CollectionCourse
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.courses import Course
|
||||
from src.services.users.users import PublicUser
|
||||
from fastapi import HTTPException, status, Request
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from src.db.organizations import Organization
|
|||
from src.services.trail.trail import get_user_trail_with_orgid
|
||||
from src.db.resource_authors import ResourceAuthor, ResourceAuthorshipEnum
|
||||
from src.db.users import PublicUser, AnonymousUser, User, UserRead
|
||||
from src.db.courses import (
|
||||
from src.db.courses.courses import (
|
||||
Course,
|
||||
CourseCreate,
|
||||
CourseRead,
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ from typing import List
|
|||
from uuid import uuid4
|
||||
from fastapi import HTTPException, Request, status
|
||||
from sqlmodel import Session, col, select
|
||||
from src.db.course_updates import (
|
||||
from src.db.courses.course_updates import (
|
||||
CourseUpdate,
|
||||
CourseUpdateCreate,
|
||||
CourseUpdateRead,
|
||||
CourseUpdateUpdate,
|
||||
)
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.organizations import Organization
|
||||
from src.db.users import AnonymousUser, PublicUser
|
||||
from src.services.courses.courses import rbac_check
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
from src.db.chapter_activities import ChapterActivity
|
||||
from src.db.courses.chapter_activities import ChapterActivity
|
||||
from fastapi import HTTPException, Request, status
|
||||
from sqlmodel import Session, select
|
||||
from src.db.activities import Activity
|
||||
from src.db.courses import Course
|
||||
from src.db.courses.activities import Activity
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.trail_runs import TrailRun, TrailRunRead
|
||||
from src.db.trail_steps import TrailStep
|
||||
from src.db.trails import Trail, TrailCreate, TrailRead
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue