mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
wip: add more schemas
This commit is contained in:
parent
732b14866c
commit
b4dcc14749
15 changed files with 319 additions and 8 deletions
|
|
@ -2,27 +2,47 @@ import logging
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
import motor.motor_asyncio
|
import motor.motor_asyncio
|
||||||
from sqlmodel import Field, SQLModel, Session, create_engine
|
from sqlmodel import Field, SQLModel, Session, create_engine
|
||||||
from src.rewrite.services.db import users
|
|
||||||
|
|
||||||
engine = create_engine('postgresql://learnhouse:learnhouse@db:5432/learnhouse', echo=True)
|
from src.rewrite.services.db import (
|
||||||
|
user_organizations,
|
||||||
|
users,
|
||||||
|
roles,
|
||||||
|
organization_settings,
|
||||||
|
organizations,
|
||||||
|
courses,
|
||||||
|
course_authors,
|
||||||
|
chapters,
|
||||||
|
activities,
|
||||||
|
course_chapters,
|
||||||
|
chapter_activities,
|
||||||
|
blocks,
|
||||||
|
collections,
|
||||||
|
)
|
||||||
|
|
||||||
|
engine = create_engine(
|
||||||
|
"postgresql://learnhouse:learnhouse@db:5432/learnhouse", echo=True
|
||||||
|
)
|
||||||
SQLModel.metadata.create_all(engine)
|
SQLModel.metadata.create_all(engine)
|
||||||
|
|
||||||
|
|
||||||
async def connect_to_db(app: FastAPI):
|
async def connect_to_db(app: FastAPI):
|
||||||
app.db_engine = engine # type: ignore
|
app.db_engine = engine # type: ignore
|
||||||
logging.info("LearnHouse database has been started.")
|
logging.info("LearnHouse database has been started.")
|
||||||
|
|
||||||
|
|
||||||
SQLModel.metadata.create_all(engine)
|
SQLModel.metadata.create_all(engine)
|
||||||
|
|
||||||
# mongodb
|
# mongodb
|
||||||
app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient( # type: ignore
|
app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient( # type: ignore
|
||||||
app.learnhouse_config.database_config.mongodb_connection_string) # type: ignore
|
app.learnhouse_config.database_config.mongodb_connection_string # type: ignore
|
||||||
app.db = app.mongodb_client["learnhouse"] # type: ignore
|
) # type: ignore
|
||||||
|
app.db = app.mongodb_client["learnhouse"] # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def get_db_session():
|
def get_db_session():
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
yield session
|
yield session
|
||||||
|
|
||||||
|
|
||||||
async def close_database(app: FastAPI):
|
async def close_database(app: FastAPI):
|
||||||
app.mongodb_client.close() # type: ignore
|
app.mongodb_client.close() # type: ignore
|
||||||
logging.info("LearnHouse has been shut down.")
|
logging.info("LearnHouse has been shut down.")
|
||||||
|
|
|
||||||
58
apps/api/src/rewrite/services/db/activities.py
Normal file
58
apps/api/src/rewrite/services/db/activities.py
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
from typing import Literal, Optional
|
||||||
|
from sqlalchemy import JSON, Column
|
||||||
|
from sqlmodel import Field, Session, SQLModel, create_engine, select
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityTypeEnum(str, Enum):
|
||||||
|
VIDEO = "VIDEO"
|
||||||
|
DOCUMENT = "DOCUMENT"
|
||||||
|
DYNAMIC = "DYNAMIC"
|
||||||
|
ASSESSMENT = "ASSESSMENT"
|
||||||
|
CUSTOM = "CUSTOM"
|
||||||
|
|
||||||
|
|
||||||
|
class ActivitySubTypeEnum(str, Enum):
|
||||||
|
# Dynamic
|
||||||
|
DYNAMIC_PAGE = "DYNAMIC_PAGE"
|
||||||
|
# Video
|
||||||
|
VIDEO_YOUTUBE = "VIDEO_YOUTUBE"
|
||||||
|
VIDEO_HOSTED = "VIDEO_HOSTED"
|
||||||
|
# Document
|
||||||
|
DOCUMENT_PDF = "DOCUMENT_PDF"
|
||||||
|
DOCUMENT_DOC = "DOCUMENT_GDOC"
|
||||||
|
# Assessment
|
||||||
|
ASSESSMENT_QUIZ = "ASSESSMENT_QUIZ"
|
||||||
|
# Custom
|
||||||
|
CUSTOM = "CUSTOM"
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityBase(SQLModel):
|
||||||
|
name: str
|
||||||
|
activity_type: ActivityTypeEnum = ActivityTypeEnum.CUSTOM
|
||||||
|
activity_sub_type: ActivitySubTypeEnum = ActivitySubTypeEnum.CUSTOM
|
||||||
|
slug: str
|
||||||
|
content: dict = Field(default={}, sa_column=Column(JSON))
|
||||||
|
published_version: int
|
||||||
|
version: int
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
course_id: int = Field(default=None, foreign_key="course.id")
|
||||||
|
|
||||||
|
|
||||||
|
class Activity(ActivityBase, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
activity_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityCreate(ActivityBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityRead(ActivityBase):
|
||||||
|
id: int
|
||||||
|
activity_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
pass
|
||||||
44
apps/api/src/rewrite/services/db/blocks.py
Normal file
44
apps/api/src/rewrite/services/db/blocks.py
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlalchemy import JSON, Column
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class BlockTypeEnum(str, Enum):
|
||||||
|
QUIZ_BLOCK = "QUIZ_BLOCK"
|
||||||
|
VIDEO_BLOCK = "VIDEO_BLOCK"
|
||||||
|
DOCUMENT_PDF_BLOCK = "DOCUMENT_PDF_BLOCK"
|
||||||
|
IMAGE_BLOCK = "IMAGE_BLOCK"
|
||||||
|
CUSTOM = "CUSTOM"
|
||||||
|
|
||||||
|
|
||||||
|
class BlockBase(SQLModel):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
block_type: BlockTypeEnum = BlockTypeEnum.CUSTOM
|
||||||
|
content: dict = Field(default={}, sa_column=Column(JSON))
|
||||||
|
|
||||||
|
|
||||||
|
class Block(BlockBase, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
content: dict = Field(default={}, sa_column=Column(JSON))
|
||||||
|
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")
|
||||||
|
activity_id: int = Field(default=None, foreign_key="activity.id")
|
||||||
|
block_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
class BlockCreate(BlockBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class BlockRead(BlockBase):
|
||||||
|
id: int
|
||||||
|
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")
|
||||||
|
activity_id: int = Field(default=None, foreign_key="activity.id")
|
||||||
|
block_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
pass
|
||||||
13
apps/api/src/rewrite/services/db/chapter_activities.py
Normal file
13
apps/api/src/rewrite/services/db/chapter_activities.py
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class ChapterActivity(SQLModel, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
order: int
|
||||||
|
chapter_id: int = Field(default=None, foreign_key="chapter.id")
|
||||||
|
activity_id: int = Field(default=None, foreign_key="activity.id")
|
||||||
|
course_id : int = Field(default=None, foreign_key="course.id")
|
||||||
|
org_id : int = Field(default=None, foreign_key="organization.id")
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
30
apps/api/src/rewrite/services/db/chapters.py
Normal file
30
apps/api/src/rewrite/services/db/chapters.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class ChapterBase(SQLModel):
|
||||||
|
name: str
|
||||||
|
description: Optional[str] = ""
|
||||||
|
thumbnail_image: Optional[str] = ""
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
|
||||||
|
class Chapter(ChapterBase, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
chapter_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
|
||||||
|
class ChapterCreate(ChapterBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ChapterRead(ChapterBase):
|
||||||
|
id: int
|
||||||
|
chapter_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
pass
|
||||||
3
apps/api/src/rewrite/services/db/collections.py
Normal file
3
apps/api/src/rewrite/services/db/collections.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
from enum import Enum
|
||||||
18
apps/api/src/rewrite/services/db/course_authors.py
Normal file
18
apps/api/src/rewrite/services/db/course_authors.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class CourseAuthorshipEnum(str, Enum):
|
||||||
|
CREATOR = "CREATOR"
|
||||||
|
MAINTAINER = "MAINTAINER"
|
||||||
|
REPORTER = "REPORTER"
|
||||||
|
|
||||||
|
|
||||||
|
class CourseAuthor(SQLModel, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
course_id: int = Field(default=None, foreign_key="course.id")
|
||||||
|
user_id: int = Field(default=None, foreign_key="user.id")
|
||||||
|
authorship: CourseAuthorshipEnum = CourseAuthorshipEnum.CREATOR
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
12
apps/api/src/rewrite/services/db/course_chapters.py
Normal file
12
apps/api/src/rewrite/services/db/course_chapters.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class CourseChapter(SQLModel, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
order: int
|
||||||
|
course_id: int = Field(default=None, foreign_key="course.id")
|
||||||
|
chapter_id: int = Field(default=None, foreign_key="chapter.id")
|
||||||
|
org_id : int = Field(default=None, foreign_key="organization.id")
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
29
apps/api/src/rewrite/services/db/courses.py
Normal file
29
apps/api/src/rewrite/services/db/courses.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
|
||||||
|
class CourseBase(SQLModel):
|
||||||
|
name: str
|
||||||
|
description: Optional[str] = ""
|
||||||
|
about: Optional[str] = ""
|
||||||
|
course_slug: str
|
||||||
|
learnings: Optional[str] = ""
|
||||||
|
tags: Optional[str] = ""
|
||||||
|
thumbnail_image: Optional[str] = ""
|
||||||
|
public: bool
|
||||||
|
|
||||||
|
class Course(CourseBase, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
course_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
class CourseCreate(CourseBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class CourseRead(CourseBase):
|
||||||
|
id: int
|
||||||
|
course_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
pass
|
||||||
17
apps/api/src/rewrite/services/db/organization_settings.py
Normal file
17
apps/api/src/rewrite/services/db/organization_settings.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class HeaderTypeEnum(str, Enum):
|
||||||
|
LOGO_MENU_SETTINGS = "LOGO_MENU_SETTINGS"
|
||||||
|
MENU_LOGO_SETTINGS = "MENU_LOGO_SETTINGS"
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizationSettings(SQLModel, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
logo_image: Optional[str] = ""
|
||||||
|
header_type: HeaderTypeEnum = HeaderTypeEnum.LOGO_MENU_SETTINGS
|
||||||
|
color: str = ""
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
26
apps/api/src/rewrite/services/db/organizations.py
Normal file
26
apps/api/src/rewrite/services/db/organizations.py
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizationBase(SQLModel):
|
||||||
|
name: str
|
||||||
|
description: Optional[str] = ""
|
||||||
|
slug: str
|
||||||
|
email: str
|
||||||
|
logo_image: Optional[str] = ""
|
||||||
|
|
||||||
|
|
||||||
|
class Organization(OrganizationBase, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
org_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizationCreate(OrganizationBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizationRead(OrganizationBase):
|
||||||
|
id: int
|
||||||
|
org_uuid: str
|
||||||
30
apps/api/src/rewrite/services/db/roles.py
Normal file
30
apps/api/src/rewrite/services/db/roles.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Optional
|
||||||
|
from sqlalchemy import JSON, Column
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class RoleTypeEnum(str, Enum):
|
||||||
|
ORGANIZATION = "ORGANIZATION"
|
||||||
|
ORGANIZATION_API_TOKEN = "ORGANIZATION_API_TOKEN"
|
||||||
|
DEFAULT = "DEFAULT"
|
||||||
|
|
||||||
|
|
||||||
|
class RoleBase(SQLModel):
|
||||||
|
name: str
|
||||||
|
description: Optional[str] = ""
|
||||||
|
rights: dict = Field(default={}, sa_column=Column(JSON))
|
||||||
|
|
||||||
|
|
||||||
|
class Role(RoleBase, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
role_type: RoleTypeEnum = RoleTypeEnum.DEFAULT
|
||||||
|
role_uuid: str
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
||||||
|
|
||||||
|
class RoleCreate(RoleBase):
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
pass
|
||||||
11
apps/api/src/rewrite/services/db/user_organizations.py
Normal file
11
apps/api/src/rewrite/services/db/user_organizations.py
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
from typing import Optional
|
||||||
|
from sqlmodel import Field, SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class UserOrganization(SQLModel, table=True):
|
||||||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
user_id: int = Field(default=None, foreign_key="user.id")
|
||||||
|
org_id: int = Field(default=None, foreign_key="organization.id")
|
||||||
|
role_id: int = Field(default=None, foreign_key="role.id")
|
||||||
|
creation_date: str
|
||||||
|
update_date: str
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from sqlmodel import Field, Session, SQLModel, create_engine, select
|
from sqlmodel import Field, SQLModel
|
||||||
|
|
||||||
|
|
||||||
class UserBase(SQLModel):
|
class UserBase(SQLModel):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from fastapi import Depends, Request
|
from fastapi import Request
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
from src.rewrite.services.db.users import User, UserCreate
|
from src.rewrite.services.db.users import User, UserCreate
|
||||||
from src.security.security import security_hash_password
|
from src.security.security import security_hash_password
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue