diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8ece3ba
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+package-lock.json
+build
+.env
\ No newline at end of file
diff --git a/README.md b/README.md
index 49352af..f6e00f7 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,64 @@
-# labook-template
-Repositório do projeto Labook
+##
📇 Labook
+
+## :memo: Descrição
+Projeto desenvolvido como didática de back-end para as turmas JBL LABENU com conteúdos que englobam o universo da criação de APIs com a temática de um rede social.
+
+## Link Documentação Postman
+[Doc_Postman](https://documenter.getpostman.com/view/22363157/2s935mtRKC)
+
+## Link Deploy Render
+https://labook4.onrender.com
+
+## 👩🏾Pessoa Desenvolvedora do Projeto
+
+ [
Byron Smith](https://github.com/byron-smith-nobrega)
+
+## :books: Funcionalidades
+* Criar Usuário: Método voltado para a criação de usuários.
+* Criar Post: Método voltado para a criação de postagens.
+* Buscar Post: Método voltado para a consulta de uma postagem.
+* Criar Amizade: Método voltado para a criação de amizade entre usuários.
+* Deletar Amizade: Método voltado para a exclusão de uma amizade.
+* Criar Curtida: Método voltado para a criação de vínculo entre usuário e postagem.
+* Deletar Curtida: Método voltado para a exclusão de vínculo entre usuário e postagem.
+* Criar Comentário : Método voltado para a criação de comentário nas postagens.
+* Buscar Feeds Amigos : Método voltado para a consulta de postagens dos amigos.
+* Buscar Feeds: Método voltado para a consulta de postagens.
+
+## :wrench: Tecnologias utilizadas
+* VS Code
+* nodeJS
+* expressJS
+* axios
+* cors
+* dotenv
+* uuid
+* MySQL
+
+
+## :rocket: Rodando o projeto
+Para rodar o repositório é necessário clonar o mesmo, dar o seguinte comando para instalar as dependências:
+```
+npm install
+```
+Após instaladas as dependências, configure o arquivo .env:
+```
+DB_HOST =
+DB_USER = ""
+DB_PASS = ""
+DB_NAME = ""
+```
+Após configuração do .env, dê o comando seguinte para rodar a aplicação:
+```
+npm run start
+```
+Após o start, dê o comando seguinte para criar as tabelas no banco de dados:
+```
+npm run migrations
+```
+
+Use o Postman ou o Insomnia para realizar as requisições desejadas.
+
+## :dart: Status do projeto
+O projeto está em andamento.
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..20a6081
--- /dev/null
+++ b/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "revisao-full-stack",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "start": "tsc && node ./build/index.js",
+ "dev": "ts-node-dev ./src/index.ts",
+ "migrations": "tsc && node ./build/data/migrations.js"
+ },
+ "author": "Byron",
+ "license": "ISC",
+ "dependencies": {
+ "@types/node": "^18.11.18",
+ "dotenv": "^16.0.3",
+ "express": "^4.18.2",
+ "knex": "^2.4.0",
+ "mysql": "^2.18.1",
+ "typescript": "^4.9.4",
+ "uuid": "^9.0.0"
+ },
+ "devDependencies": {
+ "@types/cors": "^2.8.13",
+ "@types/express": "^4.17.15",
+ "@types/knex": "^0.16.1",
+ "@types/uuid": "^9.0.0",
+ "cors": "^2.8.5",
+ "ts-node-dev": "^2.0.0"
+ }
+}
diff --git a/request.rest b/request.rest
new file mode 100644
index 0000000..c86d229
--- /dev/null
+++ b/request.rest
@@ -0,0 +1,89 @@
+
+### Create a new User
+POST http://localhost:3003/user/create
+Content-Type: application/json
+
+{
+ "name":"Bianca Smith",
+ "email":"biancasmith@gmail.com",
+ "password": "1234567"
+}
+
+### Return post
+GET http://localhost:3003/post/getpost
+Content-Type: application/json
+
+{
+ "id":"1675379034720"
+}
+
+### Create a new Post
+POST http://localhost:3003/post/create
+Content-Type: application/json
+Authorization: 1675001631299
+
+{
+ "photo" : "Foto",
+ "description": "foto da viagem",
+ "type": "normal",
+ "createdAt": "08/02/2023"
+}
+
+### Create a new Friendship
+POST http://localhost:3003/friendship/create
+Content-Type: application/json
+Authorization: 1675001631299
+
+{
+ "friendId":"1675019596015"
+}
+
+### Delete Friendship
+DELETE http://localhost:3003/friendship
+Content-Type: application/json
+Authorization: 1675001631299
+
+{
+ "friendId":"1675019596015"
+}
+
+### Return Feeds freands
+GET http://localhost:3003/post/getfeedsfreands
+Content-Type: application/json
+Authorization: fde08a25-cb5c-4948-bb59-693eb726721d
+
+### return feed by type
+GET http://localhost:3003/post/getfeeds
+Content-Type: application/json
+
+{
+ "type":"normal"
+}
+
+### Like Post
+POST http://localhost:3003/like/create
+Content-Type: application/json
+Authorization: 1675001631299
+
+{
+ "postId":"1675379034720"
+}
+
+### Delete Like Post
+DELETE http://localhost:3003/like
+Content-Type: application/json
+Authorization: 1675001631299
+
+{
+ "postId":"1675379034720"
+}
+
+### Comment Post
+POST http://localhost:3003/comments
+Content-Type: application/json
+Authorization: 1675001631299
+
+{
+ "comment":"Linda foto",
+ "postId":"1675379034720"
+}
\ No newline at end of file
diff --git a/src/business/CommentsBusiness.ts b/src/business/CommentsBusiness.ts
new file mode 100644
index 0000000..1eb1501
--- /dev/null
+++ b/src/business/CommentsBusiness.ts
@@ -0,0 +1,53 @@
+import { CommentDatabase } from "../data/CommentsDatabase";
+import { PostDatabase } from "../data/PostDatabase";
+import { UserDatabase } from "../data/UserDatabase";
+import { InputCommentControllerDTO } from "../model/Comments";
+import { IdGenerator } from "../service/IdGenerator";
+
+const commentDatabase = new CommentDatabase();
+const userDatabase = new UserDatabase();
+const postDatabase = new PostDatabase();
+const idGenerator = new IdGenerator();
+
+export class CommentsBusiness {
+ createComment = async (input: InputCommentControllerDTO): Promise => {
+ try {
+ const { comment, postId, authorId } = input;
+
+
+ if (!comment || !postId || !authorId) {
+ throw new Error(
+ 'Fill in the fields "comment", "postId" and "authorId"'
+ );
+ }
+
+ const userBase = await userDatabase.findUser();
+ const existUser = userBase.findIndex((user)=>user.id === authorId);
+
+ if(existUser === -1) {
+ throw new Error("User not exist.");
+ }
+ const postBase = await postDatabase.findPost(postId);
+ const existPost = postBase.findIndex((post)=>post.id === postId);
+
+ if(existPost === -1) {
+ throw new Error("Post not exist.");
+ }
+
+ const id: string = idGenerator.generateId();
+
+
+ await commentDatabase.insertcomment({
+ id,
+ comment,
+ postId,
+ authorId,
+ });
+ } catch (error:any) {
+ throw new Error(error.message)
+ }
+ };
+
+ findComment = () => {};
+ deleteComment = () => {};
+}
\ No newline at end of file
diff --git a/src/business/FriendshipBusiness.ts b/src/business/FriendshipBusiness.ts
new file mode 100644
index 0000000..010a6b5
--- /dev/null
+++ b/src/business/FriendshipBusiness.ts
@@ -0,0 +1,104 @@
+import { FriendshipDatabase } from "../data/FriendshipDatabase";
+import { UserDatabase } from "../data/UserDatabase";
+import { FriendInputDTO } from "../model/friends";
+import { DeleteFriendshipInputDTO, FriendshipInputDTO} from "../model/Friendship";
+import { IdGenerator } from "../service/IdGenerator";
+
+const friendshipDatabase = new FriendshipDatabase();
+const userDatabase = new UserDatabase();
+const idGenerator = new IdGenerator();
+
+export class FriendshipBusiness {
+ createFriendship = async (input: FriendInputDTO): Promise => {
+ try {
+ const { friendId, authorId } = input;
+
+ if (!friendId || !authorId) {
+ throw new Error("Fill in the friendId, authorId fields");
+ }
+
+ const queryUser = await userDatabase.findUser();
+ const existFriend = queryUser.findIndex((user) => {
+ return user.id === friendId;
+ });
+
+ if (existFriend === -1) {
+ throw new Error("Friend id does not exist.");
+ }
+
+ const existauthorId = queryUser.findIndex((user) => {
+ return user.id === authorId;
+ });
+
+ if (existauthorId === -1) {
+ throw new Error("User id does not exist.");
+ }
+
+ const id: string = idGenerator.generateId();
+
+ const queryResult: FriendshipInputDTO[] =
+ await friendshipDatabase.findFriendship(authorId);
+
+ const existFriendship = queryResult.findIndex((user) => {
+ return user.friend_id === friendId;
+ });
+
+ if (existFriendship != -1) {
+ throw new Error("friendship already exists!");
+ }
+ const idFriend: string = idGenerator.generateId();
+
+ await friendshipDatabase.insertPost({
+ id,
+ idRows: idFriend,
+ friendId,
+ authorId,
+ });
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findFriendship = () => {};
+
+ deleteFriendship = async (input: DeleteFriendshipInputDTO): Promise => {
+ try {
+ const { friendId, authorId } = input;
+
+ if (!friendId || !authorId) {
+ throw new Error("Fill in the friendId, authorId fields");
+ }
+
+ const queryUser = await userDatabase.findUser();
+ const existFriend = queryUser.findIndex((user) => {
+ return user.id === friendId;
+ });
+
+ if (existFriend === -1) {
+ throw new Error("Friend id does not exist.");
+ }
+
+ const existauthorId = queryUser.findIndex((user) => {
+ return user.id === authorId;
+ });
+
+ if (existauthorId === -1) {
+ throw new Error("User id does not exist.");
+ }
+
+ const queryResult: FriendshipInputDTO[] = await friendshipDatabase.findFriendship(authorId);
+
+ const existFriendship = queryResult.findIndex((user) => {
+ return user.friend_id === friendId;
+ });
+
+ if (existFriendship === -1) {
+ throw new Error("friendship does not exist!");
+ }
+
+ await friendshipDatabase.deletePost(input);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+}
diff --git a/src/business/LikeBusiness.ts b/src/business/LikeBusiness.ts
new file mode 100644
index 0000000..3e047c7
--- /dev/null
+++ b/src/business/LikeBusiness.ts
@@ -0,0 +1,108 @@
+import { LikeDatabase } from "../data/LikeDatabase";
+import { PostDatabase } from "../data/PostDatabase";
+import { UserDatabase } from "../data/UserDatabase";
+import { LikeInputControllerDTO, LikeInputDTO } from "../model/likes";
+import { IdGenerator } from "../service/IdGenerator";
+
+const likeDatabase = new LikeDatabase();
+const userDatabase = new UserDatabase();
+const postDatabase = new PostDatabase();
+const idGenerator = new IdGenerator();
+
+export class LikeBusiness {
+ createLike = async (input: LikeInputControllerDTO): Promise => {
+ try {
+ const { postId, authorId } = input;
+
+ if (!postId || !authorId) {
+ throw new Error("Fill in the postId, authorId.");
+ }
+
+ const queryUser = await userDatabase.findUser();
+ const queryPost = await postDatabase.findPost(postId);
+ const existPost = queryPost.findIndex((post) => {
+ return post.id === postId;
+ });
+
+ if (existPost === -1) {
+ throw new Error("Post id does not exist.");
+ }
+
+ const existauthorId = queryUser.findIndex((user) => {
+ return user.id === authorId;
+ });
+
+ if (existauthorId === -1) {
+ throw new Error("User id does not exist.");
+ }
+
+ const queryResult: LikeInputDTO[] = await likeDatabase.findLike(input);
+
+ const existLike = queryResult.findIndex((like) => {
+ return like.post_id === postId;
+ });
+
+ if (existLike !== -1) {
+ throw new Error("You already liked this post!");
+ }
+
+
+ const id: string = idGenerator.generateId();
+
+ await likeDatabase.insertLike({
+ id,
+ postId,
+ authorId,
+ });
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findLike = () => {};
+
+ deleteLike = async (input: LikeInputControllerDTO): Promise => {
+ try {
+ const { postId, authorId } = input;
+
+ if (!postId || !authorId) {
+ throw new Error("Fill in the postId, authorId");
+ }
+
+ const queryUser = await userDatabase.findUser();
+ const queryPost = await postDatabase.findPost(postId);
+
+ const existPost = queryPost.findIndex((post) => {
+ return post.id === postId;
+ });
+
+ if (existPost === -1) {
+ throw new Error("Post id does not exist.");
+ }
+
+ const existauthorId = queryUser.findIndex((user) => {
+ return user.id === authorId;
+ });
+
+ if (existauthorId === -1) {
+ throw new Error("User id does not exist.");
+ }
+
+ const queryResult: LikeInputDTO[] = await likeDatabase.findLike(input);
+
+ const existLike = queryResult.findIndex((like) => {
+ return like.post_id === postId;
+ });
+
+ if (existLike === -1) {
+ throw new Error("You didn't like this post!");
+ }
+
+ const idLike:string = queryResult[0].id
+
+ await likeDatabase.deleteLike(idLike);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+}
diff --git a/src/business/PostBusiness.ts b/src/business/PostBusiness.ts
new file mode 100644
index 0000000..7229e29
--- /dev/null
+++ b/src/business/PostBusiness.ts
@@ -0,0 +1,164 @@
+import { FriendshipDatabase } from "../data/FriendshipDatabase";
+import { PostDatabase } from "../data/PostDatabase";
+import { UserDatabase } from "../data/UserDatabase";
+import { FriendshipInputDTO } from "../model/Friendship";
+import { FeedPostDBDTO, FeedPostDTO, InpultPostDTO, PostIdDTO, PostTypeDTO, TPost } from "../model/Posts";
+import { dateFormat, dateFormatBr } from "../service/formatDate";
+import { IdGenerator } from "../service/IdGenerator";
+
+const postDatabase = new PostDatabase();
+const userDatabase = new UserDatabase();
+const friendshipDatabase = new FriendshipDatabase();
+const idGenerator = new IdGenerator();
+
+export class PostBusiness {
+ createPost = async (input: InpultPostDTO): Promise => {
+ try {
+ const { photo, description, type, createdAt, authorId } = input;
+
+ if (!photo || !description || !type || !createdAt || !authorId) {
+ throw new Error(
+ 'Fill in the fields photo, description, type, authorId'
+ );
+ }
+
+
+ if(type.toUpperCase() !== "normal".toUpperCase() && type.toUpperCase() !== "event".toUpperCase()){
+ throw new Error(
+ 'Fill in the fields type: normal or event'
+ );
+ }
+
+ const queryUser = await userDatabase.findUser();
+ const existUser = queryUser.findIndex((user)=>{
+ return user.id === authorId
+ })
+
+ if(existUser === -1){
+ throw new Error("User id does not exist.")
+ }
+
+ const formatDate:any= dateFormat(createdAt.toString())
+
+ const id: string = idGenerator.generateId();
+
+ await postDatabase.insertPost({
+ id,
+ photo,
+ description,
+ type,
+ createdAt:formatDate,
+ authorId
+ })
+
+ } catch (error:any) {
+ throw new Error(error.message)
+ }
+ };
+
+ findPost = async(input:PostIdDTO):Promise=> {
+ try {
+
+ const { id } = input;
+
+ if(!id){
+ throw new Error('Pass the id params');
+ }
+
+ const result:TPost[] = await postDatabase.findPost(id)
+ if (!result[0]) {
+ throw new Error("Post not found");
+ }
+ return result;
+
+ } catch (error:any) {
+ throw new Error(error.message)
+ }
+ };
+
+ feedPost = async(input:PostIdDTO):Promise => {
+ try {
+ const {id} = input;
+
+ const queryUser = await userDatabase.findUser();
+ const existUser = queryUser.findIndex((user)=>{
+ return user.id === id
+ })
+
+ if(existUser === -1){
+ throw new Error("User id does not exist.")
+ }
+
+ const queryFriends: FriendshipInputDTO[] = await friendshipDatabase.findFriendship(id);
+ const existFriendship = queryFriends.findIndex((user) => {
+ return user.author_id === id;
+ });
+
+ if (existFriendship === -1) {
+ throw new Error("friendship already exists!");
+ }
+
+ const friends:string[] = []
+
+ for (let i = 0; i < queryFriends.length; i++) {
+ friends.push(queryFriends[i].friend_id);
+ }
+ const posts: FeedPostDTO[] = [];
+ const result:FeedPostDBDTO[] = await postDatabase.feedPost(friends)
+ result.map((item:any)=>{
+ item.created_at = dateFormatBr(item.created_at.toString())
+ return result
+ })
+ for (let i = 0; i < result.length; i++) {
+ posts.push({
+ id: result[i].id,
+ photo: result[i].photo,
+ description: result[i].description,
+ type: result[i].type,
+ createdAt: result[i].created_at,
+ authorId: result[i].author_id}
+ )
+
+ }
+
+ return posts
+ } catch (error:any) {
+ throw new Error(error.message)
+ }
+ };
+ feedPostAll = async(input:PostTypeDTO) => {
+ try {
+
+ const{type} = input;
+
+ if(type.toUpperCase() !== "normal".toUpperCase() && type.toUpperCase() !== "event".toUpperCase()){
+ throw new Error(
+ 'Fill in the field type: normal or event'
+ );
+ }
+ const posts: FeedPostDTO[] = [];
+ const result:FeedPostDBDTO[] = await postDatabase.feedPostAll(input)
+ result.map((item:any)=>{
+ item.created_at = dateFormatBr(item.created_at.toString())
+ return result
+ })
+
+ for (let i = 0; i < result.length; i++) {
+ posts.push({
+ id: result[i].id,
+ photo: result[i].photo,
+ description: result[i].description,
+ type: result[i].type,
+ createdAt: result[i].created_at,
+ authorId: result[i].author_id}
+ )
+
+ }
+
+ return posts
+ } catch (error:any) {
+ throw new Error(error.message)
+ }
+ };
+ deletePost = () => {};
+}
\ No newline at end of file
diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts
new file mode 100644
index 0000000..f37b5a3
--- /dev/null
+++ b/src/business/UserBusiness.ts
@@ -0,0 +1,45 @@
+import { UserDatabase } from "../data/UserDatabase";
+import { InputControllerDTO } from "../model/User";
+import { IdGenerator } from "../service/IdGenerator";
+const idGenerator = new IdGenerator();
+
+export class UserBusiness {
+ createUser = async (input: InputControllerDTO): Promise => {
+ try {
+ const { name, email, password } = input;
+
+ const userDatabase = new UserDatabase();
+
+ if (!name || !email || !password) {
+ throw new Error(
+ 'Fill in the fields "name", "email" e "password"'
+ );
+ }
+
+ if (password.length < 6) {
+ throw new Error("Password too short minimum 6 characters");
+ }
+
+ const userBase = await userDatabase.findUser();
+ const existUser = userBase.findIndex((user)=>user.email === email)
+
+ if(existUser != -1) {
+ throw new Error("User already registered");
+ }
+ const id: string = idGenerator.generateId();
+
+
+ await userDatabase.insertUser({
+ id,
+ name,
+ email,
+ password,
+ });
+ } catch (error:any) {
+ throw new Error(error.message)
+ }
+ };
+
+ findUser = () => {};
+ deleteUser = () => {};
+}
\ No newline at end of file
diff --git a/src/controller/CommentsController.ts b/src/controller/CommentsController.ts
new file mode 100644
index 0000000..f3e8358
--- /dev/null
+++ b/src/controller/CommentsController.ts
@@ -0,0 +1,25 @@
+import { Request, Response } from "express";
+import { CommentsBusiness} from "../business/CommentsBusiness";
+import { InputCommentControllerDTO } from "../model/Comments";
+
+export class CommentController {
+ createComment = async (req: Request, res: Response): Promise => {
+ try {
+ const input: InputCommentControllerDTO = {
+ comment: req.body.comment,
+ postId: req.body.postId,
+ authorId: req.headers.authorization as string
+ };
+
+ const commentBusiness = new CommentsBusiness()
+ await commentBusiness.createComment(input)
+
+ res.status(201).send({ message: "Comment created!" });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ findComment = () => {};
+ deleteComment = () => {};
+}
\ No newline at end of file
diff --git a/src/controller/FriendshipController.ts b/src/controller/FriendshipController.ts
new file mode 100644
index 0000000..1b45a8a
--- /dev/null
+++ b/src/controller/FriendshipController.ts
@@ -0,0 +1,37 @@
+import { Request, Response } from "express";
+import { FriendshipBusiness } from "../business/FriendshipBusiness";
+import { FriendInputDTO } from "../model/friends";
+import { DeleteFriendshipInputDTO } from "../model/Friendship";
+const friendshipBusiness = new FriendshipBusiness();
+export class FriendshipController {
+ createFriendship = async (req: Request, res: Response): Promise => {
+ try {
+ const input: FriendInputDTO = {
+ friendId: req.body.friendId,
+ authorId: req.headers.authorization as string
+ };
+
+ await friendshipBusiness.createFriendship(input)
+
+ res.status(201).send({ message: "Friendship created!" });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ findFriendship = () => {};
+
+ deleteFriendship = async(req:Request, res:Response):Promise => {
+ try {
+ const input: DeleteFriendshipInputDTO = {
+ friendId: req.body.friendId,
+ authorId: req.headers.authorization as string
+ };
+
+ await friendshipBusiness.deleteFriendship(input)
+ res.status(201).send({ message: "deleted from friendship!" });
+ } catch (error:any) {
+ res.status(400).send(error.message);
+ }
+ };
+}
diff --git a/src/controller/LikeController.ts b/src/controller/LikeController.ts
new file mode 100644
index 0000000..88eb9b4
--- /dev/null
+++ b/src/controller/LikeController.ts
@@ -0,0 +1,37 @@
+import { Request, Response } from "express";
+import { LikeBusiness } from "../business/LikeBusiness";
+import { LikeInputControllerDTO } from "../model/likes";
+
+const likeBusiness = new LikeBusiness();
+export class LikeController {
+ createLike = async (req: Request, res: Response): Promise => {
+ try {
+ const input: LikeInputControllerDTO = {
+ postId: req.body.postId,
+ authorId: req.headers.authorization as string
+ };
+
+ await likeBusiness.createLike(input)
+
+ res.status(201).send({ message: "Like success!" });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ findLike = () => {};
+
+ deleteLike = async(req:Request, res:Response):Promise => {
+ try {
+ const input: LikeInputControllerDTO = {
+ postId: req.body.postId,
+ authorId: req.headers.authorization as string
+ };
+
+ await likeBusiness.deleteLike(input)
+ res.status(201).send({ message: "deleted from Like!" });
+ } catch (error:any) {
+ res.status(400).send(error.message);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/controller/PostController.ts b/src/controller/PostController.ts
new file mode 100644
index 0000000..ee059ac
--- /dev/null
+++ b/src/controller/PostController.ts
@@ -0,0 +1,69 @@
+import { Request, Response } from "express";
+import { PostBusiness } from "../business/PostBusiness";
+import { InpultPostDTO, PostIdDTO, PostTypeDTO } from "../model/Posts";
+
+const postBusiness = new PostBusiness()
+
+export class PostController {
+ createPost = async (req: Request, res: Response): Promise => {
+ try {
+ const input: InpultPostDTO = {
+ photo: req.body.photo,
+ description:req.body.description,
+ type: req.body.type,
+ createdAt: req.body.createdAt,
+ authorId: req.headers.authorization as string
+ };
+
+ await postBusiness.createPost(input)
+
+ res.status(201).send({ message: "Post created!" });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ findPost = async (req: Request, res: Response): Promise => {
+ try {
+ const input: PostIdDTO = {
+ id: req.body.id
+ };
+
+ const posts = await postBusiness.findPost(input)
+
+ res.status(200).send({ posts });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ feedPost = async(req: Request, res: Response) => {
+ try {
+ const input: PostIdDTO = {
+ id: req.headers.authorization as string
+ };
+
+ const posts = await postBusiness.feedPost(input)
+
+ res.status(200).send({ posts });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ feedPostAll = async(req: Request, res: Response) => {
+ try {
+ const input: PostTypeDTO = {
+ type: req.body.type
+ };
+
+ const posts = await postBusiness.feedPostAll(input)
+
+ res.status(200).send({ posts });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+ deletePost = () => {};
+
+}
\ No newline at end of file
diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts
new file mode 100644
index 0000000..b3ce7d5
--- /dev/null
+++ b/src/controller/UserController.ts
@@ -0,0 +1,25 @@
+import { Request, Response } from "express";
+import { UserBusiness } from "../business/UserBusiness";
+import { InputControllerDTO } from "../model/User";
+
+export class UserController {
+ createUser = async (req: Request, res: Response): Promise => {
+ try {
+ const input: InputControllerDTO = {
+ name: req.body.name,
+ email: req.body.email,
+ password: req.body.password,
+ };
+
+ const userBusiness = new UserBusiness()
+ await userBusiness.createUser(input)
+
+ res.status(201).send({ message: "User created!" });
+ } catch (error: any) {
+ res.status(400).send(error.message);
+ }
+ };
+
+ findUser = () => {};
+ deleteUser = () => {};
+}
\ No newline at end of file
diff --git a/src/controller/app.ts b/src/controller/app.ts
new file mode 100644
index 0000000..32e736f
--- /dev/null
+++ b/src/controller/app.ts
@@ -0,0 +1,13 @@
+import express from 'express'
+import cors from 'cors'
+
+const app = express()
+
+app.use(express.json())
+app.use(cors())
+
+app.listen(3003, ()=>{
+ console.log('Servidor rodando na porta 3003')
+})
+
+export default app
\ No newline at end of file
diff --git a/src/controller/router/FriendshipRouter.ts b/src/controller/router/FriendshipRouter.ts
new file mode 100644
index 0000000..a43c44b
--- /dev/null
+++ b/src/controller/router/FriendshipRouter.ts
@@ -0,0 +1,11 @@
+import express from "express";
+
+import { FriendshipController } from "../FriendshipController";
+
+export const friendshipRouter = express.Router()
+
+const friendshipController = new FriendshipController();
+
+friendshipRouter.post('/create',friendshipController.createFriendship);
+friendshipRouter.delete('/',friendshipController.deleteFriendship);
+
diff --git a/src/controller/router/commentsRouter.ts b/src/controller/router/commentsRouter.ts
new file mode 100644
index 0000000..3c238db
--- /dev/null
+++ b/src/controller/router/commentsRouter.ts
@@ -0,0 +1,10 @@
+import express from "express";
+
+import { CommentController } from "../CommentsController";
+
+export const commentsRouter = express.Router()
+
+const commentController = new CommentController();
+
+commentsRouter.post('/', commentController.createComment);
+
diff --git a/src/controller/router/likeRouter.ts b/src/controller/router/likeRouter.ts
new file mode 100644
index 0000000..8f58943
--- /dev/null
+++ b/src/controller/router/likeRouter.ts
@@ -0,0 +1,11 @@
+import express from "express";
+
+import { LikeController } from "../LikeController";
+
+export const likeRouter = express.Router()
+
+const likeController = new LikeController();
+
+likeRouter.post('/create',likeController.createLike);
+likeRouter.delete('/',likeController.deleteLike);
+
diff --git a/src/controller/router/postRouter.ts b/src/controller/router/postRouter.ts
new file mode 100644
index 0000000..d4d4df1
--- /dev/null
+++ b/src/controller/router/postRouter.ts
@@ -0,0 +1,13 @@
+import express from "express";
+
+import { PostController } from "../PostController";
+
+export const postRouter = express.Router()
+
+const postController = new PostController();
+
+postRouter.post('/create',postController.createPost);
+postRouter.get('/getpost',postController.findPost);
+postRouter.get('/getfeedsfreands',postController.feedPost);
+postRouter.get('/getfeeds',postController.feedPostAll);
+
diff --git a/src/controller/router/userRouter.ts b/src/controller/router/userRouter.ts
new file mode 100644
index 0000000..7d47b43
--- /dev/null
+++ b/src/controller/router/userRouter.ts
@@ -0,0 +1,10 @@
+import express from "express";
+
+import { UserController } from "../UserController";
+
+export const userRouter = express.Router()
+
+const userController = new UserController();
+
+userRouter.post('/create', userController.createUser);
+
diff --git a/src/data/BaseDatabase.ts b/src/data/BaseDatabase.ts
new file mode 100644
index 0000000..2663d9c
--- /dev/null
+++ b/src/data/BaseDatabase.ts
@@ -0,0 +1,17 @@
+import knex from "knex"
+import dotenv from "dotenv";
+
+dotenv.config();
+export abstract class BaseDatabase {
+ protected static 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_DATABASE,
+ multipleStatements: true
+ },
+});
+}
\ No newline at end of file
diff --git a/src/data/CommentsDatabase.ts b/src/data/CommentsDatabase.ts
new file mode 100644
index 0000000..056eb40
--- /dev/null
+++ b/src/data/CommentsDatabase.ts
@@ -0,0 +1,42 @@
+import { BaseDatabase } from "./BaseDatabase";
+import { CommentInputBDTO, InputCommentDTO } from "../model/Comments";
+
+export class CommentDatabase extends BaseDatabase {
+ private static TABLE_NAME ="labook_comments";
+ insertcomment = async (comment: InputCommentDTO): Promise => {
+ try {
+ await CommentDatabase.connection
+ .insert({
+ id: comment.id,
+ comment: comment.comment,
+ post_id: comment.postId,
+ author_id: comment.authorId
+ })
+ .into(CommentDatabase.TABLE_NAME);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findcomment = async (input:string): Promise => {
+ try {
+ const comments: CommentInputBDTO[] = [];
+
+ const result = await CommentDatabase.connection
+ .select("*")
+ .from(CommentDatabase.TABLE_NAME)
+ .where({input});
+
+
+ for (let comment of result) {
+ comments.push(comment);
+ }
+
+ return comments;
+
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+ deletecomment = () => {};
+}
diff --git a/src/data/FriendshipDatabase.ts b/src/data/FriendshipDatabase.ts
new file mode 100644
index 0000000..e37f5c6
--- /dev/null
+++ b/src/data/FriendshipDatabase.ts
@@ -0,0 +1,67 @@
+import { BaseDatabase } from "./BaseDatabase";
+import {
+ DeleteFriendshipInputDTO,
+ FriendshipInputDataDTO,
+ FriendshipInputDTO
+ } from "../model/Friendship";
+
+export class FriendshipDatabase extends BaseDatabase {
+ private static TABLE_NAME = "labook_friendship";
+ insertPost = async (friend: FriendshipInputDataDTO): Promise => {
+ try {
+ await FriendshipDatabase.connection
+ .insert({
+ id: friend.id,
+ friend_id: friend.friendId,
+ author_id: friend.authorId,
+ })
+ .into(FriendshipDatabase.TABLE_NAME);
+
+ await FriendshipDatabase.connection
+ .insert({
+ id: friend.idRows,
+ friend_id: friend.authorId,
+ author_id: friend.friendId,
+ })
+ .into(FriendshipDatabase.TABLE_NAME);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findFriendship = async (userid: string): Promise => {
+ try {
+ const friends: FriendshipInputDTO[] = [];
+
+ const result = await FriendshipDatabase.connection
+ .select("*")
+ .from(FriendshipDatabase.TABLE_NAME)
+ .where({ author_id: userid });
+
+ for (let friend of result) {
+ friends.push(friend);
+ }
+
+ return friends;
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+ deletePost = async (input: DeleteFriendshipInputDTO): Promise => {
+ try {
+ const { friendId, authorId } = input;
+
+ await FriendshipDatabase.connection
+ .from(FriendshipDatabase.TABLE_NAME)
+ .where({ author_id: authorId, friend_id: friendId })
+ .delete();
+
+ await FriendshipDatabase.connection
+ .from(FriendshipDatabase.TABLE_NAME)
+ .where({ author_id: friendId, friend_id: authorId })
+ .delete();
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+}
diff --git a/src/data/LikeDatabase.ts b/src/data/LikeDatabase.ts
new file mode 100644
index 0000000..e2ee473
--- /dev/null
+++ b/src/data/LikeDatabase.ts
@@ -0,0 +1,46 @@
+import { BaseDatabase } from "./BaseDatabase";
+import { LikeInputControllerDTO, LikeInputDataDTO, LikeInputDTO } from "../model/likes";
+
+export class LikeDatabase extends BaseDatabase {
+ private static TABLE_NAME = "labook_likes";
+ insertLike = async (input: LikeInputDataDTO): Promise => {
+ try {
+ await LikeDatabase.connection
+ .insert({
+ id: input.id,
+ post_id: input.postId,
+ author_id: input.authorId,
+ })
+ .into(LikeDatabase.TABLE_NAME);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findLike = async (input: LikeInputControllerDTO): Promise => {
+ try {
+
+ const {postId,authorId}= input;
+
+ const result = await LikeDatabase.connection
+ .select("*")
+ .from(LikeDatabase.TABLE_NAME)
+ .where({ post_id: postId, author_id: authorId });
+
+ return result;
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ deleteLike = async (input: string): Promise => {
+ try {
+ await LikeDatabase.connection
+ .from(LikeDatabase.TABLE_NAME)
+ .where({ id: input })
+ .delete();
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+}
diff --git a/src/data/PostDatabase.ts b/src/data/PostDatabase.ts
new file mode 100644
index 0000000..4a30b00
--- /dev/null
+++ b/src/data/PostDatabase.ts
@@ -0,0 +1,59 @@
+import { BaseDatabase } from "./BaseDatabase";
+import { FeedPostDBDTO, PostTypeDTO, TPost } from "../model/Posts";
+
+export class PostDatabase extends BaseDatabase {
+ private static TABLE_NAME = "labook_posts";
+ insertPost = async (post: TPost): Promise => {
+ try {
+ await PostDatabase.connection
+ .insert({
+ id: post.id,
+ photo: post.photo,
+ description: post.description,
+ type: post.type,
+ created_at: post.createdAt,
+ author_id: post.authorId,
+ })
+ .into(PostDatabase.TABLE_NAME);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findPost = async (postid: string): Promise => {
+ try {
+
+ const result = await PostDatabase.connection
+ .select("*")
+ .from(PostDatabase.TABLE_NAME)
+ .where({ id: postid });
+
+ return result;
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ feedPost = async (input: string[]): Promise => {
+ try {
+ const [result] = await PostDatabase.connection.raw(
+ `select * from ${PostDatabase.TABLE_NAME} where author_id in ('${input}') order by created_at desc;`
+ );
+ return result;
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ feedPostAll = async (input: PostTypeDTO): Promise => {
+ try {
+ const [result] = await PostDatabase.connection.raw(
+ `select * from ${PostDatabase.TABLE_NAME} where type = "${input.type}" order by created_at desc;`
+ );
+ return result;
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+ deletePost = () => {};
+}
diff --git a/src/data/TableDataBase.ts b/src/data/TableDataBase.ts
new file mode 100644
index 0000000..ea1c1c8
--- /dev/null
+++ b/src/data/TableDataBase.ts
@@ -0,0 +1,55 @@
+import { BaseDatabase } from "./BaseDatabase";
+
+export class Migration extends BaseDatabase {
+ createTables = async () => {
+ try {
+ await Migration.connection
+ .raw(`
+ CREATE TABLE IF NOT EXISTS labook_users(
+ id VARCHAR(255) PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ email VARCHAR(255) UNIQUE NOT NULL,
+ password VARCHAR(255) NOT NULL
+ );
+ CREATE TABLE IF NOT EXISTS labook_posts(
+ id VARCHAR(255) PRIMARY KEY,
+ photo VARCHAR(255) NOT NULL,
+ description VARCHAR(255) NOT NULL,
+ type ENUM("normal","event") DEFAULT "normal",
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ author_id VARCHAR(255),
+ FOREIGN KEY (author_id) REFERENCES labook_users (id)
+ );
+ CREATE TABLE IF NOT EXISTS labook_friendship(
+ id VARCHAR(255) PRIMARY KEY,
+ friend_id VARCHAR(255) NOT NULL,
+ author_id VARCHAR(255) NOT NULL,
+ FOREIGN KEY (author_id) REFERENCES labook_users (id),
+ FOREIGN KEY (friend_id) REFERENCES labook_users (id)
+ );
+ CREATE TABLE IF NOT EXISTS labook_likes(
+ id VARCHAR(255) PRIMARY KEY,
+ post_id VARCHAR(255) NOT NULL,
+ author_id VARCHAR(255) NOT NULL,
+ FOREIGN KEY (author_id) REFERENCES labook_users (id),
+ FOREIGN KEY (post_id) REFERENCES labook_posts (id)
+ );
+ CREATE TABLE IF NOT EXISTS labook_comments(
+ id VARCHAR(255) PRIMARY KEY,
+ comment TEXT(500) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ post_id VARCHAR(255) NOT NULL,
+ author_id VARCHAR(255) NOT NULL,
+ FOREIGN KEY (author_id) REFERENCES labook_users (id),
+ FOREIGN KEY (post_id) REFERENCES labook_posts (id)
+ );
+ `)
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+}
+
+const printError = (error: any) => {
+ console.log(error.sqlMessage || error.message);
+};
diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts
new file mode 100644
index 0000000..0630728
--- /dev/null
+++ b/src/data/UserDatabase.ts
@@ -0,0 +1,41 @@
+import { BaseDatabase } from "./BaseDatabase";
+import { UserDTO } from "../model/User";
+
+export class UserDatabase extends BaseDatabase {
+ private static TABLE_NAME = "labook_users";
+ insertUser = async (user: UserDTO): Promise => {
+ try {
+ await UserDatabase.connection
+ .insert({
+ id: user.id,
+ name: user.name,
+ email: user.email,
+ password: user.password,
+ })
+ .into(UserDatabase.TABLE_NAME);
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+
+ findUser = async (): Promise => {
+ try {
+ const users: UserDTO[] = [];
+
+ const result = await UserDatabase.connection
+ .select("*")
+ .from(UserDatabase.TABLE_NAME);
+
+
+ for (let user of result) {
+ users.push(user);
+ }
+
+ return users;
+
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+ };
+ deleteUser = () => {};
+}
diff --git a/src/data/migrations.ts b/src/data/migrations.ts
new file mode 100644
index 0000000..a7b0a5f
--- /dev/null
+++ b/src/data/migrations.ts
@@ -0,0 +1,10 @@
+import { Migration } from "./TableDataBase"
+const migration = new Migration();
+
+const queryMigrations = ()=>{
+ migration.createTables();
+ console.log("Tabelas criadas!!");
+
+}
+
+queryMigrations();
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..9c90076
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,17 @@
+import app from "./controller/app"
+import { userRouter } from "./controller/router/userRouter"
+import { postRouter } from "./controller/router/postRouter"
+import { friendshipRouter } from "./controller/router/FriendshipRouter"
+import { likeRouter } from "./controller/router/likeRouter"
+import { commentsRouter } from "./controller/router/commentsRouter"
+
+
+
+/**************************** ENDPOINTS ******************************/
+app.use('/user', userRouter)
+app.use('/post', postRouter);
+app.use('/friendship', friendshipRouter);
+app.use('/like', likeRouter);
+app.use('/comments', commentsRouter);
+
+
diff --git a/src/model/Comments.ts b/src/model/Comments.ts
new file mode 100644
index 0000000..a9ea19e
--- /dev/null
+++ b/src/model/Comments.ts
@@ -0,0 +1,22 @@
+export interface InputCommentDTO{
+ id: string,
+ comment: string,
+ postId: string,
+ authorId: string
+ }
+ export interface CommentInputBDTO{
+ id: string,
+ comment: string,
+ created_at: Date,
+ post_id: string,
+ author_id: string
+ }
+ export interface InputCommentControllerDTO{
+ comment: string,
+ postId: string,
+ authorId: string
+ }
+
+ export interface CommentIdDTO{
+ id: string,
+ }
diff --git a/src/model/Friendship.ts b/src/model/Friendship.ts
new file mode 100644
index 0000000..c97dda7
--- /dev/null
+++ b/src/model/Friendship.ts
@@ -0,0 +1,24 @@
+export type TFriendship = {
+ id: string,
+ friendId: string,
+ authorId: string
+
+}
+export interface FriendshipInputDTO{
+ id: string,
+ friend_id: string,
+ author_id: string
+
+}
+export interface FriendshipInputDataDTO{
+ id: string,
+ idRows: string,
+ friendId: string,
+ authorId: string
+
+}
+export interface DeleteFriendshipInputDTO{
+ friendId: string,
+ authorId: string
+
+}
\ No newline at end of file
diff --git a/src/model/Posts.ts b/src/model/Posts.ts
new file mode 100644
index 0000000..85947ee
--- /dev/null
+++ b/src/model/Posts.ts
@@ -0,0 +1,45 @@
+enum TPOST_TYPES {
+ NORMAL = "normal",
+ EVENT = "event"
+ }
+
+ export type TPost = {
+ id: string,
+ photo: string,
+ description: string,
+ type: TPOST_TYPES,
+ createdAt: Date,
+ authorId: string
+ }
+
+ export interface FeedPostDTO{
+ id: string,
+ photo: string,
+ description: string,
+ type: TPOST_TYPES,
+ createdAt: Date,
+ authorId: string
+ }
+ export interface FeedPostDBDTO{
+ id: string,
+ photo: string,
+ description: string,
+ type: TPOST_TYPES,
+ created_at: Date,
+ author_id: string
+ }
+ export interface InpultPostDTO{
+ photo: string,
+ description: string,
+ type: TPOST_TYPES,
+ createdAt: Date,
+ authorId: string
+ }
+
+ export interface PostIdDTO{
+ id: string,
+ }
+
+ export interface PostTypeDTO{
+ type: TPOST_TYPES
+ }
\ No newline at end of file
diff --git a/src/model/User.ts b/src/model/User.ts
new file mode 100644
index 0000000..2b98e0e
--- /dev/null
+++ b/src/model/User.ts
@@ -0,0 +1,16 @@
+export type authenticationData = {
+ id: string
+ }
+
+export interface UserDTO{
+ id: string,
+ name: string,
+ email: string,
+ password: string
+ }
+export interface InputControllerDTO{
+ name: string,
+ email: string,
+ password: string
+ }
+
\ No newline at end of file
diff --git a/src/model/friends.ts b/src/model/friends.ts
new file mode 100644
index 0000000..2009adc
--- /dev/null
+++ b/src/model/friends.ts
@@ -0,0 +1,10 @@
+export type TFriends = {
+ friend_id: string,
+ name: string
+
+}
+
+export interface FriendInputDTO{
+ friendId: string,
+ authorId: string
+}
\ No newline at end of file
diff --git a/src/model/likes.ts b/src/model/likes.ts
new file mode 100644
index 0000000..fe2deed
--- /dev/null
+++ b/src/model/likes.ts
@@ -0,0 +1,18 @@
+export interface LikeInputDTO{
+ id: string,
+ post_id: string,
+ author_id: string
+
+}
+export interface LikeInputDataDTO{
+ id: string,
+ postId: string,
+ authorId: string
+}
+export interface LikeInputControllerDTO{
+ postId: string,
+ authorId: string
+}
+export interface DeleteLikeInputDTO{
+ id: string,
+}
\ No newline at end of file
diff --git a/src/service/IdGenerator.ts b/src/service/IdGenerator.ts
new file mode 100644
index 0000000..b36379b
--- /dev/null
+++ b/src/service/IdGenerator.ts
@@ -0,0 +1,6 @@
+import { v4 } from "uuid";
+
+export class IdGenerator {
+
+ public generateId = () => v4()
+}
\ No newline at end of file
diff --git a/src/service/formatDate.ts b/src/service/formatDate.ts
new file mode 100644
index 0000000..02677c1
--- /dev/null
+++ b/src/service/formatDate.ts
@@ -0,0 +1,13 @@
+export const dateFormat = (dateAccount: string): string => {
+ let parts = dateAccount.split("/");
+ dateAccount = `${parts[2]}-${parts[1]}-${parts[0]}`;
+ return dateAccount;
+};
+export const dateFormatBr = (dateAccount: string): string => {
+ let data = new Date(dateAccount);
+ let date = String(data.getDate()).padStart(2, "0");
+ let month = String(data.getMonth() + 1).padStart(2, "0");
+ let fullYear = data.getFullYear();
+ let dataAtual = date + "/" + month + "/" + fullYear;
+ return dataAtual;
+};
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a9ee948
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
+ "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
+ "outDir": "./build" /* Redirect output structure to the directory. */,
+ "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
+ "strict": true /* Enable all strict type-checking options. */,
+ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
+ }
+}
\ No newline at end of file