Skip to content

pedronalis/coins-backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Ā 

History

9 Commits
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 

Repository files navigation

šŸŖ™ Backend REST API - Moedas de Ouro

Backend Node.js + Express para gerenciamento de moedas de ouro, com sistema de autenticação admin e API pública.

šŸ“‹ Estrutura do Projeto

coins-backend/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ index.js              # Entry point da aplicação
│   ā”œā”€ā”€ db.js                 # Pool de conexƵes PostgreSQL
│   ā”œā”€ā”€ middlewares/
│   │   ā”œā”€ā”€ authApiKey.js    # Validação de x-api-key
│   │   └── authAdminToken.js # Validação de JWT admin
│   └── routes/
│       ā”œā”€ā”€ coins.js         # Rotas pĆŗblicas (POST /coins)
│       ā”œā”€ā”€ adminAuth.js     # Rotas de autenticação admin
│       └── adminCoins.js    # Rotas admin de gerenciamento
ā”œā”€ā”€ package.json
└── Dockerfile

šŸš€ Funcionalidades

  • REST API em Node.js + Express
  • Banco de dados PostgreSQL
  • Autenticação via API Key e JWT
  • Rastreamento de consultas (user_consults_quantity e statement_consults_quantity)
  • CRUD completo de usuĆ”rios e moedas
  • Histórico de transaƧƵes (spend_history)

šŸ—„ļø Estrutura do Banco de Dados

CREATE TABLE coins (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL,
  email TEXT NOT NULL UNIQUE,
  coins INTEGER NOT NULL DEFAULT 0,
  user_consults_quantity INTEGER NOT NULL DEFAULT 0,
  statement_consults_quantity INTEGER NOT NULL DEFAULT 0,
  user_consulted_at TIMESTAMP WITH TIME ZONE,
  admin_consulted_at TIMESTAMP WITH TIME ZONE,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  spend_history JSONB NOT NULL DEFAULT '[]'::jsonb
);

šŸ“” API Endpoints

PĆŗblicos (requerem apenas x-api-key)

POST /coins

Busca moedas de um usuƔrio pelo e-mail.

Headers:

x-api-key: <API_KEY>
Content-Type: application/json

Body:

{
  "email": "usuario@exemplo.com",
  "consultType": "user"  // ou "statement" para extrato
}

Respostas:

  • 200 OK: { "email": "usuario@exemplo.com", "coins": 123, "spend_history": [...] }
  • 404 Not Found: { "error": "VocĆŖ ainda nĆ£o possui moedas de ouro 😢" }
  • 400 Bad Request: { "error": "Email is required" } ou { "error": "Invalid email format" }

Admin - Autenticação (requerem x-api-key)

POST /admin/login

Autentica o administrador e retorna token JWT.

Headers:

x-api-key: <API_KEY>
Content-Type: application/json

Body:

{
  "email": "admin@exemplo.com",
  "password": "senha_secreta"
}

Resposta 200:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "email": "admin@exemplo.com"
}

Respostas de erro:

  • 401 Unauthorized: { "error": "Invalid credentials" }
  • 400 Bad Request: { "error": "Email and password are required" }

GET /admin/me

Valida a sessão do admin e retorna informações.

Headers:

x-api-key: <API_KEY>
Authorization: Bearer <JWT_TOKEN>

Resposta 200:

{
  "email": "admin@exemplo.com",
  "role": "admin"
}

Respostas de erro:

  • 401 Unauthorized: { "error": "Invalid or expired token" } ou { "error": "Missing or invalid Authorization header" }

Admin - Gerenciamento (requerem x-api-key + JWT)

