NicolasMendesMO (discussão | contribs)
NicolasMendesMO (discussão | contribs)
Limpou toda a página
Etiqueta: Anulando
Linha 1: Linha 1:
= Fase 2 =
<br>


== Escopo ==
<br>
* Desenvolver um sistema que facilite o encontro entre pessoas que estão à procura de um quarto para alugar e as que já possuem o quarto disponível para locação em seus imóveis
* A proposta é criar uma plataforma digital (via web) que funcione como um ''matchmaking'' de moradia, similar ao funcionamento de apps de relacionamento, com base em critérios como localização, orçamento, perfil de convivência e preferências pessoais
<br>
== Requisitos Funcionais ==
<br>
[RF001] Implementar visualização de detalhes (quarto e perfil)
[RF002] Implementar match
== Requisitos Não-Funcionais ==
<br>
== Melhores práticas ==
<br>
<b>Single Responsibility Principle - Responsabilidade Única</b>
A classe <code>class UserRepository(BaseRepository)</code> possui métodos de responsabilidade única como mostrado abaixo:
<pre>
    def get_user_by_id(self, user_id: int) -> Optional[User]:
        """Busca um usuário pelo ID."""
        stmt = select(User).where(User.id == user_id)
        result = self.execute_stmt(stmt)
        return result.scalar_one_or_none()
</pre>
Essa função tem uma única responsabilidade que é obter o usuário do repositório não aplicando sobre o usuário nenhum tipo de regra de negócio ou modificação.
<b>Open/Closed Principle - Aberto para Extensão, Fechado para Modificação</b>
A classe <code>class UserService</code> tem métodos que estão fechados para modificação mas a classe pode ser extendida adicionando novos métodos, como mostrado abaixo:
<pre>
class UserService:
    def __init__(self, user_repository: UserRepository):
        self.user_repository = user_repository
    def create_user(self, name: str, email: str, senha: str, birthday: Date, profile_picture_path: str, description: str = None) -> User:
        # Verificar se já existe um usuário com este e-mail
        existing_user = self.user_repository.get_user_by_email(email)
        if existing_user:
            raise ValueError("Este e-mail já está cadastrado")
        # Hash the password before storing
        hashed_password = bcrypt.hashpw(senha.encode('utf-8'), bcrypt.gensalt())
        return self.user_repository.create_user(
            name=name,
            email=email,
            senha=hashed_password.decode('utf-8'),
            birthday=birthday,
            profile_picture_path=profile_picture_path,
            description=description
        )
    def get_user_by_id(self, user_id: int) -> Optional[User]:
        return self.user_repository.get_user_by_id(user_id)
    def update_user(self, user_id: int, **kwargs) -> Optional[User]:
        return self.user_repository.update_user(user_id, **kwargs)
    def delete_user(self, user_id: int) -> bool:
        return self.user_repository.delete_user(user_id)
   
    def get_user_by_email(self, email: str) -> Optional[User]:
        """Busca um usuário pelo email."""
        return self.user_repository.get_user_by_email(email)
    def authenticate_user(self, email: str, senha: str) -> Optional[User]:
        """Autentica um usuário verificando email e senha"""
        user = self.user_repository.get_user_by_email(email)
        if not user:
            return None
       
        if not bcrypt.checkpw(senha.encode('utf-8'), user.senha.encode('utf-8')):
            return None
       
        return user
</pre>
<b>Liskov Substitution Principle - Substituição de Liskov</b>
Todas as classes que fazem parte de um repositório herdam/implementam <code>BaseRepository</code>, como exemplo temos a classe <code>UserRepository</code>.
<pre>
class UserRepository(BaseRepository):
    def __init__(self, session: Session):
        super().__init__(session)
class BaseRepository:
    """
    Repositório base que recebe uma sessão como dependência.
    Segue o princípio de Inversão de Dependência.
    """
   
    def __init__(self, session: Session):
        """
        Inicializa o repositório com uma sessão do banco de dados.
       
        Args:
            session: Sessão do SQLAlchemy gerenciada externamente
        """
        self.session = session
   
    def execute_stmt(self, stmt: Any):
        """
        Executa um statement SQLAlchemy usando a sessão injetada.
       
        Args:
            stmt: Statement SQLAlchemy (select, insert, update, delete, etc.)
           
        Returns:
            Resultado da execução do statement
        """
        return self.session.execute(stmt)
</pre>
<b>Interface Segregation Principle - Segregação de Interfaces</b>
A linguagem Python não implementa interfaces que expõe métodos, com isso não foi possível aplicar esse princípio no projeto
<b>Dependency Inversion Principle - Inversão de Dependência</b>
Mesmo sem a presença se interfaces o que facilita a inversão de depedência, conseguimos aplicar este princípio criando um classe referente a repositório que faz a instanciação do banco de dados assim que a classe é criada não sendo necessário repetir o código novamente.
<pre>
class UserRepository(BaseRepository):
    def __init__(self, session: Session):
        super().__init__(session)
class BaseRepository:
    """
    Repositório base que recebe uma sessão como dependência.
    Segue o princípio de Inversão de Dependência.
    """
   
    def __init__(self, session: Session):
        """
        Inicializa o repositório com uma sessão do banco de dados.
       
        Args:
            session: Sessão do SQLAlchemy gerenciada externamente
        """
        self.session = session
   
    def execute_stmt(self, stmt: Any):
        """
        Executa um statement SQLAlchemy usando a sessão injetada.
       
        Args:
            stmt: Statement SQLAlchemy (select, insert, update, delete, etc.)
           
        Returns:
            Resultado da execução do statement
        """
        return self.session.execute(stmt)
</pre>
<b>Clean Code</b>
O código foi pensado para possuir métodos simples e fáceis de entender e dar manutenção, além de possuir variáveis com nomes que refletem as propriedades do objeto facilitando assim o entendimento da lógica do código.
= Evolução do projeto =
{| class="wikitable"
|-
! Item !! Data !! Atividades Room Match !! Realizado
|-
| 1 || 14/11/2025 || Documentar tópico Investigação || 0%
|-
| 2 || 14/11/2025 || Definir Proposta de Projeto || 0%
|-
| 3 || 14/11/2025 || Validar Visão do Usuário || 0%
|-
| 4 || 14/11/2025 || Especificar RFs e RNFs - Fase 2 || 100%
|-
| 5 || 17/11/2025 || RF01: Implementar visualização de detalhes || 25%
|-
| x || 24/11/2025 || TeckWeek ||
|-
| 6 || 01/12/2025 || Melhores Práticas ||
|-
| 7 || 01/12/2025 || RF01: Implementar visualização de detalhes ||
|-
| 8 || 01/12/2025 || RF02: Implementar match ||
|-
| 9 || || Desenvolver 3o RF ||
|-
| 10 || || Desenvolver 4o RF ||
|-
| 11 || || Incrementar diferencial tecnológico ||
|-
|}

Edição das 00h53min de 2 de dezembro de 2025