top-tran/README.md

320 lines
5.9 KiB
Markdown
Raw Normal View History

# Toptran
2026-04-27 17:26:53 -03:00
Aplicação full-stack composta por um backend REST em Node.js/Express com autenticação JWT e um aplicativo mobile em React Native/Expo.
2026-04-27 17:26:53 -03:00
---
2026-04-27 17:26:53 -03:00
## Estrutura do projeto
2026-04-27 17:26:53 -03:00
```
toptran/
├── backend/ → API REST (Node.js, Express, Prisma, PostgreSQL)
└── mobile/ → App mobile (React Native, Expo)
```
---
## Backend
### Tecnologias
| Pacote | Versão | Função |
|---|---|---|
| Node.js | LTS | Runtime |
| Express | 5 | Framework HTTP |
| TypeScript | 5 | Tipagem |
| Prisma | 7 | ORM |
| PostgreSQL | — | Banco de dados |
| bcryptjs | — | Hash de senha |
| jsonwebtoken | — | Access token (JWT) |
| zod | — | Validação de input |
| @prisma/adapter-pg | — | Driver nativo do Prisma 7 |
### Arquitetura em camadas
```
src/
├── server.ts → Inicialização do Express e registro das rotas
├── lib/
│ └── prisma.ts → Singleton do PrismaClient com adapter PG
├── repositories/
│ ├── users.repository.ts → Queries de usuários no Prisma
│ └── tokens.repository.ts → Queries de tokens no Prisma
├── services/
│ ├── auth.service.ts → Lógica de registro, login, logout e JWT
│ └── users.service.ts → Lógica de leitura, atualização e remoção de usuários
├── controllers/
│ ├── auth.controller.ts → Recebe requests e chama auth.service
│ └── users.controller.ts → Recebe requests e chama users.service
├── middlewares/
│ └── auth.middleware.ts → Valida o Bearer token nas rotas protegidas
└── routes/
├── auth.routes.ts → Rotas públicas de autenticação
└── users.routes.ts → Rotas protegidas de usuário
```
**Fluxo de uma requisição:**
```
Request → routes → middleware (se protegida) → controller → service → repository → Prisma → PostgreSQL
```
### Modelos do banco de dados
```prisma
model users {
id String @id
name String
email String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime
tokens tokens[]
}
model tokens {
id String @id
token String @unique
type TokenType
userId String
expiresAt DateTime
createdAt DateTime @default(now())
users users @relation(fields: [userId], references: [id], onDelete: Cascade)
}
enum TokenType {
REFRESH
}
```
### Variáveis de ambiente
Crie o arquivo `backend/.env` com as variáveis abaixo:
```env
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=localhost
DB_PORT=5432
DB_NAME=toptran
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/toptran"
PORT=4000
JWT_SECRET=sua_chave_secreta_aqui
```
> `JWT_SECRET` é obrigatório em produção. O access token expira em **15 minutos** e o refresh token em **7 dias**.
### Instalação e execução
```bash
cd backend
# Instalar dependências
npm install
# Gerar cliente Prisma
npx prisma generate
# Rodar migrations
npx prisma migrate deploy
# Iniciar em modo desenvolvimento
npm run dev
# Build de produção
npm run build
npm start
```
### API Reference
#### Autenticação — `/auth`
> Rotas públicas, não requerem token.
**POST `/auth/register`**
Cria uma nova conta de usuário.
```json
// Request body
{
"name": "João Silva",
"email": "joao@email.com",
"password": "minhasenha"
}
// Response 201
{
"id": "uuid",
"name": "João Silva",
"email": "joao@email.com"
}
```
---
**POST `/auth/login`**
Autentica o usuário e retorna os tokens.
```json
// Request body
{
"email": "joao@email.com",
"password": "minhasenha"
}
// Response 200
{
"accessToken": "eyJ...",
"refreshToken": "uuid"
}
```
---
**POST `/auth/logout`**
Revoga o refresh token.
```json
// Request body
{
"refreshToken": "uuid"
}
// Response 204 (sem body)
```
---
#### Usuários — `/users`
> Rotas protegidas. Enviar o header `Authorization: Bearer <accessToken>`.
**GET `/users/me`**
Retorna os dados do usuário autenticado.
```json
// Response 200
{
"id": "uuid",
"name": "João Silva",
"email": "joao@email.com",
"createdAt": "2026-04-27T00:00:00.000Z"
}
```
---
**PUT `/users/me`**
Atualiza nome, e-mail e/ou senha. Todos os campos são opcionais.
```json
// Request body
{
"name": "João Atualizado",
"email": "novo@email.com",
"password": "novasenha"
}
// Response 200
{
"id": "uuid",
"name": "João Atualizado",
"email": "novo@email.com"
}
```
---
**DELETE `/users/me`**
Remove a conta do usuário autenticado.
```
// Response 204 (sem body)
```
---
#### Respostas de erro
| Status | Situação |
|---|---|
| 400 | Input inválido (falha na validação Zod) |
| 401 | Token ausente, inválido ou expirado |
| 404 | Recurso não encontrado |
| 409 | E-mail já cadastrado |
---
### Deploy com Docker / Podman
```bash
cd backend
# Build da imagem
podman build -t top-tran-backend .
# Subir com compose
podman-compose up -d
```
O container expõe a porta `3000` e o serviço é reiniciado automaticamente em caso de falha.
---
## Mobile
### Tecnologias
| Pacote | Versão | Função |
|---|---|---|
| React Native | 0.81.5 | Framework mobile |
| Expo | 54 | Plataforma e toolchain |
| Expo Router | 6 | Navegação baseada em arquivos |
| Axios | 1 | Cliente HTTP |
| TypeScript | 5 | Tipagem |
### Telas
| Arquivo | Rota | Descrição |
|---|---|---|
| `src/app/index.tsx` | `/` | Tela de login |
| `src/app/signup.tsx` | `/signup` | Tela de cadastro |
### Execução
```bash
cd mobile
# Instalar dependências
npm install
# Iniciar o servidor Expo
npm start
# Abrir no Android
npm run android
# Abrir no iOS
npm run ios
```
### Conectar ao dispositivo Android via AVD na VM
1. Ligue o dispositivo Android (AVD)
2. No terminal local, crie o túnel SSH reverso:
```bash
ssh -R 5555:localhost:5555 dev@175.15.15.93
```
3. Conecte o ADB ao dispositivo tunelado:
```bash
adb connect localhost:5555
```