Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions semana21/aula64/template-testes-backend-feito/.rest
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
### CADASTRO

POST http://localhost:3003/users/signup
Content-Type: application/json

{
"name": "Alice",
"email": "alice@lbn.com",
"password": "123456",
"role":"ADMIN"
}

### LOGIN

POST http://localhost:3003/users/login
Content-Type: application/json

{
"email": "alice@lbn.com",
"password": "123456"
}
20 changes: 20 additions & 0 deletions semana21/aula64/template-testes-backend-feito/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/build/src/index.js",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
4 changes: 4 additions & 0 deletions semana22/amaro/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
package-lock.json
build
.env
34 changes: 34 additions & 0 deletions semana22/amaro/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "amaro",
"version": "1.0.0",
"description": "### Sobre o desafio",
"main": "index.js",
"scripts": {
"dev": "ts-node-dev ./src/index.ts",
"start": "tsc && node ./build/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/knex": "^0.16.1",
"@types/uuid": "^8.3.4",
"typescript": "^4.5.4"
},
"dependencies": {
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/jsonwebtoken": "^8.5.8",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^14.2.0",
"express": "^4.17.2",
"jsonwebtoken": "^8.5.1",
"knex": "^1.0.1",
"mysql": "^2.18.1",
"ts-node-dev": "^1.1.8",
"uuid": "^8.3.2"
}
}
34 changes: 34 additions & 0 deletions semana22/amaro/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
### Desafio back-end AMARO

### Sobre o desafio

- Criação de API para cadastro e consulta de produtos
- Você precisa criar uma API com os seguintes requisitos:

#### End-point para inserção de dados

- O cliente poderá enviá-los em arquivos json ou xml e a API deverá inserir no banco de dados.
- Escolha o banco de dados que achar melhor.

### End-point para consulta destes produtos

-Pode ser consultado por: id, nome ou tags. Caso a consulta seja por uma tag ou nome, deverá listar todos os produtos com aquela respectiva busca, poderá ser feito em um ou mais end-points.

### Requisitos Obrigatórios

- Ter uma cobertura de teste relativamente boa, a maior que você conseguir.
- Usar NodeJS
- Criar um cache para consulta.

### PLUS - Não necessário

- Colocar uma autenticação JWT.

### Orientações

- Procure fazer uma API sucinta.
- Os arquivos (json, xml) junto com o formato que o cliente irá enviar estão no repositório.
- Pense em escalabilidade, pode ser uma quantidade muito grande de dados.
- Coloque isso em um repositório GIT.
- Colocar as orientações de setup no README do seu repositório.
- Boa sorte!
64 changes: 64 additions & 0 deletions semana22/amaro/src/business/ProductBusiness/ProductBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
CreateProductDTO,
GetProductByNameDTO,
Product,
} from "../../entities/Product";
import {
AuthenticationData,
Authenticator,
} from "../../services/Authenticator";
import { IdGenerator } from "../../services/IdGenerator";
import { ProductDatabase } from "../../data/ProductDataBase/ProductDatabase";

export class ProductBusiness {
async registerProduct(input: CreateProductDTO): Promise<void> {
try {
const tokenManager = new Authenticator();

if (!input.name || !input.price || !input.image_url) {
throw new Error('"Name", "Price" and "image_url" must be provided');
}

if (!input.token) {
throw new Error("A jwt must be provided");
}

const tokenData: AuthenticationData = tokenManager.getTokenData(
input.token
);

const idGenerator = new IdGenerator();
const id: string = idGenerator.generateId();

const product: Product = {
id,
user_id: tokenData.id,
name: input.name,
price: input.price,
image_url: input.image_url,
};

await new ProductDatabase().registerProduct(product);
} catch (error: any) {
throw new Error(error.message);
}
}

async getProductByName(
input: GetProductByNameDTO
): Promise<Product | undefined> {
try {
const product: Product = await new ProductDatabase().getProductByName(
input.name
);

if (!product) {
throw new Error("Product not found");
}

return product;
} catch (error: any) {
throw new Error(error.message);
}
}
}
64 changes: 64 additions & 0 deletions semana22/amaro/src/business/UserBusiness/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { SignupInputDTO, LoginInputDTO, User } from "../../entities/User";
import { IdGenerator } from "../../services/IdGenerator";
import { HashManager } from "../../services/HashManager";
import { Authenticator } from "../../services/Authenticator";
import { UserDatabase } from "../../data/UserDataBase/UserDataBase";

