Skip to content

cpt-westphalen/ng-cash-frontend-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

88 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NG-CASH Jr Frontend Dev Test

NG.CASH é uma empresa de tecnologia que fornece um app financeiro para a geração Z.

Desafio

O teste técnico para o cargo de desenvolvedor frontend júnior consistia em:

Construir aplicação web fullstack dockeirizada para usuários NG.CASH fazerem transações entre si, com prazo sugerido de 7 dias para execução.

Foram fornecidas regras de negócio, schemas para o Banco de Dados e as características mínimas para o frontend. Você encontra uma cópia dos requisitos aqui.

Exemplo

2

Como rodar o código

É necessário ter docker e docker-compose instalados.

  1. Clone o repositório para sua máquina local;
  2. Abra a pasta raíz do projeto no terminal;
  3. Execute: docker-compose -f compose-dev.yml up --build
  4. Acesse localhost:5173 para acessar o frontend de desenvolvimento com proxy
  5. Acesse localhost:3000 para acessar apenas o backend com a última build do frontend
  6. Para parar os containers, aperte ctrl+c no terminal do docker-compose
  7. Na pasta raíz, execute: docker-compose -f compose-dev.yml down para remover os containers

OBS: Alterações feitas no código na máquina local são percebidas automaticamente nos containers.

Observações

O primeiro commit de setup do projeto (64de54e) foi feito em 15/nov./2022.

Consta no Readme da entrega parcial, feita em 04/dez./2022 (787a3cb):

  • Não conhecia Docker;
  • Não sabia como funcionava o processo de autenticação com JWT;
  • Pouquíssimo conhecimento em backend (nunca implementei server com db);
  • Para executar o frontend, optei por usar um Mock Service Worker para interceptar e lidar com os requests enquanto não tenho o backend;

Devido a essas limitações, optei por enviar um frontend funcional, porém mockado e continuar aprendendo para ter em portfólio um projeto fullstack.

Empreitada extra

Para isso, entre 04/dez. e 10/jan. aprendi:

  • Node + Express + Auth JWT (até 3a32b29)
  • Banco de Dados + SQLite + Nestjs (Confira aqui; Influência começa em d196996)
    • Padrões de Repository, Módulos, Inversão de Dependências, Camadas da Aplicação (db/repo/app/http)
    • Uso de Mappers entre camadas
    • Obs: Não usei Nest nem SQLite aqui, mas me apropriei de conceitos de DDD, OOP e SOLID para o projeto.
  • Docker CLI + Docker-Compose (d1caa3d)
    • Configuração de ambiente dev em docker com nodemon e proxy de chamadas para API a partir do frontend (e55f583)
    • Postgres containerizado (ac2e91b)
  • Prisma ORM (Inicial: 03cceeb)

Confira a história completa de commits: commits/main.

Stack final

Frontend

  • TypeScript
  • React
  • Vite
  • TailwindCSS
  • Outros: react-modal, react-icons, axios

Backend

  • TypeScript
  • Nodejs
  • Express
  • Outros: jsonwebtoken, bcrypt

ORM

  • Prisma

Database

  • Postgresql

DevOps

  • Docker-compose
  • Git

Destaques do Autor

Frontend

  • Frontend 100% responsivo
  • Práticas de acessibilidade no React
  • Padronização de tema no Tailwind
  • Validação de entradas (register/login/transferência)
  • Modais de Erro conforme retorno da API
  • Uma tabela automática linda para as transações financeiras <3 (ver prints abaixo)

Backend

  • Camadas desacopladas com inversão de dependência
  • Validação de entradas do usuário e checagens redundantes
  • Validação de JWT via middleware custom
  • Hashing de senhas
  • Postgres via imagem docker
  • Repositório Prisma / ORM com migrations

Screenshots

1

4

5

6

API Routes

ATTENTION: API WORKS WITH INTEGERS, aka: 1001 == $ 10.01

POST /api/register

@@ Public

Create new account and user.

Request Body

// application/json
{
  "username": string,
  "password": string
}

Response Body

// application/json
{
    "message": "account created!",
    "user": {
        "id": string,
        "username": string,
        "account": {
            "id": string,
            "balance": number,
            "transaction_ids": string[]
        },
        "accessToken": string
    }
}

POST /api/login

@@ Public

Login to existing account.

Request Body

{
  "username": string,
  "password": string
}

Response Body

// application/json
{
    "id": string,
    "username": string,
    "account": {
        "id": string,
        "balance": number
        "transaction_ids": string[]
    },
    "accessToken": string
}

GET /api/:account_id/cash

@@ Private ("Authorization": "Bearer ...")

Gets account balance.

Response Body

// application/json
{
  "account": {
    "id": string,
    "balance": number
  }
}

POST /api/:account_id/send

@@ Private ("Authorization": "Bearer ...")

Request Body

// application/json
{
  "from": string,
  "to": string,
  "amount": number
}

Important: "from" is ACCOUNT_ID, "to" is USERNAME Example:

// application/json
{
 "from": "59a33a94-d4e7-4fdf-a2c3-95cc7e32d960",
 "to": "user1234",
 "amount": 1000
}

Response Body

{
  "message": "Success!",
  "transaction": {
    "from": string,
    "to": string,
    "amount": number,
    "created_at": DateTime,
    "transaction_id": string
  }
}

GET /api/:account_id/history

@@ Private ("Authorization": "Bearer ...")

Gets transaction history as an array.

Response Body

// application/json
[
    {
        "from": string,
        "to": string,
        "amount": number,
        "created_at": DateTime,
        "transaction_id": string
    },
    // example:
    {
        "from": "teste_123",
        "to": "user1234",
        "amount": 15000,
        "created_at": "2023-01-10T12:41:04.028Z",
        "transaction_id": "6f7c72be-f868-47b2-8d54-b3abd196a5e9"
    },
]

GET /api/users

@@ DEBUG Public This route only exists for debugging purposes. Gets all users in Database.

GET /api/transactions

@@ DEBUG Public This route only exists for debugging purposes. Gets all transactions in Database.

About

Technical test for NG.CASH junior frontend dev job.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published