|
|
|
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, Integer
|
|
|
|
from datetime import datetime
|
|
|
|
import uuid
|
|
|
|
from typing import List
|
|
|
|
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, unique=True)
|
|
|
|
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")
|
|
|
|
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")
|
|
|
|
publications: Mapped[List["Course"]] = relationship(back_populates="author", cascade="all, delete-orphan")
|
|
|
|
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")
|
|
|
|
chats: Mapped[List["Chat"]] = relationship(back_populates="course", cascade="all, delete-orphan")
|
|
|
|
authorID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
|
|
|
|
author: Mapped["User"] = relationship(back_populates="publications")
|
|
|
|
description: Mapped[str] = mapped_column(String(1024), nullable=False, default='')
|
|
|
|
pageForCommunity: Mapped[[int]] = mapped_column(Integer, nullable=False, default=1)
|
|
|
|
totalPages: Mapped[[int]] = mapped_column(Integer, nullable=False, default=1)
|
|
|
|
totalEnrolled: Mapped[int] = mapped_column(Integer, 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='')
|
|
|
|
|
|
|
|
|
|
|
|
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")
|
|
|
|
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)
|
|
|
|
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())
|