Dominio - Yago-Captain/GeneralNotes GitHub Wiki

MyGeneralNotes.Domain

Este subdiretório contém as entidades, enums e interfaces do domínio. Ele é fundamental para modelar o problema de negócio que a aplicação se propõe a resolver. Aqui, cada classe e interface tem um propósito específico:

  • Entidades e Enums: As entidades capturam os objetos principais que a aplicação gerencia, enquanto os enums ajudam a restringir os valores que certos atributos das entidades podem ter, tornando o código mais seguro e fácil de manter.
  • Interfaces: As interfaces definem contratos para a lógica do usuário, rotinas de exercícios e questões de segurança. Elas são usadas para garantir que a implementação siga um conjunto específico de métodos e propriedades.

Nos próximos tópicos, detalharei cada classe e interface dentro do diretório MyGeneralNotes.Domain. A seguir, você encontrará uma explicação sobre o propósito de cada componente e como eles se inter-relacionam para formar a lógica do domínio da aplicação:

  • Entidades: Classes que representam os principais objetos do sistema, como User, Routine e Exercise.
  • Enums: Tipos enumerados que ajudam a definir valores fixos para certos atributos, como DayOfWeek e ExerciseLocation.
  • Interfaces: Contratos que definem as operações permitidas em entidades específicas, como IUserReadOnlyRepository e IRoutineWriteOnlyRepository.
  • Classes de Extensão: Métodos adicionais que estendem as funcionalidades de tipos básicos, como StringExtension e BooleanExtension.

A seguir, apresentarei cada um desses componentes em detalhes, começando pelas entidades e enums, seguidos das interfaces e, finalmente, as classes de extensão.

Entidades e Enums

As entidades e enums trabalham juntos para modelar o domínio do problema. As entidades capturam os objetos principais que o aplicativo precisa gerenciar, enquanto os enums ajudam a restringir os valores que certos atributos das entidades podem ter, tornando o código mais seguro e fácil de manter. Para criar o banco de dados e as tabelas da aplicação, está sendo utilizada uma abordagem code-first, ou seja, o banco de dados e todas as tabelas serão criadas a partir das entidades da aplicação por meio do ORM EntityFrameworkCore.

Logo abaixo, estarão todas as entidades de domínio e enums da aplicação:

EntityBase

namespace MyGeneralNotes.Domain.Entities; 

public class EntityBase 
{ 
    public long Id { get; set; } 
    public bool Active { get; set; } = true; 
    public DateTime CreatedOn { get; set; } = DateTime.UtcNow; 
}

Esta é a classe base para todas as suas entidades. Ela contém propriedades que são comuns a todas as entidades no seu domínio.

  • Id: É a chave primária, um identificador único para cada instância de uma entidade.
  • Active: É um booleano que indica se a entidade está ativa ou não.
  • CreatedOn: É a data e hora em que a entidade foi criada.

User

namespace MyGeneralNotes.Domain.Entities; 

public class User : EntityBase 
{ 
    public string Name { get; set; } = string.Empty;     
    public string Email { get; set; } = string.Empty;     
    public string Password { get; set; } = string.Empty;     
    public Guid UserIdentifier { get; set; } 
}

Esta classe representa um usuário no seu sistema. Ela herda de EntityBase, então também tem um Id, Active e CreatedOn. Além disso, ela tem propriedades específicas dos usuários, como:

  • Name: O nome do usuário.
  • Email: O endereço de email do usuário.
  • Password: A senha do usuário.
  • UserIdentifier: Um identificador único para o usuário.

Routine

namespace MyGeneralNotes.Domain.Entities; 

public class Routine : EntityBase 
{ 
    public string Name { get; set; } = string.Empty;     
    public DayOfWeek DayOfWeek { get; set; } 
    public List<Exercise> Exercises { get; set; } = new List<Exercise>();     
    public long UserId { get; set; } 
}

Esta classe representa uma rotina de exercícios. Ela está associada a um User através da propriedade UserId. Uma rotina tem um Name, um DayOfWeek e uma lista de Exercises.

  • Name: O nome da rotina.
  • DayOfWeek: O dia da semana em que a rotina deve ser realizada.
  • Exercises: Uma lista de exercícios que fazem parte da rotina.
  • UserId: A chave estrangeira que liga a rotina a um usuário.

