Enviar arquivos para "/"

This commit is contained in:
2026-04-29 01:10:56 +00:00
parent 7e7fc7eb0f
commit 13747d1d6c
5 changed files with 239 additions and 239 deletions

58
app.js
View File

@@ -1,29 +1,29 @@
const express = require('express'); const express = require('express');
const cors = require('cors'); const cors = require('cors');
const routes = require('./routes/libraryRoutes'); const routes = require('./routes/libraryRoutes');
// Este é o coração do nosso microsserviço da Biblioteca do Usuário! // Este é o coração do nosso microsserviço da Biblioteca do Usuário!
// Aqui eu configuro o servidor Express que vai gerenciar todas as rotas da nossa API. // Aqui eu configuro o servidor Express que vai gerenciar todas as rotas da nossa API.
// É como o porteiro do prédio - recebe as requisições e direciona para os andares certos. // É como o porteiro do prédio - recebe as requisições e direciona para os andares certos.
const app = express(); const app = express();
// CORS é fundamental para permitir que outros microsserviços (como o frontend ou Laravel central) // CORS é fundamental para permitir que outros microsserviços (como o frontend ou Laravel central)
// façam requisições para nossa API sem problemas de segurança do navegador. // façam requisições para nossa API sem problemas de segurança do navegador.
app.use(cors()); app.use(cors());
// Este middleware transforma o corpo das requisições JSON em objetos JavaScript // Este middleware transforma o corpo das requisições JSON em objetos JavaScript
// que podemos usar facilmente nos nossos controllers. // que podemos usar facilmente nos nossos controllers.
app.use(express.json()); app.use(express.json());
// Todas as rotas da biblioteca ficam sob o prefixo '/library' // Todas as rotas da biblioteca ficam sob o prefixo '/library'
// Isso organiza nossa API e deixa claro que tudo aqui é sobre a biblioteca do usuário. // Isso organiza nossa API e deixa claro que tudo aqui é sobre a biblioteca do usuário.
app.use('/library', routes); app.use('/library', routes);
// O serviço roda na porta 3005 - escolhi uma porta alta para não conflitar // O serviço roda na porta 3005 - escolhi uma porta alta para não conflitar
// com outros serviços que podem estar rodando na máquina. // com outros serviços que podem estar rodando na máquina.
app.listen(3005, () => { app.listen(3005, () => {
console.log('Library Service rodando na porta 3005'); console.log('Library Service rodando na porta 3005');
}); });
// Desenvolvido por: André de Oliveira Braga e Izadora Lima de Mendonça // 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 // Projeto GameVerse - Microsserviços - Centro Universitário Uninorte - Curso de Sistemas de Informação

48
db.js
View File

@@ -1,24 +1,24 @@
const mysql = require('mysql2'); const mysql = require('mysql2');
// Aqui está a configuração da nossa conexão com o banco de dados! // 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. // 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. // Estou usando MySQL porque é confiável e funciona bem com Node.js.
const connection = mysql.createConnection({ const connection = mysql.createConnection({
host: 'localhost', // O banco roda na mesma máquina host: 'localhost', // O banco roda na mesma máquina
user: 'root', // Usuário padrão do MySQL user: 'root', // Usuário padrão do MySQL
password: '', // Sem senha para desenvolvimento local password: '', // Sem senha para desenvolvimento local
database: 'gameverse_library' // Nosso banco exclusivo da biblioteca database: 'gameverse_library' // Nosso banco exclusivo da biblioteca
}); });
// Esta função tenta conectar ao banco quando o serviço inicia. // 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. // Se der erro, a gente sabe que tem problema na configuração do MySQL.
connection.connect((err) => { connection.connect((err) => {
if (err) { if (err) {
console.error('Erro ao conectar:', err); console.error('Erro ao conectar:', err);
return; return;
} }
console.log('Banco conectado!'); console.log('Banco conectado!');
}); });
// Exportamos a conexão para usar em outros arquivos, principalmente no model. // Exportamos a conexão para usar em outros arquivos, principalmente no model.
module.exports = connection; module.exports = connection;