export class UserBusiness {
async signup(input: SignupInputDTO): Promise<string | undefined> {
try {
if (!input.name || !input.email || !input.password) {
throw new Error('"name", "email" and "password" must be provided');
}

const idGenerator = new IdGenerator();
const id: string = idGenerator.generateId();

const hashManager = new HashManager();
const cypherPassword = await hashManager.hash(input.password);

const user: User = {
id,
name: input.name,
email: input.email,
password: cypherPassword,
};

const userDataBase = new UserDatabase();
await userDataBase.insertUser(user);

const tokenManager = new Authenticator();
const token: string = tokenManager.generate({ id });

return token;
} catch (error) {}
}

async login(input: LoginInputDTO): Promise<string | undefined> {
try {
if (!input.email || !input.password) {
throw new Error('"email" and "password" must be provided');
}

const userDataBase = new UserDatabase();
const user: User = await userDataBase.getUserByEmail(input.email);

const hashManager = new HashManager();
const passwordIsCorrect: boolean = await hashManager.compare(
input.password,
user.password
);

if (!user || !passwordIsCorrect) {
throw new Error("Invalid credentials");
}

const tokenManager = new Authenticator();
const token: string = await tokenManager.generate({ id: user.id });

return token;
} catch (error: any) {
throw new Error(error.message);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Request, Response } from "express";
import {
CreateProductDTO,
GetProductByNameDTO,
Product,
} from "../../entities/Product";
import { ProductBusiness } from "../../business/ProductBusiness/ProductBusiness";

export class ProductController {
async registerProduct(req: Request, res: Response): Promise<void> {
try {
const message = "Success!";

const token: string = req.headers.authorization as string;

const input: CreateProductDTO = {
name: req.body.name,
price: req.body.price,
image_url: req.body.image_url,
token,
};

await new ProductBusiness().registerProduct(input);

res.status(201).send({ message });
} catch (error: any) {
const message = error.SqlMessage || error.message;

res.send({ message });
}
}

async getProductByName(req: Request, res: Response): Promise<void> {
try {
const message = "Success!";

const input: GetProductByNameDTO = {
name: req.params.name,
};

const product: Product | undefined =
await new ProductBusiness().getProductByName(input);

res.status(200).send({ message, product });
} catch (error: any) {
let message = error.sqlMessage || error.message;
res.statusCode = 400;

res.send({ message });
}
}
}
46 changes: 46 additions & 0 deletions semana22/amaro/src/controller/UserController/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Request, Response } from "express";
import { SignupInputDTO, LoginInputDTO } from "../../entities/User";
import { UserBusiness } from "../../business/UserBusiness/UserBusiness";

export class UserController {
async signup(req: Request, res: Response): Promise<void> {
try {
const message = "Success!";

const input: SignupInputDTO = {
name: req.body.name,
email: req.body.email,
password: req.body.password,
};

const userBusiness = new UserBusiness();
const token = await userBusiness.signup(input);

res.status(201).send({ message, token });
} catch (error: any) {
const message = error.SqlMessage || error.message;

res.send({ message });
}
}

async loginUser(req: Request, res: Response) {
try {
const message = "Success!";

const input: LoginInputDTO = {
email: req.body.email,
password: req.body.password,
};

const token = await new UserBusiness().login(input);

res.status(200).send({ message, token });
} catch (error: any) {
let message = error.sqlMessage || error.message;
res.statusCode = 400;

res.send({ message });
}
}
}
11 changes: 11 additions & 0 deletions semana22/amaro/src/controller/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import express from "express";
import cors from "cors";

export const app = express();

app.use(express.json());
app.use(cors());

app.listen(3003, () => {
console.log("Server runin on port 3003");
});
9 changes: 9 additions & 0 deletions semana22/amaro/src/controller/routes/productRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Router } from "express";
import { ProductController } from "../ProductController/ProductController";

export const productRouter = Router();

const productController = new ProductController();

productRouter.post("/", productController.registerProduct);
productRouter.get("/:name", productController.getProductByName);
9 changes: 9 additions & 0 deletions semana22/amaro/src/controller/routes/userRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Router } from "express";
import { UserController } from "../UserController/UserController";

export const userRouter = Router();

const userController = new UserController();

userRouter.post("/signup", userController.signup);
userRouter.post("/login", userController.loginUser);
15 changes: 15 additions & 0 deletions semana22/amaro/src/data/BaseDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import knex from "knex";

export class BaseDatabase {
protected connection = knex({
client: "mysql",
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_SCHEMA,
port: 3306,
multipleStatements: true,
},
});
}
Loading