Exercise

using MyGeneralNotes.Domain.Enum; 

namespace MyGeneralNotes.Domain.Entities; 

public class Exercise : EntityBase 
{ 
    public string Name { get; set; } = string.Empty;     
    public ExerciseLocation Location { get; set; }     
    public double Charge { get; set; }      
    public int Repetitions { get; set; }      
    public int RestTime { get; set; }      
    public string Equipment { get; set; } = string.Empty;     
    public string Details { get; set; } = string.Empty;     
    public long RoutineId { get; set; } 
}

Esta classe representa um exercício individual em uma rotina. Ela está associada a uma Routine através da propriedade RoutineId. Um exercício tem várias propriedades, como:

  • Name: O nome do exercício.
  • Location: A localização do exercício (Ginásio ou Casa).
  • Charge: A carga do exercício em quilogramas.
  • Repetitions: O número total de repetições do exercício.
  • RestTime: O tempo de descanso entre as séries do exercício.
  • Equipment: O equipamento necessário para o exercício.
  • Details: Detalhes adicionais sobre o exercício.
  • RoutineId: A chave estrangeira que liga o exercício a uma rotina.

DayOfWeek

namespace MyGeneralNotes.Domain.Enum; 

public enum DayOfWeek 
{ 
    Sunday = 1, 
    Monday = 2,     
    Tuesday = 3, 
    Wednesday = 4, 
    Thursday = 5, 
    Friday = 6, 
    Saturday = 7 
}

Este é um enum que representa os dias da semana. Ele é usado na classe Routine para indicar em que dia da semana a rotina deve ser realizada.

ExerciseLocation

namespace MyGeneralNotes.Domain.Enum; 

public enum ExerciseLocation 
{ 
    Gym = 1, 
    Home = 2, 
}

Este é um enum que representa a localização de um exercício. Ele é usado na classe Exercise para indicar onde o exercício deve ser realizado.

Relações entre as Entidades

As entidades no domínio da aplicação MyGeneralNotes estão inter-relacionadas para refletir a estrutura e as regras do domínio de negócios. Aqui estão os principais relacionamentos entre as entidades:

  1. User e Routine:

    • Um User pode ter várias Routines. Isso significa que um único usuário pode criar e gerenciar múltiplas rotinas de exercícios.
    • Uma Routine pertence a um User. Cada rotina é associada a um usuário específico através da propriedade UserId, que atua como uma chave estrangeira ligando a rotina ao seu respectivo usuário.
  2. Routine e Exercise:

    • Uma Routine pode ter vários Exercises. Isso significa que cada rotina pode incluir uma lista de diferentes exercícios que devem ser realizados.
    • Um Exercise pertence a uma Routine. Cada exercício está associado a uma rotina específica através da propriedade RoutineId, que atua como uma chave estrangeira ligando o exercício à sua rotina correspondente.

Explicação Detalhada das Relações

  • User e Routine:

    • User: Representa um usuário do sistema, contendo informações como nome, e-mail, senha e um identificador único.
    • Routine: Representa uma rotina de exercícios, que inclui um nome, dia da semana em que deve ser realizada, uma lista de exercícios e o identificador do usuário a quem pertence.
  • Routine e Exercise:

    • Routine: Além de estar associada a um usuário, uma rotina contém uma lista de exercícios (Exercises) que descrevem as atividades a serem realizadas.
    • Exercise: Cada exercício inclui detalhes como nome, localização, carga, repetições, tempo de descanso, equipamento necessário e uma descrição. Está vinculado a uma rotina específica através da propriedade RoutineId.

Diagrama de Relações

Aqui está um resumo visual das relações:

User (1) -------------- (N) Routine
Routine (1) ----------- (N) Exercise
  • User: 1 -> N -> Routine
    • Um usuário pode ter múltiplas rotinas.
  • Routine: 1 -> N -> Exercise
    • Uma rotina pode incluir múltiplos exercícios.

Com essas relações, a estrutura da aplicação pode gerenciar usuários e suas respectivas rotinas de exercícios, onde cada rotina possui uma série de exercícios detalhados.

