API Banking é um projeto que simula um processo de transações financeiras desde cadastro de contas até o logout da conta. Como o foco é simular transações financeiras, a API permite que você informe a conta, agência e código do banco, com o objetivo de deixar mais flexível a simulação. É de consciência que em uma situação real, essas informações devem ser geradas pelo serviço, e não ser informado pelo usuário que está criando a conta.
O projeto contribuiu para o aprendizado sobre a linguagem Elixir.
- Erlang/OTP 22 [erts-10.4.2]
- Elixir 1.8.2 (compiled with Erlang/OTP 20)
- Postgres 10.9.
- absinthe: Conjunto de ferramentas GraphQL para Elixir;
- phoenix: Para a API;
- guardian: Para autenticação e autorização;
- ecto: Conjuntos de ferramentas para mapeamento de dados e consulta integrada.
- Cadastro de contas;
- Autenticação da conta (entrar na conta);
- Autorização da conta;
- Transferência de valores entre as contas;
- Saque;
- Emissão de relatório back office;
- Consultar saldo da conta logada;
- Remover autenticação (sair da conta).
- Cadastrar conta
- Pré-requisito(s):
- Nenhum
- Pré-requisito(s):
- Autenticar conta
- Pré-requisito(s):
- Cadastrar conta
- Pré-requisito(s):
- Autorizar conta
- Pré-requisito(s):
- Autenticar conta
- Pré-requisito(s):
- Transferir valor
- Pré-requisito(s)
- Autenticar conta
- Autorizar conta
- Pré-requisito(s)
- Saque
- Pré-requisito(s)
- Autenticar conta
- Autorizar conta
- Pré-requisito(s)
- Consultar saldo da conta logada
- Pré-requisito(s)
- Autenticar conta
- Pré-requisito(s)
- Emitir relatório back office
- Pré-requisito(s)
- Nenhum
- Sair da conta
- Pré-requisito(s):
- Autenticar conta
- Pré-requisito(s):
- Pré-requisito(s)
Qualquer usuário pode criar sua própria conta. Para esse simulador é necessário informar:
- Conta (obrigatório);
Ex.: 0001
- Agência (obrigatório);
Ex.: 05289
- Código do banco (obrigatório);
Ex.: 004
- CPF do titular da conta (obrigatório);
Ex.: 06401173173
- Nome do titular da conta (obrigatório);
Ex.: Maria Joana Silva
- E-mail (obrigatório);
Ex.: [email protected]
- Senha da conta (obrigatório)
- Quando o cadastro for concluido, o usuário terá R$ 1000,00 creditado em sua conta;
- A composição de Conta, Agência e Código do banco, são únicos;
- O CPF é único;
- O e-mail é único.
O processo de autenticação da conta, pode se entender como processo de entrar/logar na conta. Para efetuar essa ação, é necessário informar:
- Conta (obrigatório);
Ex.: 0001
- Agência (obrigatório);
Ex.: 04589
- Código do banco (obrigatório);
Ex.: 002
- Senha (obrigatório)
O processo de autorização da conta, só será possível se o usuário estiver logado. Esse processo é basicamente a confirmação de alguma operação específica; portanto, é necessário informar a senha da conta autenticada.
Para realizar transferência de valores, é necessário informar os seguintes dados da conta de destino:
- Conta (obrigatório);
Ex.: 0001
- Agência (obrigatório);
Ex.: 01548
- Código do banco (obrigatório);
Ex.: 005
- Valor (obrigatório)
- É permitido apenas transferir valores superiores a zero;
- É necessário ter saldo maior ou igual ao valor da transferência.
Obs.: Não é permitido transferir para própria conta logada. Para efetuar essa operação, é necessário que a conta esteja logada e autorizada.
Para realizar a operação de saque, é necessário:
- Informar o valor para saque;
- Possuir saldo para saque;
- A conta precisa estar autenticada e autorizada.
Exibe um sumário das transações feitas no dia, no mês e no ano corrente.
Exibe o saldo atual da conta.
Desconecta da conta logada.
mix deps.get # Instale as dependências
mix ecto.create # Criar o banco de dados
mix phx.server # Iniciar o endpoint do serviço
docker build --tag apibnk .
docker-compose up
mix test # Executar o comando
Obs.: Para executar o analisador de código fonte estático credo:
mix credo
-
A documentação dos módulos estão localizadas no diretório do projeto
doc
, em que foi gerado utilizando o comando$ mix docs
. -
A documentação das consultas GraphQL são disponibilizadas na própria rota do serviço
localhost:4000/api/graphiql
. -
Utilize a rota
http://127.0.0.1:4000/api/graphiql
para ter acesso aos recursos da API.- Existem dois tipos de HTTP Headers:
- Token de autenticação
- Header name: Authentication
- Header value: Bearer <Token>
- Ex.: Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
- Token de autorização: Utilizado para efetuar determinadas operações financeiras
- Header name: Authorization
- Header value: Bearer <Token>
- Ex.: Authorization : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
- Token de autenticação
- Efetuar todas a requisições via POST, informando os respecitivos tokens a depender da operação, por exemplo:
- Para acessar seu saldo, é necessário informar o token de autenticação, ou seja,
Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
- Para efetuar um saque, é necessário informar o token de autenticação e autorização, ou seja:
Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
;Authorization : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
.
- Para acessar seu saldo, é necessário informar o token de autenticação, ou seja,
- Existem dois tipos de HTTP Headers:
OBS.: Seguindo o padrão da notação do GraphQL, a exclamação (!) indica que o campo é obrigatório.
Exemplos de consultas GraphQL:
Observações:
- Existe a unicidade de CPF;
- Existe a unidade de E-mail;
- Existe a unicidade da composição de: Conta, Agência e Código do banco.
mutation {
createAccount(
account: String!
agency: String!
bankCode: String!
cpf: String!
email: String!
name: String!
password: String!
){
code
message
}
}
mutation {
createAccount(
account: "14026",
agency: "0001",
bankCode: "003",
name: "Joana",
password: "123456",
cpf: "95875628600",
email:"[email protected]"
){
code
message
}
}
{
"data": {
"createAccount": {
"code": 201,
"message": "Created"
}
}
}
query {
login(
account: String!
agency: String!
bankCode: String!
password: String!
) {
token
}
}
query {
login(bankCode:"003" agency: "0001", account: "14025", password: "123456") {
token
}
}
{
"data": {
"login": {
"token": "eyJhbGciOiJIUzUxMdWQiOBjzLZIjJ2Ur5lGRtD-ifKeOA"
}
}
}
Lembrete: Deverá ter o header Authentication, informando o token, para efetuar essa requisição. Lembrando que o formato do header é Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
.
query {
authorization(password: String!) {
token
}
}
query {
authorization(password: "123456") {
token
}
}
{
"data": {
"authorization": {
"token": "eyJhbGciOiJIUzUxMdWQiOBjzLZIjJ2Ur5lGRtD-ifKeOA"
}
}
}
query {
reportBackOffice {
totalDay
totalYear
totalMonth
}
}
{
"data": {
"reportBackOffice": {
"totalDay": "1000",
"totalMonth": "1000",
"totalYear": "1000"
}
}
}
Lembrete: Deverá ter o header Authentication e Authorization, informando seus respectivos tokens, para efetuar essa requisição. Lembrando que o formato do header é Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
e Authorization : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
; para cada saque é necessário gerar um novo token de autorização.
mutation {
withdrawal(value: Float!){
message
code
}
}
mutation {
withdrawal(value: 50.55){
message
code
}
}
{
"data": {
"withdrawal": {
"code": 200,
"message": "Saque realizado com sucesso. Um e-mail foi enviado para [email protected]"
}
}
}
Lembrete: Deverá ter o header Authentication e Authorization, informando seus respectivos tokens, para efetuar essa requisição. Lembrando que o formato do header é Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
e Authorization : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
; para cada transferência é necessário gerar um novo token de autorização.
mutation {
transferency(
account: String!
agency: String!
bankCode: String!
value: Float!
){
message
code
}
}
mutation {
transferency(account: "14026", agency: "0001", bankCode: "003", value: 100.63){
message
code
}
}
{
"data": {
"createAccount": {
"code": 201,
"message": "Created"
}
}
}
Lembrete: Deverá ter o header Authentication, informando o token, para efetuar essa requisição. Lembrando que o formato do header é Authentication : Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
.
query {
balance
}
{
"data": {
"balance": "949.45"
}
}
mutation{
logout{
code
message
}
}
{
"data": {
"logout": {
"code": 200,
"message": "OK"
}
}
}