diff --git a/backend/api/post.py b/backend/api/post.py new file mode 100644 index 0000000..9cc200b --- /dev/null +++ b/backend/api/post.py @@ -0,0 +1,16 @@ +from fastapi import APIRouter, Depends +from ..services import PostService, UserService +from ..models import Post +from .authentication import registered_user + +api = APIRouter(prefix="/api/post") + + +@api.post("", response_model=Post, tags=['Post']) +def create(post: Post, post_svc: PostService = Depends(), usr_svc: UserService = Depends()): + user_entity = usr_svc.findUser(post.user) + return post_svc.create(post,user_entity) + +@api.get("", response_model=list[Post], tags=['Post']) +def getAll(post_svc: PostService = Depends()): + return post_svc.getAll() diff --git a/backend/entities/__init__.py b/backend/entities/__init__.py index 8f3a6ef..4c82a91 100644 --- a/backend/entities/__init__.py +++ b/backend/entities/__init__.py @@ -18,6 +18,7 @@ from .role_entity import RoleEntity from .permission_entity import PermissionEntity from .user_role_entity import user_role_table +from .post_entity import PostEntity __authors__ = ["Kris Jordan"] diff --git a/backend/entities/post_entity.py b/backend/entities/post_entity.py index f1b8546..c1223b3 100644 --- a/backend/entities/post_entity.py +++ b/backend/entities/post_entity.py @@ -1,14 +1,16 @@ '''User accounts for all registered users in the application.''' -from sqlalchemy import Integer, String +from sqlalchemy import Integer, String, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, relationship from typing import Self from .entity_base import EntityBase -from .user_role_entity import user_role_table -from ..models import User +#from ..models import User from ..models import Post - +from fastapi import Depends +from .user_entity import UserEntity +from .post_votes_entity import post_votes_table +#from ..services import UserPostService __authors__ = ['Kris Jordan'] __copyright__ = 'Copyright 2023' @@ -16,32 +18,43 @@ class PostEntity(EntityBase): - __tablename__ = 'user' + __tablename__ = 'posts' id: Mapped[int] = mapped_column(Integer, primary_key=True) content: Mapped[str] = mapped_column(String(64), nullable=False, default='') - user: Mapped[User] = mapped_column(User, nullable=False, default='') - votes: Mapped[list[User]] + + user_id: Mapped[int] = mapped_column(ForeignKey('user.id')) + user: Mapped[UserEntity] = relationship("UserEntity",back_populates='posts') + + votes: Mapped[list[UserEntity]] = relationship(secondary=post_votes_table) + timestamp: Mapped[str] = mapped_column(String(64), nullable=False, default='') @classmethod - def from_model(cls, model: Post) -> Self: + def from_model(cls, model: Post, user: UserEntity ) -> Self: + #user_svc: UserPostService = Depends() return cls( id=model.id, content=model.content, - user=model.user, - votes=model.votes, + user = user, + votes= [], timestamp=model.timestamp, + + #user_svc.findUser(model.user) + #[user_svc.findUser(vote) for vote in model.votes] ) def to_model(self) -> Post: + vote_num = [vote.to_model() for vote in self.votes] return Post( id=self.id, content=self.content, - user=self.user, - votes=self.votes, + user=self.user.to_model(), + votes=vote_num, timestamp=self.timestamp, ) def update(self, model: Post) -> None: self.content = model.content + + diff --git a/backend/entities/post_votes_entity.py b/backend/entities/post_votes_entity.py new file mode 100644 index 0000000..471e872 --- /dev/null +++ b/backend/entities/post_votes_entity.py @@ -0,0 +1,9 @@ +from sqlalchemy import Table, Column, ForeignKey +from .entity_base import EntityBase + +post_votes_table = Table( + "post_votes", + EntityBase.metadata, + Column('user_id', ForeignKey('user.id'), primary_key=True), + Column('post_id', ForeignKey('posts.id'), primary_key=True) +) \ No newline at end of file diff --git a/backend/entities/role_entity.py b/backend/entities/role_entity.py index ea317c4..45fe5e3 100644 --- a/backend/entities/role_entity.py +++ b/backend/entities/role_entity.py @@ -12,7 +12,7 @@ class RoleEntity(EntityBase): id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String, unique=True) - users: Mapped[list['UserEntity']] = relationship(secondary=user_role_table, back_populates='roles') + users: Mapped[list['UserEntity']] = relationship(secondary=user_role_table) permissions: Mapped[list['PermissionEntity']] = relationship(back_populates='role') @classmethod diff --git a/backend/entities/user_entity.py b/backend/entities/user_entity.py index 15cdc61..ab475bd 100644 --- a/backend/entities/user_entity.py +++ b/backend/entities/user_entity.py @@ -1,12 +1,13 @@ '''User accounts for all registered users in the application.''' -from sqlalchemy import Integer, String +from sqlalchemy import Integer, String, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, relationship from typing import Self from .entity_base import EntityBase from .user_role_entity import user_role_table from ..models import User +from .post_votes_entity import post_votes_table __authors__ = ['Kris Jordan'] @@ -32,6 +33,12 @@ class UserEntity(EntityBase): roles: Mapped[list['RoleEntity']] = relationship(secondary=user_role_table, back_populates='users') permissions: Mapped['PermissionEntity'] = relationship(back_populates='user') + + #create Secondary table for posts??? + posts: Mapped[list['PostEntity']] = relationship(back_populates='user') + + votes: Mapped[list['PostEntity']] = relationship(secondary=post_votes_table, back_populates='votes') + @classmethod def from_model(cls, model: User) -> Self: diff --git a/backend/main.py b/backend/main.py index 6bfad33..7ab8457 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,7 +1,7 @@ """Entrypoint of backend API exposing the FastAPI `app` to be served by an application server such as uvicorn.""" from fastapi import FastAPI -from .api import health, static_files, profile, authentication, user +from .api import health, static_files, profile, authentication, user, post from .api.admin import users as admin_users from .api.admin import roles as admin_roles @@ -26,4 +26,5 @@ app.include_router(authentication.api) app.include_router(admin_users.api) app.include_router(admin_roles.api) +app.include_router(post.api) app.mount("/", static_files.StaticFileMiddleware(directory="./static")) \ No newline at end of file diff --git a/backend/models/__init__.py b/backend/models/__init__.py index 6255f08..0450829 100644 --- a/backend/models/__init__.py +++ b/backend/models/__init__.py @@ -5,6 +5,12 @@ from .user import User, ProfileForm, NewUser from .role import Role from .role_details import RoleDetails +from .post import Post +# import sys +# sys.path.append("/workspace/backend/models") +# import + + __authors__ = ["Kris Jordan"] __copyright__ = "Copyright 2023" diff --git a/backend/models/post.py b/backend/models/post.py index b3370b9..81caf06 100644 --- a/backend/models/post.py +++ b/backend/models/post.py @@ -3,11 +3,13 @@ from pydantic import BaseModel from . import User - class Post(BaseModel): id: int | None = None content: str - user: User - votes: list[User] + user: 'User' + votes: list['User'] = [] timestamp: str + + + diff --git a/backend/services/__init__.py b/backend/services/__init__.py index 5408cff..13ce1d7 100644 --- a/backend/services/__init__.py +++ b/backend/services/__init__.py @@ -1,3 +1,5 @@ from .user import UserService from .permission import PermissionService, UserPermissionError -from .role import RoleService \ No newline at end of file +from .role import RoleService +from .post import PostService +from .user_post import UserPostService \ No newline at end of file diff --git a/backend/services/post.py b/backend/services/post.py new file mode 100644 index 0000000..9cb337b --- /dev/null +++ b/backend/services/post.py @@ -0,0 +1,28 @@ +from fastapi import Depends +from sqlalchemy import select, or_, func +from sqlalchemy.orm import Session +from ..database import db_session +from ..models import User, Role, RoleDetails, Permission, Post +from ..entities import RoleEntity, PermissionEntity, UserEntity +from ..entities.post_entity import PostEntity +from .permission import PermissionService, UserPermissionError + + +class PostService: + + def __init__(self, session: Session = Depends(db_session), permission: PermissionService = Depends()): + self._session = session + self._permission = permission + + def create(self, post: Post, user: UserEntity) -> Post: + entity = PostEntity.from_model(post,user) + self._session.add(entity) + self._session.commit() + return entity.to_model() + user_entity = user_svc.findUser(post.user) + return None + + def getAll(self) -> list[Post]: + query = select(PostEntity) + entities = self._session.scalars(query).all() + return [entity.to_model() for entity in entities] \ No newline at end of file diff --git a/backend/services/user.py b/backend/services/user.py index 3bf9f16..67a1a6e 100644 --- a/backend/services/user.py +++ b/backend/services/user.py @@ -64,6 +64,14 @@ def search(self, _subject: User, query: str) -> list[User]: statement = statement.where(criteria).limit(10) entities = self._session.execute(statement).scalars() return [entity.to_model() for entity in entities] + + def findUser(self, _subject: User) -> UserEntity: + # query = select(UserEntity).filter_by(id=_subject.id) + query = select(UserEntity).where(UserEntity.pid == _subject.pid) + user_entity: UserEntity = self._session.execute(query).scalar() + return user_entity + + def list(self, subject: User, pagination_params: PaginationParams) -> Paginated[User]: """List Users. @@ -148,3 +156,4 @@ def update(self, subject: User, user: User) -> User: entity.update(user) self._session.commit() return entity.to_model() + diff --git a/backend/services/user_post.py b/backend/services/user_post.py new file mode 100644 index 0000000..ef09c81 --- /dev/null +++ b/backend/services/user_post.py @@ -0,0 +1,22 @@ +from fastapi import Depends +from sqlalchemy import select, or_, func +from sqlalchemy.orm import Session +from ..database import db_session +from ..models import User, Paginated, PaginationParams +from ..entities import UserEntity +from .permission import PermissionService +from . import * + +class UserPostService: + + _session: Session + _permission: PermissionService + + def findUser(self, _subject: User, user_svc: 'UserService' = Depends()) -> UserEntity: + return user_svc.findUser(_subject) + + + + + +