feat: init CourseUpdates backend CRUD

This commit is contained in:
swve 2024-04-15 22:36:02 +02:00
parent 171feabe99
commit d1a620b2e2
4 changed files with 260 additions and 2 deletions

View file

@ -0,0 +1,41 @@
from typing import Optional
from sqlalchemy import Column, ForeignKey, Integer
from sqlmodel import Field, SQLModel
class CourseUpdate(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
courseupdate_uuid: str
title: str
content: str
course_id: int = Field(
sa_column=Column(Integer, ForeignKey("course.id", ondelete="CASCADE"))
)
linked_activity_uuids: Optional[str] = Field(default=None)
org_id: int = Field(default=None, foreign_key="organization.id")
creation_date: str
update_date: str
class CourseUpdateCreate(SQLModel):
title: str
content: str
linked_activity_uuids: Optional[str] = Field(default=None)
org_id: int
class CourseUpdateRead(SQLModel):
id: int
title: str
content: str
course_id: int
courseupdate_uuid: str
linked_activity_uuids: Optional[str] = Field(default=None)
org_id: int
creation_date: str
update_date: str
class CourseUpdateUpdate(SQLModel):
title: Optional[str] = None
content: Optional[str] = None
linked_activity_uuids: Optional[str] = Field(default=None)

View file

@ -2,6 +2,11 @@ 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 (
CourseUpdateCreate,
CourseUpdateRead,
CourseUpdateUpdate,
)
from src.db.users import PublicUser
from src.db.courses import (
CourseCreate,
@ -19,6 +24,7 @@ from src.services.courses.courses import (
delete_course,
update_course_thumbnail,
)
from src.services.courses.updates import create_update, delete_update, get_updates_by_course_uuid, update_update
router = APIRouter()
@ -51,7 +57,9 @@ async def api_create_course(
learnings=learnings,
tags=tags,
)
return await create_course(request, org_id, course, current_user, db_session, thumbnail)
return await create_course(
request, org_id, course, current_user, db_session, thumbnail
)
@router.put("/{course_uuid}/thumbnail")
@ -145,3 +153,64 @@ async def api_delete_course(
"""
return await delete_course(request, course_uuid, current_user, db_session)
@ router.get("/{course_uuid}/updates")
async def api_get_course_updates(
request: Request,
course_uuid: str,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
) -> List[CourseUpdateRead]:
"""
Get Course Updates by course_uuid
"""
return await get_updates_by_course_uuid(request, course_uuid, current_user, db_session)
@router.post("/{course_uuid}/update")
async def api_create_course_update(
request: Request,
course_uuid: str,
update_object: CourseUpdateCreate,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
) -> CourseUpdateRead:
"""
Create new Course Update
"""
return await create_update(
request, course_uuid, update_object, current_user, db_session
)
@router.put("/{course_uuid}/update/{courseupdate_uuid}")
async def api_update_course_update(
request: Request,
course_uuid: str,
courseupdate_uuid: str,
update_object: CourseUpdateUpdate,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
) -> CourseUpdateRead:
"""
Update Course Update by courseupdate_uuid
"""
return await update_update(
request, courseupdate_uuid, update_object, current_user, db_session
)
@router.delete("/{course_uuid}/update/{courseupdate_uuid}")
async def api_delete_course_update(
request: Request,
course_uuid: str,
courseupdate_uuid: str,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
):
"""
Delete Course Update by courseupdate_uuid
"""
return await delete_update(request, courseupdate_uuid, current_user, db_session)

View file

@ -5,7 +5,7 @@ async def check_element_type(element_uuid):
"""
Check if the element is a course, a user, a house or a collection, by checking its prefix
"""
if element_uuid.startswith("course_"):
if element_uuid.startswith("course_") or element_uuid.startswith("courseupdate_"):
return "courses"
elif element_uuid.startswith("user_"):
return "users"

View file

@ -0,0 +1,148 @@
from datetime import datetime
from typing import List
from uuid import uuid4
from fastapi import HTTPException, Request, status
from sqlmodel import Session, select
from src.db.course_updates import (
CourseUpdate,
CourseUpdateCreate,
CourseUpdateRead,
CourseUpdateUpdate,
)
from src.db.courses import Course
from src.db.organizations import Organization
from src.db.users import AnonymousUser, PublicUser
from src.services.courses.courses import rbac_check
async def create_update(
request: Request,
course_uuid: str,
update_object: CourseUpdateCreate,
current_user: PublicUser | AnonymousUser,
db_session: Session,
) -> CourseUpdateRead:
# CHekc if org exists
statement_org = select(Organization).where(Organization.id == update_object.org_id)
org = db_session.exec(statement_org).first()
if not org or org.id is None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist"
)
statement = select(Course).where(Course.course_uuid == course_uuid)
course = db_session.exec(statement).first()
if not course or course.id is None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist"
)
# RBAC check
await rbac_check(request, course.course_uuid, current_user, "update", db_session)
# Generate UUID
courseupdate_uuid = str(f"courseupdate_{uuid4()}")
update = CourseUpdate(
**update_object.model_dump(),
course_id=course.id,
courseupdate_uuid=courseupdate_uuid,
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
)
db_session.add(update)
db_session.commit()
db_session.refresh(update)
return CourseUpdateRead(**update.model_dump())
# Update Course Update
async def update_update(
request: Request,
courseupdate_uuid: str,
update_object: CourseUpdateUpdate,
current_user: PublicUser | AnonymousUser,
db_session: Session,
) -> CourseUpdateRead:
statement = select(CourseUpdate).where(
CourseUpdate.courseupdate_uuid == courseupdate_uuid
)
update = db_session.exec(statement).first()
if not update or update.id is None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Update does not exist"
)
# RBAC check
await rbac_check(
request, update.courseupdate_uuid, current_user, "update", db_session
)
for key, value in update_object.model_dump().items():
if value is not None:
setattr(update, key, value)
db_session.add(update)
db_session.commit()
db_session.refresh(update)
return CourseUpdateRead(**update.model_dump())
# Delete Course Update
async def delete_update(
request: Request,
courseupdate_uuid: str,
current_user: PublicUser | AnonymousUser,
db_session: Session,
):
statement = select(CourseUpdate).where(
CourseUpdate.courseupdate_uuid == courseupdate_uuid
)
update = db_session.exec(statement).first()
if not update or update.id is None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Update does not exist"
)
# RBAC check
await rbac_check(
request, update.courseupdate_uuid, current_user, "delete", db_session
)
db_session.delete(update)
db_session.commit()
return {"message": "Update deleted successfully"}
# Get Course Updates by Course ID
async def get_updates_by_course_uuid(
request: Request,
course_uuid: str,
current_user: PublicUser | AnonymousUser,
db_session: Session,
) -> List[CourseUpdateRead]:
# FInd if course exists
statement = select(Course).where(Course.course_uuid == course_uuid)
course = db_session.exec(statement).first()
if not course or course.id is None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist"
)
statement = select(CourseUpdate).where(CourseUpdate.course_id == course.id)
updates = db_session.exec(statement).all()
return [CourseUpdateRead(**update.model_dump()) for update in updates]