Unifies naming conventions for users, companies, and rides across backend and mobile app, standardizing field names for consistency and easier data interchange. Introduces endpoints to fetch all companies and rides for sync. Enhances sync logic to support both upload and download of companies, including first-time population from server. Updates local database schema and access logic to match backend structure, improving maintainability and reliability of sync. |
||
|---|---|---|
| .claude | ||
| backend | ||
| toptran-app | ||
| .gitignore | ||
| README.md | ||
Toptran
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.
Estrutura do projeto
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
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:
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
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.
// 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.
// Request body
{
"email": "joao@email.com",
"password": "minhasenha"
}
// Response 200
{
"accessToken": "eyJ...",
"refreshToken": "uuid"
}
POST /auth/logout
Revoga o refresh token.
// 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.
// 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.
// 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
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
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
- Ligue o dispositivo Android (AVD)
- No terminal local, crie o túnel SSH reverso:
ssh -R 5555:localhost:5555 dev@175.15.15.93 - Conecte o ADB ao dispositivo tunelado:
adb connect localhost:5555