Skip to content

Commit 85e894c

Browse files
committed
NLW #2 - Creating backend with express.js
1 parent 5208daa commit 85e894c

17 files changed

Lines changed: 2992 additions & 0 deletions

nlw-02/aulas/server/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

nlw-02/aulas/server/knexfile.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import path from "path";
2+
3+
module.exports = {
4+
client: "sqlite3",
5+
connection: {
6+
filename: path.resolve(__dirname, "src", "database", "database.sqlite"),
7+
},
8+
migrations: {
9+
directory: path.resolve(__dirname, "src", "database", "migrations"),
10+
},
11+
useNullAsDefault: true,
12+
};

nlw-02/aulas/server/package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "server",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"license": "MIT",
6+
"scripts": {
7+
"start": "tsnd --transpile-only --ignore-watch node_modules --respawn src/server.ts",
8+
"knex:migrate": "knex --knexfile knexfile.ts migrate:latest"
9+
},
10+
"devDependencies": {
11+
"@types/cors": "^2.8.7",
12+
"ts-node-dev": "^1.0.0-pre.56",
13+
"typescript": "^3.9.7"
14+
},
15+
"dependencies": {
16+
"@types/express": "^4.17.7",
17+
"cors": "^2.8.5",
18+
"express": "^4.17.1",
19+
"knex": "^0.21.2",
20+
"sqlite3": "^5.0.0"
21+
}
22+
}

nlw-02/aulas/server/readme.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Functionalities
2+
3+
## Conclusions
4+
5+
- Route to list total of conections done;
6+
- Route to create a new conection;
7+
8+
## Classes
9+
10+
- Route to create a class;
11+
- Route to list classes;
12+
- Filter by subject, week day, and time;
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Request, Response } from "express";
2+
import db from "../database/connection";
3+
import convertHoursToMinutes from "../utils/convertHourToMinutes";
4+
5+
interface ScheduleItem {
6+
week_day: number;
7+
from: string;
8+
to: string;
9+
}
10+
11+
export default class ClassesController {
12+
async index(request: Request, response: Response) {
13+
const filters = request.query;
14+
15+
const subject = filters.subject as string;
16+
const week_day = filters.week_day as string;
17+
const time = filters.time as string;
18+
19+
if (!filters.week_day || !filters.subject || !filters.time) {
20+
return response.status(400).json({
21+
error: "Missing filters to search classes",
22+
});
23+
}
24+
25+
const timeInMinutes = convertHoursToMinutes(time);
26+
27+
const classes = await db("classes")
28+
.whereExists(function () {
29+
this.select("class_schedule.*")
30+
.from("class_schedule")
31+
.whereRaw("`class_schedule`.`class_id` = `classes`.`id`")
32+
.whereRaw("`class_schedule`.`week_day` = ??", [Number(week_day)])
33+
.whereRaw("`class_schedule`.`from` <= ??", [timeInMinutes])
34+
.whereRaw("`class_schedule`.`to` > ??", [timeInMinutes]);
35+
})
36+
.where("classes.subject", "=", subject)
37+
.join("users", "classes.user_id", "=", "users.id")
38+
.select(["classes.*", "users.*"]);
39+
response.json(classes);
40+
}
41+
42+
async create(request: Request, response: Response) {
43+
const {
44+
name,
45+
avatar,
46+
whatsapp,
47+
bio,
48+
subject,
49+
cost,
50+
schedule,
51+
} = request.body;
52+
53+
const trx = await db.transaction();
54+
55+
try {
56+
const insertedUsersIds = await trx("users").insert({
57+
name,
58+
avatar,
59+
whatsapp,
60+
bio,
61+
});
62+
63+
const user_id = insertedUsersIds[0];
64+
65+
const insertedClasessIds = await trx("classes").insert({
66+
subject,
67+
cost,
68+
user_id,
69+
});
70+
71+
const class_id = insertedClasessIds[0];
72+
73+
const classSchedule = schedule.map((scheduleItem: ScheduleItem) => {
74+
return {
75+
class_id,
76+
week_day: scheduleItem.week_day,
77+
from: convertHoursToMinutes(scheduleItem.from),
78+
to: convertHoursToMinutes(scheduleItem.to),
79+
};
80+
});
81+
82+
await trx("class_schedule").insert(classSchedule);
83+
84+
await trx.commit();
85+
86+
return response.status(201).send();
87+
} catch (err) {
88+
await trx.rollback();
89+
return response.status(400).json({
90+
error: "Unexpected error while creating new class",
91+
});
92+
}
93+
}
94+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Request, Response } from "express";
2+
import db from "../database/connection";
3+
4+
export default class ConnectionsController {
5+
async index(request: Request, response: Response) {
6+
const totalConnections = await db("connections").count("* as total");
7+
8+
const { total } = totalConnections[0];
9+
10+
return response.json({ total });
11+
}
12+
async create(request: Request, response: Response) {
13+
const { user_id } = request.body;
14+
15+
await db("connections").insert({
16+
user_id,
17+
});
18+
19+
return response.status(201).send();
20+
}
21+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import knex from "knex";
2+
import path from "path";
3+
4+
const db = knex({
5+
client: "sqlite3",
6+
connection: {
7+
filename: path.resolve(__dirname, "database.sqlite"),
8+
},
9+
useNullAsDefault: true,
10+
});
11+
12+
export default db;
32 KB
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Knext from "knex";
2+
3+
export async function up(knex: Knext) {
4+
return knex.schema.createTable("users", (table) => {
5+
table.increments("id").primary();
6+
table.string("name").notNullable();
7+
table.string("avatar").notNullable();
8+
table.string("whatsapp").notNullable();
9+
table.string("bio").notNullable();
10+
});
11+
}
12+
export async function down(knex: Knext) {
13+
return knex.schema.dropTableIfExists("users");
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Knext from "knex";
2+
3+
export async function up(knex: Knext) {
4+
return knex.schema.createTable("classes", (table) => {
5+
table.increments("id").primary();
6+
table.string("subject").notNullable();
7+
table.string("cost").notNullable();
8+
9+
table
10+
.integer("user_id")
11+
.notNullable()
12+
.references("id")
13+
.inTable("users")
14+
.onUpdate("CASCADE")
15+
.onDelete("CASCADE");
16+
});
17+
}
18+
export async function down(knex: Knext) {
19+
return knex.schema.dropTableIfExists("classes");
20+
}

0 commit comments

Comments
 (0)