This commit is contained in:
2024-04-21 20:46:17 +00:00
parent 0e2ecd3449
commit 2ca7787dcb
17 changed files with 249 additions and 72 deletions

View File

@@ -5,7 +5,9 @@ from fastapi import Depends
from api.application.abstractions.uow import UnitOfWork
from api.application.protocols.password_hasher import PasswordHasher
from api.application.usecase.auth.create_user import CreateUser
from api.application.usecase.company.get_users_company import GetCompaniesByOwnerEmail
from api.application.usecase.company.create_company import CreateCompany
from api.application.usecase.company.get_users_company import \
GetCompaniesByOwnerEmail
from api.domain.company.repository import CompanyRepository
from api.domain.user.repository import UserRepository
from api.infrastructure.dependencies.stub import Stub
@@ -16,10 +18,18 @@ def provide_create_user(
uow: Annotated[UnitOfWork, Depends(Stub(UnitOfWork))],
password_hasher: Annotated[PasswordHasher, Depends(Stub(PasswordHasher))],
) -> CreateUser:
return CreateUser(uow=uow, user_repository=user_repository, password_hasher=password_hasher)
return CreateUser(
uow=uow, user_repository=user_repository, password_hasher=password_hasher
)
def provide_get_companies_by_email(
company_repository: Annotated[CompanyRepository, Depends(Stub(CompanyRepository))],
) -> GetCompaniesByOwnerEmail:
return GetCompaniesByOwnerEmail(company_repository=company_repository)
def provide_create_company(
company_repository: Annotated[CompanyRepository, Depends(Stub(CompanyRepository))]
) -> CreateCompany:
return CreateCompany(company_repository=company_repository)

View File

@@ -0,0 +1,4 @@
class TransactionContextManagerError(Exception):
def __init__(self, message: str, *args: object) -> None:
self.message = message
super().__init__(*args)

View File

@@ -1,13 +1,13 @@
import uuid
from sqlalchemy import UUID
from sqlalchemy import UUID, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column
from api.infrastructure.persistence.models.base import Base
class CompanyModel(Base):
__tablename__ = "companies"
__tablename__ = "company"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
@@ -15,3 +15,45 @@ class CompanyModel(Base):
)
name: Mapped[str]
email: Mapped[str] = mapped_column(unique=True)
address: Mapped[str]
owner_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("users.id", ondelete="CASCADE"),
)
class DepartmentModel(Base):
__tablename__ = "department"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
)
name: Mapped[str]
address: Mapped[str]
company_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("company.id", ondelete="CASCADE")
)
class CompanyDepartmentModel(Base):
__tablename__ = "company_department_m2m"
company_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("company.id", ondelete="CASCADE"),
primary_key=True,
)
department_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("department.id", ondelete="CASCADE"),
primary_key=True,
)
class DepartmentUserModel(Base):
__tablename__ = "department_user_m2m"
department_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("department.id", ondelete="CASCADE"),
primary_key=True,
)
user_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("users.id"),
primary_key=True,
)

View File

@@ -14,5 +14,6 @@ class UserModel(Base):
primary_key=True,
)
name: Mapped[str]
last_name: Mapped[str]
email: Mapped[str] = mapped_column(unique=True)
hashed_password: Mapped[str]

View File

@@ -1,30 +1,33 @@
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from api.domain.company.model import Company, CompanyEmail, CompanyId, CompanyName
from api.domain.company.model import (Company, CompanyAddress, CompanyEmail,
CompanyId, CompanyName)
from api.domain.company.repository import CompanyRepository
from api.domain.user.model import UserId
class SqlAlchemyCompanyRepository(CompanyRepository):
def __init__(self, session: AsyncSession) -> None:
self.session = session
# async def create_user(self, user: User) -> None:
# stmt = text(
# """INSERT INTO users (id, name, email, hashed_password)
# VALUES(:id, :name, :email, :hashed_password)
# """
# )
# await self.session.execute(
# stmt,
# {
# "id": str(user.id.value),
# "name": user.name.value,
# "email": user.email.value,
# "hashed_password": user.hashed_password,
# },
# )
#
async def create_company(self, company: Company) -> None:
stmt = text(
"""INSERT INTO company (id, name, email, address, owner_id)
VALUES(:id, :name, :email, :address, :owner_id)
"""
)
await self.session.execute(
stmt,
{
"id": str(company.id.value),
"name": company.name.value,
"email": company.email.value,
"address": company.address.value,
"owner_id": str(company.owner_id.value),
},
)
async def get_companies_by_owner_email(self, filter: dict) -> list[Company]:
stmt = text("""SELECT * FROM companies WHERE email = :val""")
result = await self.session.execute(stmt, {"val": filter["email"]})
@@ -36,6 +39,8 @@ class SqlAlchemyCompanyRepository(CompanyRepository):
id=CompanyId(c.id),
name=CompanyName(c.name),
email=CompanyEmail(c.email),
address=CompanyAddress(c.address),
owner_id=UserId(c.owner_id),
)
for c in result
]

View File

@@ -2,7 +2,8 @@ from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from api.domain.user import User, UserRepository
from api.domain.user.model import UserEmail, UserFirstName, UserId
from api.domain.user.model import (UserEmail, UserFirstName, UserId,
UserLastName)
class SqlAlchemyUserRepository(UserRepository):
@@ -11,8 +12,8 @@ class SqlAlchemyUserRepository(UserRepository):
async def create_user(self, user: User) -> None:
stmt = text(
"""INSERT INTO users (id, name, email, hashed_password)
VALUES(:id, :name, :email, :hashed_password)
"""INSERT INTO users (id, name, last_name, email, hashed_password)
VALUES(:id, :name, :last_name, :email, :hashed_password)
"""
)
await self.session.execute(
@@ -20,6 +21,7 @@ class SqlAlchemyUserRepository(UserRepository):
{
"id": str(user.id.value),
"name": user.name.value,
"last_name": user.last_name.value,
"email": user.email.value,
"hashed_password": user.hashed_password,
},
@@ -37,6 +39,7 @@ class SqlAlchemyUserRepository(UserRepository):
return User(
id=UserId(result.id),
name=UserFirstName(result.name),
last_name=UserLastName(result.last_name),
email=UserEmail(result.email),
hashed_password=result.hashed_password,
)

View File

@@ -0,0 +1,29 @@
from types import TracebackType
from sqlalchemy.ext.asyncio import AsyncSession
from api.infrastructure.persistence.error import TransactionContextManagerError
class SqlalchemyTransactionContextManager:
def __init__(self, session: AsyncSession):
self._session = session
async def __aenter__(self):
return self
async def __aexit__(
self,
exc_type: type[BaseException],
exc_val: BaseException,
exc_tb: TracebackType,
) -> None:
if exc_type:
await self.rollback()
raise TransactionContextManagerError(message="Transaction Error")
async def commit(self):
await self._session.commit()
async def rollback(self):
await self._session.rollback()