Enviar arquivos para "/"
This commit is contained in:
108
README.md
Normal file
108
README.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# Biblioteca do Usuário - GameVerse
|
||||||
|
|
||||||
|
Este é o microsserviço da Biblioteca do Usuário para o projeto GameVerse.
|
||||||
|
Eu sou responsável por guardar jogos e gift cards que os usuários compraram.
|
||||||
|
Aqui eu mantenho a coleção digital de cada usuário organizada e acessível.
|
||||||
|
|
||||||
|
## Minha responsabilidade
|
||||||
|
|
||||||
|
- Guardar jogos comprados pelo usuário
|
||||||
|
- Guardar gift cards adquiridos
|
||||||
|
- Manter o histórico de aquisições
|
||||||
|
- Expor a biblioteca digital para outros serviços
|
||||||
|
|
||||||
|
## Tecnologias usadas
|
||||||
|
|
||||||
|
- Node.js
|
||||||
|
- Express.js
|
||||||
|
- MySQL
|
||||||
|
- CORS
|
||||||
|
|
||||||
|
## Estrutura de dados
|
||||||
|
|
||||||
|
Tabela: `users_library`
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE users_library (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
user_id INT NOT NULL,
|
||||||
|
type ENUM('game', 'gift_card') NOT NULL,
|
||||||
|
item_id INT NOT NULL,
|
||||||
|
title VARCHAR(255) NOT NULL,
|
||||||
|
platform VARCHAR(100),
|
||||||
|
acquired_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Endpoints da API
|
||||||
|
|
||||||
|
### POST /library/add
|
||||||
|
Adiciona um item manualmente à biblioteca do usuário.
|
||||||
|
|
||||||
|
Exemplo de request:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"type": "game",
|
||||||
|
"item_id": 123,
|
||||||
|
"title": "The Witcher 3",
|
||||||
|
"platform": "Steam"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### GET /library/user/:user_id
|
||||||
|
Retorna todos os itens da biblioteca de um usuário.
|
||||||
|
|
||||||
|
### POST /library/integration/payment-approved
|
||||||
|
Recebe confirmação de pagamento aprovado e adiciona o item à biblioteca.
|
||||||
|
|
||||||
|
## Fluxo de integração
|
||||||
|
|
||||||
|
1. Recebo dados do serviço de pagamentos
|
||||||
|
2. Verifico se o item já está na biblioteca
|
||||||
|
3. Se não estiver, adiciono ao banco
|
||||||
|
4. Retorno confirmação de sucesso ou erro
|
||||||
|
|
||||||
|
## Dados de teste
|
||||||
|
|
||||||
|
Usuário 1:
|
||||||
|
- Jogo: "The Witcher 3: Wild Hunt" (Steam)
|
||||||
|
- Gift Card: "Steam Gift Card $50"
|
||||||
|
|
||||||
|
Usuário 2:
|
||||||
|
- Jogo: "Cyberpunk 2077" (Epic Games)
|
||||||
|
- Jogo: "FIFA 24" (EA Play)
|
||||||
|
|
||||||
|
## Como executar
|
||||||
|
|
||||||
|
1. Instalar dependências:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
2. Criar o banco de dados `gameverse_library` e executar `schema.sql`
|
||||||
|
3. Iniciar o serviço:
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
O serviço estará disponível em `http://localhost:3005`
|
||||||
|
|
||||||
|
## Padrão de respostas
|
||||||
|
|
||||||
|
Todas as respostas seguem este formato:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": boolean,
|
||||||
|
"message": string,
|
||||||
|
"data": any,
|
||||||
|
"error": any
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Desenvolvido por:
|
||||||
|
- André de Oliveira Braga
|
||||||
|
- Izadora Lima de Mendonça
|
||||||
|
|
||||||
|
Centro Universitário Uninorte - Curso de Sistemas de Informação
|
||||||
24
db.js
Normal file
24
db.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const mysql = require('mysql2');
|
||||||
|
|
||||||
|
// Aqui está a configuração da nossa conexão com o banco de dados!
|
||||||
|
// Cada microsserviço tem seu próprio banco, lembra? Isso garante independência.
|
||||||
|
// Estou usando MySQL porque é confiável e funciona bem com Node.js.
|
||||||
|
const connection = mysql.createConnection({
|
||||||
|
host: 'localhost', // O banco roda na mesma máquina
|
||||||
|
user: 'root', // Usuário padrão do MySQL
|
||||||
|
password: '', // Sem senha para desenvolvimento local
|
||||||
|
database: 'gameverse_library' // Nosso banco exclusivo da biblioteca
|
||||||
|
});
|
||||||
|
|
||||||
|
// Esta função tenta conectar ao banco quando o serviço inicia.
|
||||||
|
// Se der erro, a gente sabe que tem problema na configuração do MySQL.
|
||||||
|
connection.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Erro ao conectar:', err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('Banco conectado!');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Exportamos a conexão para usar em outros arquivos, principalmente no model.
|
||||||
|
module.exports = connection;
|
||||||
127
libraryController.js
Normal file
127
libraryController.js
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
const model = require('../models/libraryModel');
|
||||||
|
|
||||||
|
// Este é o "cérebro" do nosso microsserviço!
|
||||||
|
// O controller recebe as requisições HTTP, valida os dados,
|
||||||
|
// chama as funções do model e retorna respostas apropriadas.
|
||||||
|
// É como o gerente que coordena tudo.
|
||||||
|
|
||||||
|
// Função para adicionar um item manualmente à biblioteca.
|
||||||
|
// Pode ser usado para correções ou imports especiais.
|
||||||
|
exports.addItem = (req, res) => {
|
||||||
|
// Validação básica dos dados obrigatórios
|
||||||
|
const { user_id, type, item_id, title } = req.body;
|
||||||
|
|
||||||
|
if (!user_id || !type || !item_id || !title) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
message: 'Dados obrigatórios faltando: user_id, type, item_id, title'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Só aceitamos tipos válidos para manter consistência
|
||||||
|
if (!['game', 'gift_card'].includes(type)) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
message: 'Tipo inválido. Use "game" ou "gift_card"'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chama o model para adicionar o item
|
||||||
|
model.addItem(req.body, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
error: err,
|
||||||
|
message: 'Erro ao adicionar item à biblioteca'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Item adicionado à biblioteca com sucesso!'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Função que retorna toda a biblioteca de um usuário.
|
||||||
|
// É chamada quando o usuário abre sua página de biblioteca.
|
||||||
|
exports.getLibrary = (req, res) => {
|
||||||
|
const user_id = req.params.user_id;
|
||||||
|
|
||||||
|
// Validação do ID do usuário
|
||||||
|
if (!user_id || isNaN(user_id)) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
message: 'ID do usuário inválido'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Busca todos os itens do usuário
|
||||||
|
model.getUserLibrary(user_id, (err, results) => {
|
||||||
|
if (err) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
error: err,
|
||||||
|
message: 'Erro ao buscar biblioteca'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
data: results,
|
||||||
|
message: `Encontrados ${results.length} itens na biblioteca`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Esta é a função mais importante para integração!
|
||||||
|
// É chamada AUTOMATICAMENTE pelo serviço de pagamentos quando uma compra é aprovada.
|
||||||
|
// Garante que o usuário receba seu jogo/gift card na biblioteca.
|
||||||
|
exports.paymentApproved = (req, res) => {
|
||||||
|
const data = req.body;
|
||||||
|
|
||||||
|
// Validações rigorosas pois isso vem de outro serviço
|
||||||
|
const { user_id, type, item_id, title } = data;
|
||||||
|
|
||||||
|
if (!user_id || !type || !item_id || !title) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
message: 'Dados de pagamento incompletos'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primeiro verifica se o usuário já tem esse item (evita duplicatas)
|
||||||
|
model.checkItem(user_id, item_id, (err, results) => {
|
||||||
|
if (err) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
error: err,
|
||||||
|
message: 'Erro ao verificar item existente'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se já tem, informa que não precisa adicionar novamente
|
||||||
|
if (results.length > 0) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
message: 'Usuário já possui este item em sua biblioteca'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se não tem, adiciona o item
|
||||||
|
model.addItem(data, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
error: err,
|
||||||
|
message: 'Erro ao adicionar item após pagamento'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Pagamento aprovado! Item adicionado à biblioteca.'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
41
schema.sql
Normal file
41
schema.sql
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-- 🎮 SCHEMA DO BANCO DE DADOS - Biblioteca do Usuário GameVerse
|
||||||
|
-- Este arquivo cria minha "casa" no banco de dados!
|
||||||
|
-- Cada microsserviço tem seu próprio banco, lembra? Isso me deixa independente.
|
||||||
|
|
||||||
|
-- Criando meu banco de dados exclusivo
|
||||||
|
CREATE DATABASE IF NOT EXISTS gameverse_library;
|
||||||
|
USE gameverse_library;
|
||||||
|
|
||||||
|
-- Minha tabela principal: users_library
|
||||||
|
-- Aqui eu guardo TODOS os jogos e gift cards que os usuários compraram
|
||||||
|
CREATE TABLE users_library (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY, -- ID único para cada item na biblioteca
|
||||||
|
user_id INT NOT NULL, -- ID do usuário dono do item
|
||||||
|
type ENUM('game', 'gift_card') NOT NULL, -- Tipo: jogo ou cartão presente
|
||||||
|
item_id INT NOT NULL, -- ID do item no catálogo geral
|
||||||
|
title VARCHAR(255) NOT NULL, -- Nome do jogo ou gift card
|
||||||
|
platform VARCHAR(100), -- Plataforma (Steam, Epic, etc.)
|
||||||
|
acquired_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Quando ganhou isso na biblioteca
|
||||||
|
|
||||||
|
-- Índices para buscas rápidas (como um catálogo organizado!)
|
||||||
|
INDEX idx_user_id (user_id), -- Para buscar biblioteca de um usuário
|
||||||
|
INDEX idx_item_id (item_id), -- Para verificar se já tem o item
|
||||||
|
INDEX idx_type (type) -- Para separar jogos de gift cards
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 🎭 DADOS DE TESTE - Para desenvolvimento e testes
|
||||||
|
-- Estes são exemplos de bibliotecas que uso para testar se tudo funciona
|
||||||
|
INSERT INTO users_library (user_id, type, item_id, title, platform) VALUES
|
||||||
|
-- Biblioteca do usuário 1 (tem um jogo e um gift card)
|
||||||
|
(1, 'game', 1, 'The Witcher 3: Wild Hunt', 'Steam'),
|
||||||
|
(1, 'gift_card', 2, 'Steam Gift Card $50', 'Steam'),
|
||||||
|
|
||||||
|
-- Biblioteca do usuário 2 (tem dois jogos)
|
||||||
|
(2, 'game', 3, 'Cyberpunk 2077', 'Epic Games'),
|
||||||
|
(2, 'game', 4, 'FIFA 24', 'EA Play');
|
||||||
|
|
||||||
|
-- Agora meu banco está pronto! 🎉
|
||||||
|
-- Posso guardar jogos, gift cards, e mostrar para os usuários suas coleções!
|
||||||
|
|
||||||
|
-- Desenvolvido por: André de Oliveira Braga e Izadora Lima de Mendonça
|
||||||
|
-- Projeto GameVerse - Microsserviços - Centro Universitário Uninorte - Curso de Sistemas de Informação
|
||||||
54
tests.http
Normal file
54
tests.http
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# 🧪 TESTES DA API - Biblioteca do Usuário GameVerse
|
||||||
|
# Este arquivo contém exemplos de como testar meus endpoints
|
||||||
|
# Use com REST Client no VS Code ou qualquer ferramenta HTTP
|
||||||
|
|
||||||
|
### 1. Testar adicionar item manualmente
|
||||||
|
POST http://localhost:3005/library/add
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"type": "game",
|
||||||
|
"item_id": 999,
|
||||||
|
"title": "Test Game",
|
||||||
|
"platform": "Steam"
|
||||||
|
}
|
||||||
|
|
||||||
|
### 2. Ver biblioteca do usuário 1
|
||||||
|
GET http://localhost:3005/library/user/1
|
||||||
|
|
||||||
|
### 3. Ver biblioteca do usuário 2
|
||||||
|
GET http://localhost:3005/library/user/2
|
||||||
|
|
||||||
|
### 4. Simular pagamento aprovado (integração)
|
||||||
|
POST http://localhost:3005/library/integration/payment-approved
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"type": "gift_card",
|
||||||
|
"item_id": 888,
|
||||||
|
"title": "Epic Games Gift Card $25",
|
||||||
|
"platform": "Epic Games"
|
||||||
|
}
|
||||||
|
|
||||||
|
### 5. Testar erro - dados faltando
|
||||||
|
POST http://localhost:3005/library/add
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user_id": 1
|
||||||
|
// Faltam type, item_id, title
|
||||||
|
}
|
||||||
|
|
||||||
|
### 6. Testar erro - tipo inválido
|
||||||
|
POST http://localhost:3005/library/add
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"type": "filme", // Tipo inválido
|
||||||
|
"item_id": 123,
|
||||||
|
"title": "Test Movie",
|
||||||
|
"platform": "Netflix"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user