| [Home](home) | **Arquitetura** |[Banco de Dados](banco_dados) | [Configuração](configuracao) | [Gerenciamento do Projeto](Gerenciamento_projeto) | [Instalação](instalacao) | [Materiais de Estudo](Materiais_estudo) | [Mockups](mockups) | [Requisitos](requisitos) | [Reuniões](reunioes) | [Sprints](sprints) |
| ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ |
# Arquitetura do Sistema
* [Fluxograma de funcionamento do aplicativo](#fluxograma-de-funcionamento-do-aplicativo)
* [Git Branching Model](#git-branching-model)
* [Code Review](#code-review)
* [Guia de desenvolvimento](#guia-de-desenvolvimento)
* [Estrutura de pacotes do aplicativo](#estrutura-de-pacotes-do-app)
* [Deploy em produção](#deploy-em-produção)
* [Estratégia online/offline do app](#estratégia-onlineoffline-do-app)
* [Próximos artefatos](#pr%C3%B3ximos-poss%C3%ADveis-artefatos)
## Fluxograma de funcionamento do aplicativo
Este fluxograma é referente à aplicação mobile que tem como principal função a coleta do tempo das atividades.
Perceba que num primeiro momento estamos abstraindo o fluxo de inserção de dados, considere que estes já estarão disponíveis na API. Nossa prioridade é o desenvolvimento do App (Android e IOS) para coleta de tempos, para que posteriormente possamos dedicar tempo para as tarefas administrativas (Cadastrar Hospitais, Cadastrar Processos - que contém atividades -).
É possível notar que não é necessário login para o uso de funcionários e bolsistas, estes só precisam identificar o respectivo hospital, para que sejam vinculados os processos e atividades referentes à sua função. A identificação do paciente é apenas para identificar e diferenciar possíveis processos parecidos sendo realizados ao mesmo tempo. Esta identificação deve ser feita de forma que facilite o máximo possível o atendimento. Possíveis identificações: Iniciais do paciente, Código do atendimento do paciente no hospital ou outro. (Esta identificação deve ser informada no momento no fluxo apresentado).
## Git Branching Model
O modelo de gestão das branches do Git é baseado no [Git Flow "trandicional"](https://nvie.com/posts/a-successful-git-branching-model/) com adaptações. Não é previsto o uso de branches `hotfix/*`, uma vez que na AGES não há situações onde um ajuste do produto entregue será integrado antes do final da sprint corrente.
O desenvolvimento nos repositórios _app_ e _api_ deve seguir o fluxo de Git aqui definido:
- uma branch `master` com o código atualmente em produção;
- uma branch `develop` com o código em desenvolvimento, com funcionalidades finalizadas mas ainda em fase de testes para validação;
- feature branches para tasks relacionadas às user stories a serem desenvolvidas. Uma branch de task deve ser nomeada com o número único da task, seguida da breve descrição da task (por exemplo, `feature/t06-login` ou `feature/t24-reports-ui`);
- quando uma feature é finalizada, um PR da branch `feature/` relacionada é aberto com destino à branch `develop`.
O código da `develop` é integrado com a `master` ao final da sprint, após validação dos stakeholders do que foi desenvolvido.
Dessa forma, o fluxo usual de trabalho é o seguinte:
1. antes de iniciar o desenvolvimento de uma task, fazer checkout para a branch `develop` e pegar as últimas atualizações (`pull`);
2. criar uma branch para a task com o ID da task (`feature/tXX-YYYYY`);
3. "enviar" a branch para o remoto (`git push -u origin feature/tXX-YYYYY`);
4. desenvolver, commitar mudanças e atualizar o remoto (`push`);
5. voltar para o item **4** até finalizar a task;
6. abrir um PR com destino à branch `develop`;
7. mover o card da task no Trello para a lista _Code Review_ e avisar no Slack (canal #code-review) que a task está pronta para review;
8. fim! 😃
## Padrões de commit
Quando realizar um commit, tente manter o seguinte padrão nas mensagens:
- título: número da task e breve descrição da mudança;
- se preciso, adicione um descrição mais longa da mudança, do porquê ela se faz necessária ou do porquê foi feito dessa forma; essa descrição longa deve estar separada do título por uma linha em branco;
- se mais de uma pessoa participou das mudanças do commit: indique a co-autoria conforme exemplo abaixo, também separada por uma linha em branco da descrição longa (o Git precisa de um formato bem específico nessa parte, com uma pessoa por linha; não é preciso adicionar uma linha para a pessoa que está fazendo o commit, porque o Git já pega isso automaticamente).
Exemplo:
```
#48: Fix patient name field placeholder
The placeholder was clipped smartphones with small screens; reduced placeholder
length for better UX on those devices.
Co-authored-by: Marcos Silva
```
## Code Review
Após o desenvolvimento de uma task, um _pull/merge request_ (PR) deve ser aberto com destino à branch _develop_ do repositório relativo à task: _app_ ou _api_. Todos os PRs são revisados por pelo menos dois AGES III, que se responsabilizam por garantir a qualidade do que foi desenvolvido e que os artefatos e estruturas se adequem aos padrões definidos neste documento.
Os AGES III se comprometem a revisar os PRs o mais rápido possível, garantindo que PRs abertos até dois dias antes de uma entrega serão integrados (se cumprirem todas as regras do code review).
Foram definidas algumas regras usadas durante o processo de code review dos PRs abertos nos repositórios:
- _app_:
- funciona obrigatoriamente em Android, preferencialmente em iOS;
- interface funciona nos tamanhos de tela suportados;
- interface segue especificação no Figma;
- conforme critérios de aceitação para a tarefa;
- passa nos testes funcionais definidos para a tarefa/story;
- documentação atualizada;
- código dentro dos padrões;
- código sem warnings ou erros de linter.
- _api_:
- funciona conforme especificação no Postman;
- possui testes de unidade associados;
- mantém cobertura de pelo menos 50%;
- dependências externas adicionadas aprovadas pelos AGES III;
- documentação atualizada;
- código dentro dos padrões;
- código sem warnings ou erros de linter.
Essas regras foram adicionadas como template de PR em cada projeto.
## Guia de desenvolvimento
Foi criado um [guia de desenvolvimento para o backend](guia_desenvolvimento_backend), com o intuito de auxiliar no processo de entendimento da arquitetura de camadas usada no backend, organização física do repositório e acesso à documentação das rotas.
[🔗 Acesse o guia de desenvolvimento](guia_desenvolvimento_backend).
### Estrutura de pacotes do App
Aqui está a descrição das principais camadas do aplicativo:
- **Component** (``átomo``): o mais genérico e reutilizável da UI (User Interface). Não contém regra de negócio.
- **Container** (``molécula``): é responsável por agrupar componentes que serão utilizados em uma tela. Contém regra de negócio / lógica.
- **Screen** (``organismo``): responsável pela a apresentação dos containers e interage com a navegação entre as telas. Possui pouca lógica/regra de negócio (menos do que o container). Onde são feitas as requisições pra API, geralmente.
![image](uploads/b6d5558af5b43030bedcea929b0941d0/image.png)
#### Diagrama de pacotes da aplicação
Neste diagrama são apresentados os principais artefatos do aplicação no lado do cliente, a forma como foram estrturados e contém um mapeamento dos artefatos produzidos até então no escopo da aplicação
![image](uploads/8ac82926554cf35631137136384a0ee5/image.png)
É possível notar no diagrama apresentado que a arquitetura da aplicação é baseada no modelo em `camadas`, onde os principais pacotes da aplicação são as camadas `screens`, `containers` e `componentes`. E a comunicação entre eles ocorre como demonstrado no diagrama de pacotes.
## Deploy em produção
Nessa seção, você terá instruções sobre como fazer o deploy do backend para o ambiente de produção, e como gerar uma APK do aplicativo Android para distribuição pela Play Store.
### Deploy da API em produção
Para disponibilizarmos nossa API em produção, o seguinte blog foi utilizado como referência: https://medium.com/@nishankjaintdk/setting-up-a-node-js-app-on-a-linux-ami-on-an-aws-ec2-instance-with-nginx-59cbc1bcc68c
A abordagem final é a que segue:
1. Criar conta na Amazon AWS
- Acesse o blog referência e realize os passos da seção "Create an AWS account".
2. Criar instância EC2
- Acesse a documentação da Amazon AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html
- Configure na aba Security Groups o seu grupo desta forma:
![Regras](uploads/0a23f421b760daceaea617fbead4c9cb/Regras.PNG)
3. Acessar através de conexão ssh a instância EC2
- Acesse a documentação da Amazon AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html
4. Instalar na instância Git, NodeJS, Docker, Docker-Compose e PM2
- Comandos:
```bash
$ sudo yum update
$ sudo yum install -y docker
$ sudo usermod -a -G docker ec2-user
$ sudo service docker start
$ sudo chkconfig docker on
$ sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-`uname -s`-`uname -m` | sudo tee /usr/local/bin/docker-compose > /dev/null
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
$ sudo yum install git
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
```
- Desconecte da instância e conecte novamente, então:
```bash
$ nvm install v13.12.0
$ npm install pm2 -g
```
5. Realizar o deploy do PostgreSQL usando Docker e Docker-Compose
- Crie o seguinte arquivo dentro da instância: [docker-compose.yaml](uploads/be552d4e6fcadd4d54d8fb8a49c6c109/docker-compose.yaml)
- Então use o comando:
```bash
$ docker-compose up -d
```
6. Configurar o banco de dados conforme documentação da API usando pgAdmin4
- Acesse o repositório e leia o passo a passo para PostgreSQL: http://tools.ages.pucrs.br/dtool/backend
7. Clonar repositório do backend do projeto
```bash
$ git clone http://tools.ages.pucrs.br/dtool/backend.git
$ cd backend
$ npm i
```
8. Inicializar backend com PM2
- Acesse o blog referência e realize os passos da seção "Keep the app running".
- Obs: para o passo do comando pm2 start, utilize o comando:
```bash
$ pm2 start npm --name "backend" -- start
```
#### Diagrama de deploy
![image](uploads/63644523044d142012795a83f08ebb82/image.png)
### Gerar APK para envio à Google Play Store
Antes de continuar, certifique-se de que o ambiente de desenvolvimento está configurado e funcionando corretamente.
#### 1 - Gerar chaves
> Se você já mandou o app para a Play Store e tem um arquivo com a keystore e chave de upload, pule essa etapa.
Antes da primeira submissão do APK à Play Store, é preciso gerar uma chave privada para assinar o APK da aplicação. Essa chave deve ser guardada em um local seguro, pois será necessária sempre que for preciso disponibilizar uma atualização da aplicação na Play Store.
É preciso gerar uma _keystore_ (capaz de armazenar várias _keys_) e uma _key_. Abra uma janela do terminal e execute o seguinte comando:
```bash
$ keytool -genkeypair -v -keystore upload.keystore -alias upload -keyalg RSA -keysize 2048 -validity 10000
```
Você deverá informar duas senhas: uma para a keystore e outra para a chave. Também será preciso informar alguns dados de identificação, como nome, organização, cidade, estado e país.
O resultado da execução é um arquivo `upload.keystore` (com uma key `upload`) presente na mesma pasta onde o comando foi executado. **Guarde este arquivo e as senhas informadas em um local seguro, e não os armazene no repositório da aplicação.** Sem ele, não será possível atualizar o aplicativo na Play Store (apenas enviar outro APK como se fosse um novo app).
#### 2 - Configurações no projeto
> Considerando que você tem um arquivo keystore com uma chave para upload.
1. Copie o arquivo da keystore para a pasta `android/app/`;
2. Edite o arquivo `android/gradle.properties`, conforme exemplo abaixo:
```bash
DTOOL_UPLOAD_STORE_FILE=upload.keystore # nome do arquivo com a keystore
DTOOL_UPLOAD_KEY_ALIAS=upload # nome da key presente na keystore
DTOOL_UPLOAD_STORE_PASSWORD=dtool2020 # senha da keystore
DTOOL_UPLOAD_KEY_PASSWORD=dtoolupload # senha da key
```
**Não adicione essas mudanças ao repositório (não commite isso).** Realize essas mudanças sempre que for preciso gerar uma APK para distribuição.
#### 3 - Gerando o APK
Abra uma janela do terminal, vá até a pasta `android/` e execute o comando `./gradlew assembleRelease`. O comando deve demorar um pouco para completar, uma vez que o processo de build para distribuição é mais demorado.
Quando o comando finalizar, o APK final estará na pasta `android/app/build/outputs/apk/release/`.
#### 4 - Enviando à Play Store
Confira os [tutoriais oficiais da Google](https://support.google.com/googleplay/android-developer/answer/113469?hl=pt-BR) para ver como fazer o upload da aplicação para a Play Store.
[🔗 Fazer upload de um app - Ajuda do Play Console](guia_desenvolvimento_backend).
#### Mais informações
Para mais informações, consulte as documentações oficiais:
- [🔗 React Native - como gerar uma APK assinada](https://reactnative.dev/docs/signed-apk-android)
- [🔗 Android - gerar e assinar uma APK a partir da linha de comando](https://developer.android.com/studio/build/building-cmdline)
## Estratégia online/offline do app
De acordo com a necessidade apontada pelos stakeholders: manter a aplicação em pleno funcionamento e com o máximo de consistência de dados possível, mesmo que o usuário esteja sem conexão de internet em algum momento do percurso - cenário previsível no contexto do cliente-, definimos a seguinte estratégia de interação `online/offline` (implementada a partir da segunda sprint):
![Online_offline-Fluxo_online_offline](uploads/0a466d7af2cd1545caedabe6e5684bf0/Online_offline-Fluxo_online_offline.png)
### Próximos passos:
1. Prover uma `estrutura inicial` desta estratégia durante a Sprint 2.
2. Esta estrutura inicial será utilizada e continuada no decorrer das próximas sprints.
## Próximos possíveis artefatos:
* [ ] Segurança
* [ ] Rotas de Backend (Arquitetura
funcional)
* [ ] Objects – Backend API
* [ ] Methods – Backend API
* [ ] Arquitetura - Não Funcional
* [x] Diagrama de Pacotes / Componentes
(Arquitetura de software)
* [x] Diagrama de Deploy
* [ ] Documentação sobre aplicação de
Design do Projeto
* [ ] Análise dos principios SOLID
Devem ser apresentados das seguintes formas:
* Imagens ou Gifs
* Diagramas ou Sistemas
* Descrições ou textos explicativos