Classes de Extensão

StringExtension

using System.Diagnostics.CodeAnalysis;

namespace MyGeneralNotes.Domain.Extensions;

public static class StringExtension
{
    public static bool NotEmpty([NotNullWhen(true)] this string? value) => string.IsNullOrEmpty(value).IsFalse();
}

Esta classe estática contém o seguinte método de extensão:

  • NotEmpty(this string? value): Este método verifica se uma string fornecida não está vazia. Ele usa o método IsNullOrEmpty da classe string para verificar se a string é nula ou vazia e então chama o método IsFalse para inverter o resultado. Se a string não estiver vazia, o método retorna true; caso contrário, retorna false.

BooleanExtension

namespace MyGeneralNotes.Domain.Extensions;

public static class BooleanExtension
{
    public static bool IsFalse(this bool value) => !value;
}

Esta classe estática contém o seguinte método de extensão:

  • IsFalse(this bool value): Este método inverte o valor booleano fornecido. Se o valor for true, o método retorna false; se o valor for false, o método retorna true.

Interfaces

IUserReadOnlyRepository

namespace MyGeneralNotes.Domain.Repositories.User;

public interface IUserReadOnlyRepository 
{ 
    public Task<bool> ExistActiveUserWithEmail(string email);     
    public Task<Entities.User?> GetUserByEmailAndPassword(string email, string password); 
    public Task<bool> ExistActiveUserWithIdentifier(Guid userIdentifier); 
    public Task<Entities.User> GetByUserIdentifier(Guid userIdentifier); 
}

Esta interface é usada para operações de leitura em um usuário. Ela contém os seguintes métodos:

  • ExistActiveUserWithEmail(string email): Este método verifica se existe um usuário ativo com o e-mail fornecido.
  • GetUserByEmailAndPassword(string email, string password): Este método retorna um usuário baseado no e-mail e senha fornecidos.
  • ExistActiveUserWithIdentifier(Guid userIdentifier): Este método verifica se existe um usuário ativo com o identificador de usuário fornecido.
  • GetByUserIdentifier(Guid userIdentifier): Este método retorna um usuário baseado no identificador de usuário fornecido.

IUserUpdateOnlyRepository

namespace MyGeneralNotes.Domain.Repositories.User;

public interface IUserUpdateOnlyRepository 
{ 
    public Task<Entities.User> GetById(long id);     
    public void Update(Entities.User user); 
}

Esta interface é usada para operações de atualização em um usuário. Ela contém os seguintes métodos:

  • GetById(long id): Este método retorna um usuário baseado no ID fornecido.
  • Update(Entities.User user): Este método atualiza um usuário existente.

IUserWriteOnlyRepository

namespace MyGeneralNotes.Domain.Repositories.User;

public interface IUserWriteOnlyRepository 
{ 
    public Task Add(Entities.User user); 
}

Esta interface é usada para operações de gravação em um usuário. Ela contém o seguinte método:

  • Add(Entities.User user): Este método adiciona um novo usuário.

IRoutineReadOnlyRepository

namespace MyGeneralNotes.Domain.Repositories.Routine;

public interface IRoutineReadOnlyRepository 
{ 
    Task<IList<Entities.Routine>> GetAllUserRoutines(long userId); 
    Task<Entities.Routine?> GetRoutine(long routineId); 
}

Esta interface é usada para operações de leitura em uma rotina. Ela contém os seguintes métodos:

  • GetAllUserRoutines(long userId): Este método retorna todas as rotinas de um usuário baseado no ID do usuário fornecido.
  • GetRoutine(long routineId): Este método retorna uma rotina baseada no ID da rotina fornecida.

IRoutineUpdateOnlyRepository

namespace MyGeneralNotes.Domain.Repositories.Routine;

public interface IRoutineUpdateOnlyRepository 
{ 
    Task<Entities.Routine?> GetById(long routineId);     
    void Update(Entities.Routine routine); 
}

Esta interface é usada para operações de atualização em uma rotina. Ela contém os seguintes métodos:

  • GetById(long routineId): Este método retorna uma rotina baseada no ID da rotina fornecida.
  • Update(Entities.Routine routine): Este método atualiza uma rotina existente.