View File

@@ -1,127 +1,127 @@
const model = require('../models/libraryModel'); const model = require('../models/libraryModel');
// Este é o "cérebro" do nosso microsserviço! // Este é o "cérebro" do nosso microsserviço!
// O controller recebe as requisições HTTP, valida os dados, // O controller recebe as requisições HTTP, valida os dados,
// chama as funções do model e retorna respostas apropriadas. // chama as funções do model e retorna respostas apropriadas.
// É como o gerente que coordena tudo. // É como o gerente que coordena tudo.
// Função para adicionar um item manualmente à biblioteca. // Função para adicionar um item manualmente à biblioteca.
// Pode ser usado para correções ou imports especiais. // Pode ser usado para correções ou imports especiais.
exports.addItem = (req, res) => { exports.addItem = (req, res) => {
// Validação básica dos dados obrigatórios // Validação básica dos dados obrigatórios
const { user_id, type, item_id, title } = req.body; const { user_id, type, item_id, title } = req.body;
if (!user_id || !type || !item_id || !title) { if (!user_id || !type || !item_id || !title) {
return res.json({ return res.json({
success: false, success: false,
message: 'Dados obrigatórios faltando: user_id, type, item_id, title' message: 'Dados obrigatórios faltando: user_id, type, item_id, title'
}); });
} }
// Só aceitamos tipos válidos para manter consistência // Só aceitamos tipos válidos para manter consistência
if (!['game', 'gift_card'].includes(type)) { if (!['game', 'gift_card'].includes(type)) {
return res.json({ return res.json({
success: false, success: false,
message: 'Tipo inválido. Use "game" ou "gift_card"' message: 'Tipo inválido. Use "game" ou "gift_card"'
}); });
} }
// Chama o model para adicionar o item // Chama o model para adicionar o item
model.addItem(req.body, (err) => { model.addItem(req.body, (err) => {
if (err) { if (err) {
return res.json({ return res.json({
success: false, success: false,
error: err, error: err,
message: 'Erro ao adicionar item à biblioteca' message: 'Erro ao adicionar item à biblioteca'
}); });
} }
res.json({ res.json({
success: true, success: true,
message: 'Item adicionado à biblioteca com sucesso!' message: 'Item adicionado à biblioteca com sucesso!'
}); });
}); });
}; };
// Função que retorna toda a biblioteca de um usuário. // Função que retorna toda a biblioteca de um usuário.
// É chamada quando o usuário abre sua página de biblioteca. // É chamada quando o usuário abre sua página de biblioteca.
exports.getLibrary = (req, res) => { exports.getLibrary = (req, res) => {
const user_id = req.params.user_id; const user_id = req.params.user_id;
// Validação do ID do usuário // Validação do ID do usuário
if (!user_id || isNaN(user_id)) { if (!user_id || isNaN(user_id)) {
return res.json({ return res.json({
success: false, success: false,
message: 'ID do usuário inválido' message: 'ID do usuário inválido'
}); });
} }
// Busca todos os itens do usuário // Busca todos os itens do usuário
model.getUserLibrary(user_id, (err, results) => { model.getUserLibrary(user_id, (err, results) => {
if (err) { if (err) {
return res.json({ return res.json({
success: false, success: false,
error: err, error: err,
message: 'Erro ao buscar biblioteca' message: 'Erro ao buscar biblioteca'
}); });
} }
res.json({ res.json({
success: true, success: true,
data: results, data: results,
message: `Encontrados ${results.length} itens na biblioteca` message: `Encontrados ${results.length} itens na biblioteca`
}); });
}); });
}; };
// Esta é a função mais importante para integração! // Esta é a função mais importante para integração!
// É chamada AUTOMATICAMENTE pelo serviço de pagamentos quando uma compra é aprovada. // É chamada AUTOMATICAMENTE pelo serviço de pagamentos quando uma compra é aprovada.
// Garante que o usuário receba seu jogo/gift card na biblioteca. // Garante que o usuário receba seu jogo/gift card na biblioteca.
exports.paymentApproved = (req, res) => { exports.paymentApproved = (req, res) => {
const data = req.body; const data = req.body;
// Validações rigorosas pois isso vem de outro serviço // Validações rigorosas pois isso vem de outro serviço
const { user_id, type, item_id, title } = data; const { user_id, type, item_id, title } = data;
if (!user_id || !type || !item_id || !title) { if (!user_id || !type || !item_id || !title) {
return res.json({ return res.json({
success: false, success: false,
message: 'Dados de pagamento incompletos' message: 'Dados de pagamento incompletos'
}); });
} }
// Primeiro verifica se o usuário já tem esse item (evita duplicatas) // Primeiro verifica se o usuário já tem esse item (evita duplicatas)
model.checkItem(user_id, item_id, (err, results) => { model.checkItem(user_id, item_id, (err, results) => {
if (err) { if (err) {
return res.json({ return res.json({
success: false, success: false,
error: err, error: err,
message: 'Erro ao verificar item existente' message: 'Erro ao verificar item existente'
}); });
} }
// Se já tem, informa que não precisa adicionar novamente // Se já tem, informa que não precisa adicionar novamente
if (results.length > 0) { if (results.length > 0) {
return res.json({ return res.json({
success: false, success: false,
message: 'Usuário já possui este item em sua biblioteca' message: 'Usuário já possui este item em sua biblioteca'
}); });
} }
// Se não tem, adiciona o item // Se não tem, adiciona o item
model.addItem(data, (err) => { model.addItem(data, (err) => {
if (err) { if (err) {
return res.json({ return res.json({
success: false, success: false,
error: err, error: err,
message: 'Erro ao adicionar item após pagamento' message: 'Erro ao adicionar item após pagamento'
}); });
} }
res.json({ res.json({
success: true, success: true,
message: 'Pagamento aprovado! Item adicionado à biblioteca.' message: 'Pagamento aprovado! Item adicionado à biblioteca.'
}); });
}); });
}); });
}; };