Importante: Todas as rotas /admin/* (exceto /admin/login e /admin/me) exigem dupla proteção:

  1. Header x-api-key vƔlido
  2. Header Authorization: Bearer <JWT_TOKEN> vƔlido

GET /admin/coins

Lista registros da tabela coins com filtros opcionais.

Headers:

x-api-key: <API_KEY>
Authorization: Bearer <JWT_TOKEN>

Query Parameters (opcionais):

  • name - Filtro por nome (busca parcial, case-insensitive)
  • email - Filtro por email (busca parcial, case-insensitive)

Exemplo:

GET /admin/coins?name=João&email=exemplo

Resposta 200:

{
  "items": [
    {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@exemplo.com",
      "coins": 150,
      "user_consults_quantity": 5,
      "statement_consults_quantity": 3,
      "user_consulted_at": "2024-01-15T10:30:00.000Z",
      "admin_consulted_at": "2024-01-20T14:00:00.000Z",
      "created_at": "2024-01-01T00:00:00.000Z",
      "updated_at": "2024-01-20T14:00:00.000Z",
      "spend_history": []
    }
  ],
  "count": 1
}

POST /admin/coins

Cria um novo registro na tabela coins.

Headers:

x-api-key: <API_KEY>
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

Body:

{
  "name": "Nome do usuƔrio",
  "email": "usuario@exemplo.com",
  "coins": 0
}

Resposta 201: Retorna o registro criado completo (mesmo formato da listagem).

Respostas de erro:

  • 409 Conflict: { "error": "Email already exists" }
  • 400 Bad Request: { "error": "Name is required" } ou { "error": "Email is required" }

PATCH /admin/coins

Atualiza a quantidade de moedas de um usuƔrio.

Headers:

x-api-key: <API_KEY>
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

Body (opção 1 - valor absoluto):

{
  "email": "usuario@exemplo.com",
  "coins": 200
}

Body (opção 2 - delta):

{
  "email": "usuario@exemplo.com",
  "coinsDelta": 50
}

Body (atualizar mĆŗltiplos campos):

{
  "email": "usuario@exemplo.com",
  "coins": 200,
  "name": "Novo Nome",
  "spend_history": [...]
}

Regras:

  • email Ć© obrigatório
  • Pelo menos um entre coins, coinsDelta, name ou spend_history deve ser fornecido
  • Se ambos coins e coinsDelta forem fornecidos, coins tem prioridade e coinsDelta Ć© ignorado
  • O valor final de coins nĆ£o pode ser negativo

Resposta 200: Retorna o registro atualizado completo (mesmo formato da listagem).

Respostas de erro:

  • 404 Not Found: { "error": "Email not found" }
  • 400 Bad Request: { "error": "Email is required" } ou { "error": "Coins cannot be negative" }

DELETE /admin/coins

Remove um registro da tabela coins pelo email.

Headers:

x-api-key: <API_KEY>
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

Body:

{
  "email": "usuario@exemplo.com"
}

Resposta 200:

{
  "message": "User deleted successfully"
}

Respostas de erro:

  • 404 Not Found: { "error": "Email not found" }

šŸ”§ Configuração

VariƔveis de Ambiente

Crie um arquivo .env na pasta coins-backend/:

Obrigatórias:

  • API_KEY - Chave de API para autenticação nas rotas pĆŗblicas e admin
  • PGHOST - Host do PostgreSQL (ou use DATABASE_URL)
  • PGPORT - Porta do PostgreSQL (padrĆ£o: 5432)
  • PGDATABASE - Nome do banco de dados
  • PGUSER - UsuĆ”rio do PostgreSQL
  • PGPASSWORD - Senha do PostgreSQL
  • ADMIN_EMAIL - Email do administrador
  • ADMIN_PASSWORD - Senha do administrador
  • JWT_SECRET - Chave secreta para assinar tokens JWT

Opcionais:

  • DATABASE_URL - URL completa de conexĆ£o (substitui PGHOST, PGPORT, etc.)
  • JWT_EXPIRES_IN - Tempo de expiração do token JWT (padrĆ£o: '8h')
  • PORT - Porta do servidor (padrĆ£o: 3000)
  • NODE_ENV - Ambiente de execução (development/production)

šŸ“¦ Instalação

cd coins-backend
npm install

šŸš€ Execução

npm start

Para desenvolvimento com auto-reload:

npm run dev

🐳 Deploy com Docker

Build

cd coins-backend
docker build -t coins-backend .

Run

docker run -p 3000:3000 --env-file .env coins-backend

šŸ“ MigraƧƵes

Execute a migração para adicionar a coluna statement_consults_quantity:

ALTER TABLE coins 
ADD COLUMN IF NOT EXISTS statement_consults_quantity INTEGER NOT NULL DEFAULT 0;

Ou execute o arquivo coins-backend/migration_add_statement_consults.sql.

šŸ“Š Rastreamento de Consultas

O sistema rastreia dois tipos de consultas:

  • user_consults_quantity: Incrementado quando o usuĆ”rio carrega a pĆ”gina com suas moedas (consultType: "user")
  • statement_consults_quantity: Incrementado quando o usuĆ”rio visualiza o extrato (consultType: "statement")

šŸ” SeguranƧa

  • Todas as rotas (exceto /health) exigem x-api-key vĆ”lido
  • Rotas admin de gerenciamento exigem JWT vĆ”lido alĆ©m do x-api-key
  • Tokens JWT expiram após o tempo configurado em JWT_EXPIRES_IN (padrĆ£o: 8 horas)
  • Use HTTPS em produção
  • Mantenha JWT_SECRET e ADMIN_PASSWORD seguros

šŸ“„ LicenƧa

ISC

šŸ‘„ Autor

Pedro Nalis

About

Backend REST API para gerenciamento de moedas de ouro

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors