“Tudo o que temos de decidir é o que fazer com o tempo que nos é dado"
- Apresentação do Projeto
- Design da Aplicação, Tecnologias e Abordagens utilizadas
- Glossário
- Contextos Delimitados
- Modelagens
- Camadas da Aplicação
- Controllers
- Features
- Desafios e Proximos Passos
- Requirements
- Get Started
- Agradecimentos
- Desenvolvedores
O objetivo do presente projeto é atender os critérios do desafio final da turma de .NET da Raro Academy, sintetizando todo o conteúdo visto nas ultimas 10 semanas por meio de aulas síncronas na plataforma Zoom e monitorias diárias.
Como motivação, nos foi apresentado a proposta de projeto pelo cliente Raro Labs, que pretende gradualmente parar de usar software de terceiros para realizar a gestão de horas que são destinadas a projetos pelos seus colaboradores.
Para isso, se viu necessário a criação de uma solução que atendesse as expectativas do cliente.
Essa solução se chama Chronos v1.0
O design escolhido para a arquitetura do software foi o Domain-Driven-Design (DDD). Essa modelagem consiste (de uma maneira bem abstrata) em camadas de design de dados, design estratégico e design tático, este ultimo somente funcionando se o design estratégico funcionar de maneira excepcional.
Desse modo, o primeiro passo da modelagem do nosso sistema foi realizar a montagem do Glossário a ser utilizado ao longo da aplicação para estabelecer uma linguagem ubíqua(universal) que facilitasse a comunicação entre os desenvolvedores e os stakeholders.
Com o glossário em mãos, o próximo passo a ser realizado, ainda no design estratégico, foi traçar os Contextos Delimitados da aplicação (Bounded Contexts) para após isso, engatinhar para a a modelagem.
Para facilitar a construção da aplicação, realizamos inicialmente o Diagrama de Entidade-Relacionamento para começarmos a ter uma idéia do que precisariamos persistir no banco de dados.
Feito isso, o próximo passo foi começar a pensar nas classes, interfaces, e contratos que provavelmente utilizariamos ao desenvolver o software. Nessa etapa, diversas mudanças foram feitas ao adentrar mais e mais no problema e entender o que realmente precisariamos realizar para alcançar o que nos era solicitado. Para isso, realizamos o Diagrama de Classes para auxiliar nesse processo.
O próximo processo foi realmente colocar "as mãos no código". Seguindo a arquitetura do DDD, as Camadas da Aplicação foram executadas, testadas e documentadas, sempre seguindo também as boas práticas S.O.L.I.D para manter o código limpo, legível e escalável.
O projeto foi realizado utilizando a plataforma de desenvolvimento open source .NET Core 6.
A solução de banco de dados relacional utilizada foi o Microsoft SQL Server.
A comunicação com o serviço Toggl foi feita por meio da integração com o Toggl Api.
Para facilitar a persistência dos dados e comunicação com o banco de dados, utilizamos a biblioteca O/RM Entity Framework Core
Algumas outras bibliotecas externas utilizadas ao longo do desenvolvimento:
- Autofixture v4.17.0
- Automapper v12.0.0
- Bogus v34.0.2
- FluentValidation v11.3.0
- Newtonsoft.Json v9.0.1
- Bcrypt v
- Moq v4.18.2
- Moq.EntityFrameworkCore v6.0.1.4
- NetCORE.MailKit v2.1.0
- Miro
- Draw.io
- Usuário: qualquer pessoa cadastrada na solução Chronos. Um usuário pode ser Colaborador e Administrador.
- Projeto: Representação do projeto na solução. Um Usuário participar de nenhum ou vários projetos. Um projeto pode ter nenhum ou vários usuários inseridos.
- Usuario_Projeto: Representação da relação entre projeto e usuário. Obrigatoriamente precisa ter um projeto e um usuário. Uma relação Usuario_Projeto pode ter zero ou várias tarefas.
- Tarefa: Representação das tarefas realizadas pelos usuários cadastrados na solução. Uma tarefa obrigatoriamente precisa ser vinculada a um e somente um Usuario_Projeto.
- ConfirmacaoToken: Token criado para a confirmação do e-mail do usuário.
- CodigoResetSenha: Código criado para o reset da senha de um usuário.
- Relatório de Horas: Representação de uma lista de tarefas, contendo total de horas, descrição, data inicial, data final da tarefa e nome do projeto.
- Integração com Toggl: comunicação com o serviço externo Toggl, que era responsável pelo registro total das horas trabalhadas dos colaboradores Raro.
- Usuario
- Todo usuário deverá ser cadastrado e para acessar a solução, precisa autenticar seu e-mail.
- Um usuário pode ser administrador ou colaborador, mas mantem outras caracteristicas iguais.
- Um colaborador somente pode alterar e ver suas informações.
- Um administrador pode alterar, ver e deletar todos os usuários.
- Autenticação
- Um usuário precisa ter seu e-mail autenticado para acesso total a solução Chronos.
- Um usuário pode efetuar login no sistema usando seu e-mail confirmado e senha.
- Projetos
- Apenas usuários administradores podem ver, deletar, criar, editar e adicionar outros usuários em todos os projetos.
- Usuários colaboradores podem apenas ver os projetos em que estão inseridos.
- Tarefas
- Qualquer usuário pode efetuar cadastro de uma tarefa na solução, desde que esteja participando de um projeto.
- Um usuário colaborador só pode ver o seu relatório de horas, editar, ver, iniciar, parar e excluir suas tarefas.
- Um usuário administrador pode ver todos os relatório de horas, editar, ver, iniciar, parar e excluir as tarefas de todos os usuários.
- Uma tarefa só pode ser iniciada se não tiver sido iniciada ou finalizada.
- Uma tarefa só pode ser finalizada se não tiver sido finalizada e já tiver sido iniciada.
- Toggl
- Um usuário administrador pode solicitar a visualização e importação dos dados da plataforma de terceiros Toggl. Para realizar a importação para o banco de dados, o usuário responsável pela tarefa precisa já estar cadastrado no Chronos. Apenas administradores podem solicitar a importação dos dados para banco de dados.
- Foi realizado uma Modelagem no Miro, para melhor visualização dos contextos e suas interações com outros contextos.
- Um usuário pode ter zero ou vários (n-n) Projetos
- Um Projeto pode ter zero ou vários(n-n) Usuários
- Tabela Auxiliar de Many-to-Many: Usuario_Projeto
- Um Usuario_Projeto tem um e apenas um (1-1) usuário e projeto.
- Um Usuario_Projeto pode ter zero ou várias (0-n) Tarefas.
- Uma tarefa pertence a um e somente um Usuario_Projeto(1-1) (consequentemente a Tarefa está relacionada ao mesmo tempo com Usuário e Projeto)
- Para facilitar a visualização, acesse o link para Draw.io
- Camada responsável por fazer a aplicação se comunicar diretamente com o domínio. Nela, são construídas as classes que serão necessárias para a aplicação. A construção dessas classes, feitas por meio de injeção de dependencias com o intuito de reduzir o acomplamento da aplicação, é realizado com o auxílio da camada de inversão de controle.
Handlers
- AuthorizationHandler.cs → classe de middleware, responsável por intervir durante o acesso a aplicação e retornar uma excessão personalizada no caso de acesso não permitido.
Filters
- ExceptionFilter.cs → classe de filtro de excessão personalizada.
Controllers
- BaseController.cs → classe de base em que outros controllers se especificam.
- AutenticacaoController.cs → definição dos endpoints de autenticação de um usuário.
- TarefaController.cs → definição dos endpoints para interação com as tarefas de um usuário.
- TogglController.cs → definição dos endpoints para integração com a API do Toggl.
- UsuarioController.cs→ definição dos endpoints para interação com o contexto de usuário.
- Camada que realiza a distribuição de responsabilidades transversais (métodos comuns). Essa camada "cruza" toda a hierarquia de camadas, provendo a configuração dos serviços necessários para as classes funcionarem e estabelecendo o tempo de vida desses serviços.
DependencyInjection
- ConfigureMappers.cs → configuração da injeção de dependência dos serviços de mapeamentos de Entidade para Contracts (entity ↔ request/response)
- ConfigureRepository.cs → configuração da injeção de dependência do contexto de banco de dados e repositórios.
- ConfigureServices.cs → configuração da injeção de dependência das classes de services da aplicação.
- Camada que se comunica diretamente e somente com o CrossCutting, e é utilizada na camada de aplicação, que é responsável por registrar as dependencias necessárias para o funcionamento dos serviços do aplicativo.
- NativeInjectorBootstraper.cs → classe responsável por registrar as dependencias do aplicativo (mappers, services e repositories).
- Camada responsável por se comunicar diretamente com o banco de dados. Aqui são definidas as entidades da aplicação, que posteriormente irão ser persistidas no banco de dados. É realizado todo o "mapeamento" de configuração dessas entidades para estabelecimento correto de relacionamentos e outros constraints do SQL. Por meio do EF Core Code First, são feitas migrações para o banco de dados e a construção das Tables, com tudo previamente configurado. Também são construidas as classes que irão interagir com o banco de dados, na qual possuem métodos que realizam o CRUD necessário para a aplicação.
Context
- ApplicationDbContext.cs → classe que define o contexto a ser utilizado para comunicação e transações com o banco de dados.
Mappings
- ProjetoMap.cs → classe de configuração da entidade Projeto, definindo suas constraints e relacionamentos.
- TarefaMap.cs → classe de configuração da entidade Tarefa definindo suas constraints e relacionamentos.
- Usuario_ProjetoMap.cs → classe de configuração da entidade Usuario_Projeto definindo suas constraints e relacionamentos.
- UsuarioMap.cs → classe de configuração da entidade Usuario definindo suas constraints e relacionamentos.
Repositories
- BaseRepository.cs → classe que define os métodos base para comunicação com o banco de dados.
- LogRepository.cs → classe que herda de base repository e interage com a tabela de Log.
- ProjetoRepository.cs → classe que herda de base repository e interage com a tabela de Projeto.
- TarefaRepository.cs → classe que herda de base repository e interage com a tabela de Tarefa.
- Usuario_ProjetoRepository.cs → classe que herda de base repository e interage com a tabela de Usuario_Projeto.
- UsuarioRepository.cs → classe que herda de base repository e interage com a tabela de Usuario.
- Camada que delimita o "coração" do nosso negócio. Aqui, são construidos, com auxilio da linguagem ubíqua, contextos e modelagens realizados anteriormente, as interfaces, contratos de transferência de dados e entidades que serão utilizados em toda a aplicação. Além disso, classes auxiliares e utilitárias, excessões personalizadas e configurações são definidas nessa camada.
Contracts
- ColaboradoresRequest.cs → define as informações a serem requisitadas no ProjetoController.cs para adicionar ou remover colaboradores de um projeto.
- LoginRequest.cs → define as informações a serem requisitadas no AutenticacaoController.cs para realizar o login de um usuário.
- NovaSenhaRequest.cs → define as informações a serem requisitadas no UsuarioController.cs para realizar o processo de reset de senha de um usuário.
- ProjetoRequest.cs → define as informações a serem requisitadas no ProjetoController.cs para realizar a interação(criação, alteração) para com a entidade de Projeto.
- ResetSenhaRequest.cs → define as informações a serem requisitadas no UsuarioController.cs para mudar a senha de um usuário.
- TarefaRequest.cs → define as informações a serem requisitadas no TarefaController.cs para realizar a interação(criação, alteração) para com a entidade de Tarefa.
- TarefaStartRequest.cs → define as informações a serem requisitadas no TarefaController.cs para realizar o inicio de uma tarefa.
- TarefaStopRequest.cs → define as informações a serem requisitadas no TarefaController.cs para realizar a finalização de uma tarefa.
- TogglDetailedRequest.cs → define as informações a serem requisitadas no TogglController.cs para realizar a integração com a API do Toggl e recuperar as informações de projetos e tarefas dos usuários cadastrados na plataforma Toggl.
- UsuarioRequest.cs → define as informações a serem requisitadas no UsuarioController.cs para realizar a interação(criação, alteração) para com a entidade de Usuario.
- MessageResponse.cs → classe que define o padrão de mensagem que será entregue quando uma solicitação for feita, com código de status, descrição da mensagem, várias mensagens e detalhes da requisição.
- ProjetoResponse.cs → define as informações que serão entregues como resposta a uma solicitação que se relacione com a entidade Projeto.
- TarefaResponse.cs → define as informações que serão entregues como resposta a uma solicitação que se relacione com a entidade Tarefa.
- TogglDetailedResponse.cs → define as informações que serão entregues como resposta a uma solicitação a API do Toggl.
- Usuario_ProjetoResponse.cs → define as informações que serão entregues como resposta a uma solicitação que se relacione com a entidade de Tarefa, visto que um usuario_projeto possui diversas tarefas.
- UsuarioResponse.cs → define as informações que serão entregues como resposta a uma solicitação que se relacione com a entidade Usuario.
Entities
- BaseEntity.cs → classe base que define as propriedades(colunas) que serão persistidas no banco de dados.
- Log.cs → classe que define a tabela Log e suas propriedades que serão persistidas no banco de dados. Não herda de BaseEntity.
- Projeto.cs → classe que define a tabela Projeto e suas propriedades que serão persistidas no banco de dados e suas propriedades de referência.
- Tarefa.cs → classe que define a tabela Tarefa e suas propriedades que serão persistidas no banco de dados e suas propriedades de referência.
- Usuario.cs → classe que define a tabela Usuario e suas propriedades que serão persistidas no banco de dados e suas propriedades de referência.
- Usuario_Projeto.cs → classe que define a tabela Usuario_Projeto e suas propriedades que serão persistidas no banco de dados e suas propriedades de referência.
Exceptions
- BaseException.cs → classe que define a excessão personalizada ao ser utilizada pelo filtro de excessão quando uma requisição não atender os requisitos necessários para ser processada, ou outros erros ocorrerem.
- StatusException.cs → enum que define o tipo de status a ser entregue por uma MessageResponse.
Interfaces
- Repository → definem os métodos a serem implementados pelas classes de repository.
- Sevices → definem os métodos a serem implementados pelas classes de services.
para mais informações: Diagrama De Classes
Settings
- AppSettings.cs → classe que resgata a securityKey da aplicação para ser utilizada em métodos de services.
- EmailSettings.cs → classe que resgata informações para serem utilizadas pelo serviço de email na comunicação com o servidor de email externo.
- TogglSettings.cs → classe que resgata informações sobre a conta toggl para serem utilizadas pelo serviço de integração com a API do toggl.
Shared
- Token.cs → classe que gera JsonWebToken, este que é utilizado nas requisições como bearer para a autenticação na plataforma.
- Camada que aplica as regras de negócio impostas pelo cliente e implementa a lógica dos serviços que a aplicação irá prover. Nela, são definidas validações para a transferência de dados dos contratos e permissões personalizadas que serão utilizadas pelos controllers.
Validators
- ColaboradoresRequestValidator.cs → define regras de validação para as informações a serem recebidas no contract ColaboradoresRequest.
- NovaSenhaRequestValidator.cs → define regras de validação para as informações a serem recebidas no contract NovaSenhaRequest.
- ProjetoRequestValidator.cs → define regras de validação para as informações a serem recebidas no contract ProjetoRequest.
- TarefaRequestValidator.cs → define regras de validação para as informações a serem recebidas no contract TarefaRequest.
- UsuarioRequestValidator.cs → define regras de validação para as informações a serem recebidas no contract UsuarioRequest. Services
- BaseService.cs → classe base utilizada apenas para compartilhar, no mesmo contexto HTTP, as claims de uma requisição e de um usuário.
- EmailService.cs → classe responsável por implementar os métodos contendo a lógica necessária para o funcionamento do serviço de comunicação com o servidor de email.
- LogService.cs → classe responsável por implementar o método de logar toda ação feita dentro da aplicação e salvar no banco de dados.
- ProjetoService → classe responsável por implementar todos os métodos e lógica de negócio no que concerne aos Projetos.
- TarefaService → classe responsável por implementar todos os métodos e lógica de negócio no que concerne as Tarefas.
- TogglService → classe responsável por implementar o método necessário para a integração com a API externa do Toggl.
- Usuario_ProjetoService.cs → classe que realiza a conexão entre um usuário e seus projetos e implementa métodos verificadores que auxiliam na lógica do TarefaService e ProjetoService,
- UsuarioService.cs → classe que implementa os métodos a serem utilizados no contexto de um Usuario.
- Camada que realiza testes de todos os componentes da aplicação.
- /api/autenticacao
POST
Ativa o e-mail do usuário. - /api/autenticacao/login
POST
Realiza o login do usuário.
- /api/projeto
POST
Cadastra um projeto. - /api/projeto
GET
Lista todos os projetos. - /api/projeto/{id}/colaboradores
POST
Adiciona colaboradores em um projeto. - /api/projeto/{id}/colaboradores
POST
Remove colaboradores de um projeto. - /api/projeto/{id}
GET
Retorna um projeto pelo ID. - /api/projeto/{id}
PUT
Edita um projeto - /api/projeto/{id}
DELETE
Remove um projeto. - /api/projeto/usuario/{usuarioId}
GET
Lista todos os projetos que um usuário participa.
- /api/usuario/{id}
PATCH
Muda a permissão de um Usuario. - /api/usuario
POST
Cadastra um usuário. - /api/usuario
GET
Lista todos os usuários. - /api/usuario/{id}
DELETE
Remove um usuário. - /api/usuario/{id}
GET
Retorna um usuário pelo ID. - /api/usuario/{id}
PUT
Edita as informações de um usuário. - /api/usuario/senha
POST
Envia o código para reset de senha para o e-mail. - /api/usuario/senha
PUT
Reseta a senha de um usuário.
- /api/tarefa
POST
Cadastra uma tarefa. - /api/tarefa
GET
Lista todas as tarefas. - /api/tarefa/{id}/start
PATCH
Inicia uma tarefa. - /api/tarefa/{id}/stop
PATCH
Para uma tarefa. - /api/tarefa/{id}
DELETE
Remove uma tarefa. - /api/tarefa/{id}
PUT
Edita uma tarefa. - /api/tarefa/{id}
GET
Retorna uma tarefa pelo ID. - /api/tarefa/usuario/{usuarioId}
GET
Retorna todas as tarefas de um usuário. - /api/tarefa/usuario/{usuarioId}/filter_by
GET
Retorna todas as tarefas de um usuário aplicando filtros de data. - /api/tarefa/projeto/{projetoId}
GET
Lista todas as tarefas de um projeto.
- /toggl/relatorio-de-horas
GET
Endpoint de integração com o toggl.
- Cadastro do usuário
- Autenticação do e-mail de um usuário
- Login de um usuário cadastrado
- Resetar a senha de um usuário
- Criar projetos
- Adicionar e remover colaboradores de um projeto
- Editar e remover projetos
- Criar tarefas e associa-las a projetos
- Iniciar e parar tarefas
- Editar e excluir tarefas
- Ver e importar tarefas e projetos a partir dos dados do Toggl
- Possibilitar a total integração da gestão de horas da raro, não dependendo do Toggl.
- Separação dos Projetos por Clientes
# Clone este repositório:
git clone https://gitlab.com/gloinho/chronos.git
# Entre na pasta da camada de aplicação do projeto.
cd Chronos.Api
# Rode a aplicação.
dotnet run
# Observações:
# Usuário Administrador necessita ser previamente cadastrado no banco de dados.
- Gostariamos de agradecer a todo suporte dado pela Raro Academy, aos instrutores que nos aguentaram e auxiliaram e aos monitores que estavam disponíveis para tirar nossas dúvidas.