View File

@@ -1,33 +1,33 @@
const db = require('../config/db'); const db = require('../config/db');
// Este arquivo é o nosso "guarda-roupa" - aqui guardamos todas as funções // Este arquivo é o nosso "guarda-roupa" - aqui guardamos todas as funções
// que interagem diretamente com o banco de dados da biblioteca. // que interagem diretamente com o banco de dados da biblioteca.
// Seguimos o padrão MVC: Model lida com dados, Controller com lógica, View com apresentação. // Seguimos o padrão MVC: Model lida com dados, Controller com lógica, View com apresentação.
// Função para adicionar um item (jogo ou gift card) à biblioteca do usuário. // Função para adicionar um item (jogo ou gift card) à biblioteca do usuário.
// É chamada quando um pagamento é aprovado ou quando queremos adicionar manualmente. // É chamada quando um pagamento é aprovado ou quando queremos adicionar manualmente.
exports.addItem = (data, callback) => { exports.addItem = (data, callback) => {
// SQL preparado para evitar injeção de código malicioso // SQL preparado para evitar injeção de código malicioso
// Campos: user_id (quem comprou), type (jogo ou gift card), item_id (ID do item), // Campos: user_id (quem comprou), type (jogo ou gift card), item_id (ID do item),
// title (nome do jogo/gift), platform (onde roda ou vale) // title (nome do jogo/gift), platform (onde roda ou vale)
const sql = `INSERT INTO users_library (user_id, type, item_id, title, platform) const sql = `INSERT INTO users_library (user_id, type, item_id, title, platform)
VALUES (?, ?, ?, ?, ?)`; VALUES (?, ?, ?, ?, ?)`;
// Executa a query com os dados sanitizados // Executa a query com os dados sanitizados
db.query(sql, [data.user_id, data.type, data.item_id, data.title, data.platform], callback); db.query(sql, [data.user_id, data.type, data.item_id, data.title, data.platform], callback);
}; };
// Função que busca TODOS os itens da biblioteca de um usuário específico. // Função que busca TODOS os itens da biblioteca de um usuário específico.
// É usada quando o usuário quer ver sua coleção completa. // É usada quando o usuário quer ver sua coleção completa.
exports.getUserLibrary = (user_id, callback) => { exports.getUserLibrary = (user_id, callback) => {
// Query simples mas eficiente - busca tudo do usuário // Query simples mas eficiente - busca tudo do usuário
db.query('SELECT * FROM users_library WHERE user_id = ?', [user_id], callback); db.query('SELECT * FROM users_library WHERE user_id = ?', [user_id], callback);
}; };
// Função importante para evitar duplicatas! // Função importante para evitar duplicatas!
// Antes de adicionar um item, verificamos se o usuário já não o tem. // Antes de adicionar um item, verificamos se o usuário já não o tem.
// Isso evita que alguém compre o mesmo jogo duas vezes por acidente. // Isso evita que alguém compre o mesmo jogo duas vezes por acidente.
exports.checkItem = (user_id, item_id, callback) => { exports.checkItem = (user_id, item_id, callback) => {
// Busca se existe algum registro com esse usuário e item // Busca se existe algum registro com esse usuário e item
db.query('SELECT * FROM users_library WHERE user_id = ? AND item_id = ?', [user_id, item_id], callback); db.query('SELECT * FROM users_library WHERE user_id = ? AND item_id = ?', [user_id, item_id], callback);
}; };

