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
4 changes: 4 additions & 0 deletions semana23/case-fullstack-cubo/back/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
package-lock.json
build
.env
6 changes: 6 additions & 0 deletions semana23/case-fullstack-cubo/back/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
roots: ["<rootDir>/tests"],
transform: { "^.+\\.tsx?$": "ts-jest", },
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
}
35 changes: 35 additions & 0 deletions semana23/case-fullstack-cubo/back/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "back",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "tsc && node ./build/index.js",
"dev": "ts-node-dev ./src/index.ts",
"migrations": "tsnd ./src/data/Migration.ts",
"test": "clear && echo \"Running tests...\" && jest"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/jest": "^27.4.0",
"@types/node": "^17.0.13",
"jest": "^27.4.7",
"ts-jest": "^27.1.3",
"ts-node-dev": "^1.1.8",
"typescript": "^4.5.5"
},
"dependencies": {
"@types/knex": "^0.16.1",
"@types/uuid": "^8.3.4",
"cors": "^2.8.5",
"dotenv": "^14.3.2",
"express": "^4.17.2",
"knex": "^1.0.1",
"mysql": "^2.18.1",
"uuid": "^8.3.2"
}
}
40 changes: 40 additions & 0 deletions semana23/case-fullstack-cubo/back/src/business/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { UserDatabase } from "../data/UserDatabase";
import { InvalidInputError } from "../error/InvalidInputError";
import { UserInputDTO, UserInsertDTO } from "../model/User";
import { IdGenerator } from "../services/IdGenerator";

export class UserBusiness {

constructor (
private idGenerator: IdGenerator,
private userDatabase: UserDatabase
) {}

async createUser(input: UserInputDTO) {

if(!input.name || !input.lastName || !input.participation) {
throw new InvalidInputError("Invalid input to create user")
}


const id = this.idGenerator.generate()

const newUser: UserInsertDTO = {
id: id,
name: input.name,
lastName: input.lastName,
participation: input.participation
}

await this.userDatabase.createUser(newUser)

}

async getAllUsers() {

const allUsers = await this.userDatabase.getAllUsers()

return allUsers

}
}
51 changes: 51 additions & 0 deletions semana23/case-fullstack-cubo/back/src/controller/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Request, Response } from "express";
import { UserBusiness } from "../business/UserBusiness";
import { UserDatabase } from "../data/UserDatabase";
import { UserInputDTO } from "../model/User";
import { IdGenerator } from "../services/IdGenerator";

export class UserController {

async createUser(req: Request, res: Response) {

try {

const input: UserInputDTO = {
name: req.body.name,
lastName: req.body.lastName,
participation: req.body.participation
}

const userBusiness = new UserBusiness(new IdGenerator, new UserDatabase)
await userBusiness.createUser(input)


res.status(201).send({ message: "User created successfully!" })

} catch (error) {
if (error instanceof Error) {
res.status(400).send({ message: error.message })
} else {
res.status(400).send({ message: "Unexpected error!"})
}
}
}

async getAllUsers(req: Request, res: Response) {

try {

const userBusiness = new UserBusiness(new IdGenerator, new UserDatabase)
const allUsers = await userBusiness.getAllUsers()

res.status(200).send(allUsers)

} catch (error) {
if (error instanceof Error) {
res.status(400).send({ message: error.message })
} else {
res.status(400).send({ message: "Unexpected error!"})
}
}
}
}
16 changes: 16 additions & 0 deletions semana23/case-fullstack-cubo/back/src/controller/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import express, { Express } from "express";
import cors from "cors";
import { AddressInfo } from "net";

export const app: Express = express();
app.use(express.json());
app.use(cors());

const server = app.listen(process.env.PORT || 3003, () => {
if (server) {
const address = server.address() as AddressInfo;
console.log(`Server is running in http://localhost:${address.port}`);
} else {
console.error(`Failure upon starting server.`);
}
});
37 changes: 37 additions & 0 deletions semana23/case-fullstack-cubo/back/src/data/BaseDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { config } from "dotenv";
import knex, { Knex } from "knex";

