You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeBug/backend/db/model.py

159 lines
10 KiB

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, MappedAsDataclass
from sqlalchemy import types, text, String, DateTime, func, Boolean, ForeignKey, SmallInteger
from datetime import datetime
import uuid
from typing import List
6 months ago
from config import *
from constants import UserRole, PublishedStatus
class Base(MappedAsDataclass, DeclarativeBase):
pass
db = SQLAlchemy(model_class=Base)
class User(db.Model):
__tablename__ = 'user'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
email: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
firstName: Mapped[str] = mapped_column(String(32), nullable=False)
lastName: Mapped[str] = mapped_column(String(32), nullable=False)
username: Mapped[str] = mapped_column(String(32), nullable=False)
hash_password: Mapped[str] = mapped_column(String(256), nullable=False)
activationKey: Mapped[str] = mapped_column(String(128), nullable=False)
sessions: Mapped[List["Session"]] = relationship(back_populates="user", cascade="all, delete-orphan")
enrollments: Mapped[List["Enrollment"]] = relationship(back_populates="user", cascade="all, delete-orphan")
quizzes: Mapped[List["Quiz"]] = relationship(back_populates="creatorUser", cascade="all, delete-orphan")
6 months ago
quiz_attempts: Mapped[List["QuizAttempt"]] = relationship(back_populates="user", cascade="all, delete-orphan")
chats: Mapped[List["Chat"]] = relationship(back_populates="user", cascade="all, delete-orphan")
notifications: Mapped[List["Notification"]] = relationship(back_populates="user", cascade="all, delete-orphan")
user_badges: Mapped[List["UserBadge"]] = relationship(back_populates="user", cascade="all, delete-orphan")
6 months ago
dob: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.fromisocalendar(2002, 1, 1))
pfpFilename: Mapped[str] = mapped_column(String(256), nullable=False, default=DEFAULT_PROFILE_FILE)
joinedDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
lastOnline: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now())
bio: Mapped[str] = mapped_column(String(256), nullable=False, default='')
role: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=UserRole.USER)
isActivated: Mapped[bool] = mapped_column(Boolean, nullable=False, default=ACTIVATE_ACCOUNTS_ON_SIGNUP)
class Session(db.Model):
__tablename__ = 'session'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
userID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
user: Mapped["User"] = relationship(back_populates="sessions")
key: Mapped[str] = mapped_column(String(256), nullable=False, unique=True)
ua: Mapped[str] = mapped_column(String(1024), nullable=False)
creationDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
lastUsed: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now())
isValid: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
class Category(db.Model):
__tablename__ = 'category'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
name: Mapped[str] = mapped_column(String(32), nullable=False, unique=True)
courses: Mapped[List["Course"]] = relationship(back_populates="category", cascade="all, delete-orphan")
description: Mapped[str] = mapped_column(String(128), nullable=False, default='')
isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
creationDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
class Course(db.Model):
__tablename__ = 'course'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
name: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
categoryID: Mapped[uuid.UUID] = mapped_column(ForeignKey("category.id"))
category: Mapped["Category"] = relationship(back_populates="courses")
enrollments: Mapped[List["Enrollment"]] = relationship(back_populates="course", cascade="all, delete-orphan")
quizzes: Mapped[List['Quiz']] = relationship(back_populates="course", cascade="all, delete-orphan")
6 months ago
chats: Mapped[List["Chat"]] = relationship(back_populates="course", cascade="all, delete-orphan")
description: Mapped[str] = mapped_column(String(1024), nullable=False, default='')
isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
publishedStatus: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=PublishedStatus.DRAFT)
creationDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
coverImage: Mapped[str] = mapped_column(String(256), nullable=False, default=DEFAULT_COURSE_COVER)
serverFilename: Mapped[str] = mapped_column(String(256), nullable=False, default='')
6 months ago
class Enrollment(db.Model):
__tablename__ = 'enrollment'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
userID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
user: Mapped["User"] = relationship(back_populates="enrollments")
courseID: Mapped[uuid.UUID] = mapped_column(ForeignKey("course.id"))
course: Mapped["Course"] = relationship(back_populates="enrollments")
joinedDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
lastActivity: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now())
currentPage: Mapped[int] = mapped_column(nullable=False, default=1)
maxPage: Mapped[int] = mapped_column(nullable=False, default=1)
class Quiz(db.Model):
__tablename__ = 'quiz'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
creatorUserID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
creatorUser: Mapped["User"] = relationship(back_populates="quizzes")
6 months ago
quiz_attempts: Mapped[List["QuizAttempt"]] = relationship(back_populates="quiz", cascade="all, delete-orphan")
courseID: Mapped[uuid.UUID] = mapped_column(ForeignKey("course.id"))
course: Mapped["Course"] = relationship(back_populates="quizzes")
quizJson: Mapped[str] = mapped_column(String, nullable=False)
creationDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
class QuizAttempt(db.Model):
__tablename__ = 'quiz_attempts'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
userID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
user: Mapped["User"] = relationship(back_populates="quiz_attempts")
quizID: Mapped[uuid.UUID] = mapped_column(ForeignKey("quiz.id"))
quiz: Mapped["Quiz"] = relationship(back_populates="quiz_attempts")
answerKey: Mapped[str] = mapped_column(String, nullable=False)
score: Mapped[int] = mapped_column(default=0, nullable=False)
attemptDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
class Chat(db.Model):
__tablename__ = 'chat'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
textContent: Mapped[str] = mapped_column(nullable=False)
userID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
courseID: Mapped[uuid.UUID] = mapped_column(ForeignKey("course.id"))
course: Mapped["Course"] = relationship(back_populates="chats")
user: Mapped["User"] = relationship(back_populates="chats")
chatDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
class Notification(db.Model):
__tablename__ = 'notification'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
userID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
user: Mapped["User"] = relationship(back_populates="notifications")
notificationType: Mapped[int] = mapped_column(SmallInteger, nullable=False)
notificationData: Mapped[str] = mapped_column(String, nullable=False)
isSeen: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
notifDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
class Badge(db.Model):
__tablename__ = 'badge'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
name: Mapped[str] = mapped_column(String(16), nullable=False)
6 months ago
user_badges: Mapped[List["UserBadge"]] = relationship(back_populates="badge", cascade="all, delete-orphan")
description: Mapped[str] = mapped_column(String(256), nullable=False, default='')
createDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
icon: Mapped[str] = mapped_column(String(256), nullable=False, default='')
canClaim: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
class UserBadge(db.Model):
__tablename__ = 'userbadge'
id: Mapped[uuid.UUID] = mapped_column(types.Uuid, primary_key=True, init=False, server_default=text("gen_random_uuid()"))
userID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
badgeID: Mapped[uuid.UUID] = mapped_column(ForeignKey("badge.id"))
user: Mapped["User"] = relationship(back_populates="user_badges")
badge: Mapped["Badge"] = relationship(back_populates="user_badges")
claimedDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())