IRoutineWriteOnlyRepository

namespace MyGeneralNotes.Domain.Repositories.Routine;

public interface IRoutineWriteOnlyRepository 
{ 
    Task Register(Entities.Routine routine); 
    Task Delete(long routineId); 
}

Esta interface é usada para operações de gravação em uma rotina. Ela contém os seguintes métodos:

  • Register(Entities.Routine routine): Este método registra uma nova rotina.
  • Delete(long routineId): Este método deleta uma rotina baseada no ID da rotina fornecida.

IPasswordEncrypter

namespace MyGeneralNotes.Domain.Security.Cryptography;

public interface IPasswordEncrypter 
{ 
    public string Encrypt(string password); 
}

Esta interface é usada para operações de criptografia de senha. Ela contém o seguinte método:

  • Encrypt(string password): Este método criptografa uma senha fornecida e retorna a senha criptografada.

IAccessTokenGenerator

namespace MyGeneralNotes.Domain.Security.Tokens;

public interface IAccessTokenGenerator 
{ 
    public string Generate(Guid userIdentifier); 
}

Esta interface é usada para gerar tokens de acesso. Ela contém o seguinte método:

  • Generate(Guid userIdentifier): Este método gera um token de acesso para um identificador de usuário fornecido e retorna o token de acesso.

IAccessTokenValidator

namespace MyGeneralNotes.Domain.Security.Tokens;

public interface IAccessTokenValidator 
{ 
    public Guid ValidateAndGetUserIdentifier(string token); 
}

Esta interface é usada para validar tokens de acesso. Ela contém o seguinte método:

  • ValidateAndGetUserIdentifier(string token): Este método valida um token de acesso fornecido e retorna o identificador do usuário associado a esse token.

ITokenProvider

namespace MyGeneralNotes.Domain.Security.Tokens;

public interface ITokenProvider 
{ 
    public string Value(); 
}

Esta interface é usada para fornecer tokens de acesso. Ela contém o seguinte método:

  • Value(): Este método retorna o valor do token de acesso atual.

ILoggedUser

using MyGeneralNotes.Domain.Entities;

namespace MyGeneralNotes.Domain.Services.LoggedUser;

public interface ILoggedUser 
{ 
    public Task<User> User(); 
}

IUnitOfWork

namespace MyGeneralNotes.Domain.Repositories
{
    public interface IUnitOfWork
    {
        public Task Commit();
    }
}

Esta interface é responsável por definir um contrato para a unidade de trabalho. No padrão de design Repository, uma unidade de trabalho é responsável por agrupar todas as operações de persistência de dados em uma única transação. Isso garante que todas as operações sejam executadas com sucesso ou que nenhuma delas seja persistida no banco de dados. Ela contém o seguinte método:

  • Commit(): Este método é usado para confirmar todas as operações pendentes na unidade de trabalho e efetivar as mudanças no banco de dados. Ele geralmente é chamado após todas as operações de leitura e gravação terem sido concluídas com sucesso.

O uso da interface IUnitOfWork ajuda a manter a consistência e a integridade dos dados, garantindo que as transações sejam tratadas de forma adequada e que as operações de persistência sejam executadas de maneira eficiente.

Esta interface é usada para operações relacionadas ao usuário logado. Ela contém o seguinte método:

  • User(): Este método retorna um objeto User que representa o usuário atualmente logado. Ele permite recuperar as informações do usuário que está atualmente autenticado no sistema.

Encerramento do Domínio

Esta seção cobriu detalhadamente a estrutura do domínio da nossa aplicação, incluindo as entidades, enums, interfaces e classes de extensão. Com essa compreensão sólida do domínio, estamos prontos para avançar para a próxima etapa, onde exploraremos a infraestrutura subjacente que suporta a lógica de negócios do nosso sistema.

Na próxima página, abordaremos os detalhes da infraestrutura, incluindo acesso a dados, serviços externos e configurações de segurança. Vamos nos aprofundar nos aspectos técnicos que sustentam a funcionalidade do nosso aplicativo.


Próxima: MyGeneralNotes.Infrastructure

⚠️ **GitHub.com Fallback** ⚠️