Trainify é uma solução robusta para gerenciamento de academias, proporcionando funcionalidades essenciais como registro de usuários, autenticação, localização de academias próximas e controle de check-ins. Inspirada em plataformas como o GymPass, esta API oferece uma experiência eficiente e segura para academias e seus frequentadores.
- 🟢 Node.js: Plataforma para execução do JavaScript no servidor.
- 🟦 TypeScript: Superset do JavaScript com tipagem estática.
- ⚡ Fastify: Framework web de alta performance para Node.js.
- 🗄️ PostgreSQL: Banco de dados relacional utilizado para armazenar informações.
- 🛢️ Prisma: ORM moderno para interações com o banco de dados.
- 🐳 Docker: Containerização para ambiente de desenvolvimento.
- 💎 Zod: Validação de esquemas e dados.
- 🛡️ JWT: Json Web Tokens para autenticação.
- 🧪 Vitest: Framework de testes.
- 🕷️ Supertest: Biblioteca para testar APIs de forma simples e eficaz.
- 🔨 Tsup: Ferramenta para bundling.
- ⚙️ ESLint: Linter para garantir a qualidade do código.
- 🔒 Bcrypt: Biblioteca para hashing de senhas.
- 📅 Day.js: Manipulação de datas.
- 🌱 Dotenv: Gerenciamento de variáveis de ambiente.
- ⚙️ GitHub Actions: Ferramenta de CI que automatiza o processo de testes e implantações.
- 🎉 Criar usuário: Cria um novo usuário na plataforma.
- 🔐 Autenticar usuário: Realiza o login de um usuário existente.
- 🔄 Refresh token: Gera um novo token de autenticação.
- 👤 Ver perfil: Retorna as informações do perfil do usuário autenticado.
- 🏋️ Criar academia: Adiciona uma nova academia ao sistema.
- 🔍 Buscar academias: Localiza academias com base em critérios de pesquisa.
- 📍 Listar academias próximas: Retorna academias localizadas nas proximidades do usuário.
- ✅ Criar check-in: Registra a presença do usuário em uma academia.
- 📜 Histórico de check-ins: Exibe o histórico de check-ins do usuário.
- 📊 Métricas de check-ins: Fornece dados sobre a quantidade total de check-ins realizados.
- ✔️ Validar check-in: Confirma a validade de um check-in.
-
Clone o repositório:
git clone https://github.com/joschonarth/trainify.git
-
Crie um arquivo
.env
a partir do exemplo:cp .env.example .env
Edite o arquivo
.env
para configurar as variáveis de ambiente necessárias. -
Instale as dependências:
npm install
-
Inicie o banco de dados PostgreSQL utilizando o container Docker com a imagem
bitnami/postgresql
:docker-compose up -d
-
Execute as migrações do banco de dados:
npx prisma migrate dev
-
Inicie a API:
npm run start:dev
A aplicação estará disponível em http://localhost:3333.
-
Descrição: Cria um novo usuário na plataforma.
-
Método:
POST
-
URL:
/users
-
Corpo da Requisição:
{ "name": "John Doe", "email": "johndoe@example.com", "password": "123456" }
-
Descrição: Realiza o login de um usuário existente.
-
Método:
POST
-
URL:
/sessions
-
Corpo da Requisição:
{ "email": "johndoe@example.com", "password": "123456" }
-
Exemplo de Resposta:
{ "token": "eyJhbGciOiJIUzI1NiIsInR..." }
-
Descrição: Gera um novo token de autenticação.
-
Método:
PATCH
-
URL:
/token/refresh
-
Corpo da Requisição:
-
Exemplo de Resposta:
{ "token": "eyJhbGciOiJIUzI1NiIsInR..." }
-
Descrição: Retorna as informações do perfil do usuário autenticado.
-
Método:
GET
-
URL:
/me
-
Exemplo de Resposta:
{ "user": { "id": "be48f670-7df1-44b8-b4c0-7f6722978ed6", "name": "John Doe", "email": "johndoe@gmail.com", "role": "MEMBER", "created_at": "2025-02-24T17:53:17.994Z" } }
-
Descrição: Adiciona uma nova academia ao sistema.
-
Método:
POST
-
URL:
/gyms
-
Corpo da Requisição:
{ "title": "TypeScript Gym", "description": "Some description", "phone": "11999999999", "latitude": -20.7400886, "longitude": -47.753894 }
-
Descrição: Localiza academias com base em critérios de pesquisa.
-
Método:
GET
-
URL:
/gyms/search
-
Query Params:
q
(string, required): Termo de pesquisa para filtrar academias pelo título ou descrição.page
(number, optional): Número da página para paginação dos resultados.
-
Exemplo de Requisição:
GET /gyms/search?q=TypeScript&page=1
-
Exemplo de Resposta:
{ "gyms": [ { "id": "8a83ce21-250f-443e-ac06-a1061c9ffb0c", "title": "TypeScript Gym", "description": "Some description", "phone": "11999999999", "latitude": "-20.7400886", "longitude": "-47.753894" } ] }
-
Descrição: Retorna academias localizadas nas proximidades do usuário.
-
Método:
GET
-
URL:
/gyms/nearby
-
Parâmetros de Consulta:
latitude
(number, required) - Latitude atual do usuário (deve estar entre -90 e 90).longitude
(number, required) - Longitude atual do usuário (deve estar entre -180 e 180).
-
Exemplo de Requisição:
GET /gyms/nearby?latitude=-20.7400886&longitude=-47.753894
-
Exemplo de Resposta:
{ "gyms": [ { "id": "8a83ce21-250f-443e-ac06-a1061c9ffb0c", "title": "TypeScript Gym", "description": "Some description", "phone": "11999999999", "latitude": "-20.7400886", "longitude": "-47.753894" }, { "id": "1aedfe5a-4aa1-452a-b0c2-b40c4b74b8a4", "title": "JavaScript Gym", "description": "Some description", "phone": "11999999999", "latitude": "-20.7400886", "longitude": "-47.753894" } ] }
-
Descrição: Registra a presença do usuário em uma academia.
-
Método:
POST
-
URL:
/gyms/:gymId/check-ins
-
Corpo da Requisição:
{ "latitude": -20.7400886, "longitude": -47.753894 }
-
Descrição: Exibe o histórico de check-ins do usuário.
-
Método:
GET
-
URL:
/check-ins/history
-
Query Params:
page
(number, optional): Número da página para paginação dos resultados.
-
Exemplo de Resposta:
{ "checkIns": [ { "id": "ccfd55a9-9eb2-4d05-9b0b-ef19e70165f5", "created_at": "2025-02-24T18:29:52.436Z", "validated_at": null, "user_id": "be48f670-7df1-44b8-b4c0-7f6722978ed6", "gym_id": "8a83ce21-250f-443e-ac06-a1061c9ffb0c" } ] }
-
Descrição: Fornece dados sobre a quantidade total de check-ins realizados.
-
Método:
GET
-
URL:
/check-ins/metrics
-
Exemplo de Resposta:
{ "checkInsCount": 1 }
- Descrição: Confirma a validade de um check-in.
- Método:
PATCH
- URL:
/check-ins/:checkInId/validate
As rotas da API estão protegidas por autenticação JWT (JSON Web Token). Para acessar as rotas que requerem autenticação, é necessário obter um token de acesso.
-
Faça a autenticação com suas credenciais (email e senha) na rota
/sessions
para obter um token JWT:- Método:
POST
- URL:
/sessions
- Corpo da Requisição:
{ "email": "user@email.com", "password": "password" }
- Resposta:
{ "token": "your_token" }
- Método:
-
Utilize o token nas requisições às rotas protegidas, incluindo-o no Postman (ou outro API Client) da seguinte forma:
- No Postman, vá até a aba Authorization.
- Selecione o tipo Bearer Token.
- No campo Token, insira o valor do seu token JWT obtido no passo anterior.
A aplicação implementa uma autorização baseada em cargos (RBAC - Role-Based Access Control). Algumas rotas, como a de criar academia e validar check-in, requerem que o usuário tenha a role ADMIN para serem acessadas. Portanto, certifique-se de que sua conta possui as permissões necessárias para executar essas ações.
Este projeto inclui testes unitários e testes E2E (end-to-end) para garantir a confiabilidade e o funcionamento correto dos recursos implementados. Para executar os testes, utilize os seguintes comandos:
-
Executar testes unitários:
npm run test
-
Executar testes unitários em modo de observação:
npm run test:watch
-
Preparar o ambiente do Prisma antes dos testes E2E:
npm run pretest:e2e
-
Executar testes E2E:
npm run test:e2e
-
Executar testes E2E em modo de observação:
npm run test:e2e:watch
-
Executar testes com cobertura:
npm run test:coverage
-
Executar a interface do usuário do Vitest:
npm run test:ui
O projeto utiliza o GitHub Actions para automação de testes, garantindo qualidade contínua no desenvolvimento. Os testes unitários são executados automaticamente a cada push
para o repositório, enquanto os testes E2E são acionados em cada pull request
. Essa configuração assegura que todas as alterações sejam validadas, promovendo um fluxo de trabalho eficiente e livre de erros.
Contribuições são bem-vindas! Sinta-se à vontade para abrir issues ou pull requests com melhorias ou correções. 🚀