config()

export abstract class BaseDatabase {

private static connection: Knex | null = null;

protected tableName = {
users: "CUBO_USERS"
}

protected getConnection(): Knex {
if (!BaseDatabase.connection) {
BaseDatabase.connection = knex({
client: "mysql",
connection: {
host: process.env.DB_HOST,
port: 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_SCHEMA,
},
});
}

return BaseDatabase.connection;
}

public static async destroyConnection(): Promise<void> {
if (BaseDatabase.connection) {
await BaseDatabase.connection.destroy();
BaseDatabase.connection = null;
}
}
}
25 changes: 25 additions & 0 deletions semana23/case-fullstack-cubo/back/src/data/Migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { BaseDatabase } from "./BaseDatabase";

class Migrations extends BaseDatabase {

async createTable() {

await this.getConnection()
.raw(`
create table CUBO_USERS_MIGRATION (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
lastName VARCHAR(255) NOT NULL,
participation FLOAT NOT NULL
);
`)

console.log("Tabela CUBO_USERS_MIGRATION criada com sucesso!")
BaseDatabase.destroyConnection()
}
}


const createTable = new Migrations()

createTable.createTable()
50 changes: 50 additions & 0 deletions semana23/case-fullstack-cubo/back/src/data/UserDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { User, UserInsertDTO } from "../model/User";
import { BaseDatabase } from "./BaseDatabase";

export class UserDatabase extends BaseDatabase {

async createUser(newUser: UserInsertDTO): Promise<void> {
try {

await this.getConnection()
.insert({
id: newUser.id,
name: newUser.name,
lastName: newUser.lastName,
participation: newUser.participation
})
.into(this.tableName.users)

} catch (error) {
if (error instanceof Error) {
throw new Error(error.message)
} else {
throw new Error("Erro no banco de dados!")
}
}

}

async getAllUsers(): Promise<User[]> {
try {

const users = await this.getConnection()
.select("*")
.from(this.tableName.users)

const allUsers = users.map((user) => {
return User.toUserModel(user)
})

return allUsers

} catch (error) {
if (error instanceof Error) {
throw new Error(error.message)
} else {
throw new Error("Erro no banco de dados!")
}
}

}
}
9 changes: 9 additions & 0 deletions semana23/case-fullstack-cubo/back/src/error/BaseError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export abstract class BaseError extends Error {

constructor (
message: string,
public code: number
) {
super(message)
}
}
11 changes: 11 additions & 0 deletions semana23/case-fullstack-cubo/back/src/error/InvalidInputError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BaseError } from "./BaseError";

export class InvalidInputError extends BaseError {

constructor (
message: string
) {
super(message, 400)
}

}
4 changes: 4 additions & 0 deletions semana23/case-fullstack-cubo/back/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { app } from "./controller/app";
import { userRouter } from "./routes/userRouter";

app.use("/user", userRouter)
28 changes: 28 additions & 0 deletions semana23/case-fullstack-cubo/back/src/model/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export class User {

constructor (
private id: string,
private name: string,
private lastName: string,
private participation: number
) {}

static toUserModel(user: any): User {
return new User(
user.id,
user.name,
user.lastName,
user.participation
)
}
}

export interface UserInputDTO {
name: string;
lastName: string;
participation: number;
}

export interface UserInsertDTO extends UserInputDTO {
id: string
}
8 changes: 8 additions & 0 deletions semana23/case-fullstack-cubo/back/src/routes/userRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from "express"
import { UserController } from "../controller/UserController"

export const userRouter = express.Router()
const userController = new UserController()

userRouter.post("/create", userController.createUser)
userRouter.get("/all", userController.getAllUsers)
8 changes: 8 additions & 0 deletions semana23/case-fullstack-cubo/back/src/services/IdGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { v4 } from "uuid";

export class IdGenerator {

generate(): string {
return v4()
}
}
Loading