View File

@@ -1,26 +1,26 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const controller = require('../controllers/libraryController'); const controller = require('../controllers/libraryController');
// Este arquivo define as "portas de entrada" da nossa API! // Este arquivo define as "portas de entrada" da nossa API!
// Cada rota é como uma porta específica do prédio - cada uma leva a um lugar diferente. // Cada rota é como uma porta específica do prédio - cada uma leva a um lugar diferente.
// Seguimos convenções REST: POST para criar, GET para buscar. // Seguimos convenções REST: POST para criar, GET para buscar.
// Rota para adicionar um item manualmente à biblioteca // Rota para adicionar um item manualmente à biblioteca
// Método: POST /library/add // Método: POST /library/add
// Uso: Para correções ou imports especiais (não para compras normais) // Uso: Para correções ou imports especiais (não para compras normais)
router.post('/add', controller.addItem); router.post('/add', controller.addItem);
// Rota para buscar toda a biblioteca de um usuário // Rota para buscar toda a biblioteca de um usuário
// Método: GET /library/user/:user_id // Método: GET /library/user/:user_id
// Exemplo: GET /library/user/123 retorna todos os jogos e gift cards do usuário 123 // Exemplo: GET /library/user/123 retorna todos os jogos e gift cards do usuário 123
router.get('/user/:user_id', controller.getLibrary); router.get('/user/:user_id', controller.getLibrary);
// Rota CRUCIAL para integração com o serviço de pagamentos! // Rota CRUCIAL para integração com o serviço de pagamentos!
// Método: POST /library/integration/payment-approved // Método: POST /library/integration/payment-approved
// Esta rota é chamada AUTOMATICAMENTE quando um pagamento é aprovado. // Esta rota é chamada AUTOMATICAMENTE quando um pagamento é aprovado.
// É o elo entre "comprou" e "recebeu na biblioteca". // É o elo entre "comprou" e "recebeu na biblioteca".
router.post('/integration/payment-approved', controller.paymentApproved); router.post('/integration/payment-approved', controller.paymentApproved);
// Exportamos o router para que o app.js possa usar essas rotas // Exportamos o router para que o app.js possa usar essas rotas
module.exports = router; module.exports = router;