Skip to content

Commit

Permalink
build doc api
Browse files Browse the repository at this point in the history
  • Loading branch information
alfredo003 committed Dec 9, 2024
1 parent f978621 commit 665ef54
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 44 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@
"author": "alfredo chivela <[email protected]>",
"license": "MIT",
"scripts": {
"dev": "ts-node-dev --inspect --transpile-only --ignore-watch node_modules --respawn ./src/server.ts",
"dev": "ts-node-dev -r tsconfig-paths/register --inspect --transpile-only --ignore-watch node_modules --respawn ./src/server.ts",
"migration:run": "typeorm migration:run -- -d ./src/database",
"typeorm": "ts-node-dev ./node_modules/typeorm/cli.js"
},
"dependencies": {
"@types/bcryptjs": "^2.4.6",
"@types/swagger-ui-express": "^4.1.7",
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"express": "^4.21.1",
"express-async-errors": "^3.1.1",
"jsonwebtoken": "^9.0.2",
"multer": "^1.4.5-lts.1",
"pg": "^8.13.1",
"reflect-metadata": "^0.2.2",
"swagger-ui-express": "^5.0.1",
"typeorm": "^0.3.20"
},
"devDependencies": {
Expand All @@ -33,6 +36,7 @@
"eslint-plugin-import": "^2.31.0",
"globals": "^15.12.0",
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.7.2",
"typescript-eslint": "^8.16.0"
}
Expand Down
15 changes: 6 additions & 9 deletions src/controllers/MilistoneController.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Request,Response } from "express"
import { MilistoneRepository } from "../repositories/MilistoneRepository"
import { AppError } from "../errors/AppError";

export class MilistoneController
{
static async getAll(req:Request, res:Response):Promise<Response>
{
try {
const milistones = await MilistoneRepository.find();
if(!milistones) throw new AppError("Error fetching milistones",401);
return res.json(milistones);
} catch (error) {
return res.status(500).json({message:"Error fetching milistones",error})
}

}
static async create(req:Request, res:Response):Promise<Response>
{
Expand All @@ -19,17 +18,15 @@ export class MilistoneController
if (!title || !date || !user_id) {
return res.status(400).json({ message: "Missing required fields" });
}

try {
const milistone = MilistoneRepository.create({
title,
date,
user_id,
});
const milistoneSave = await MilistoneRepository.save(milistone);

if(!milistoneSave) throw new AppError("Error saving milistone",401);
return res.status(201).json(milistoneSave);
} catch (error) {
return res.status(500).json({ message: "Error saving milistone", error });
}

}
}
41 changes: 20 additions & 21 deletions src/controllers/TasksController.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
import { AppError } from "../errors/AppError";
import { TaskRepository } from "../repositories/TaskRepository";
import {Request, Response} from 'express';
import { Request, Response } from "express";

export class TasksController {
static async getAll(req: Request, res: Response): Promise<Response> {
try {
const tasks = await TaskRepository.find();
const tasks = await TaskRepository.find();
if (tasks) {
return res.status(200).json(tasks);
} catch (error) {
return res.status(500).json({ message: "Error fetching tasks", error });
}
throw new AppError("Error fetching tasks", 401);
}
static async create(req: Request, res: Response): Promise<Response> {
const { title, description, milistone_id, status } = req.body;

if (!title || !description || !milistone_id || !status) {
return res.status(400).json({ message: "Missing required fields" });
}

try {
const task = TaskRepository.create({
title,
description,
status,
milistone_id
});
const taskSave = await TaskRepository.save(task);
return res.status(200).json(taskSave);
} catch (error) {
return res.status(500).json({ message: "Error saving tasks", error });
if (!title || !description || !milistone_id || !status) {
return res.status(400).json({ message: "Missing required fields" });
}

const task = TaskRepository.create({
title,
description,
status,
milistone_id,
});
const taskSave = await TaskRepository.save(task);
if (!taskSave) throw new AppError("Error saving tasks", 401);

return res.status(200).json(taskSave);

}
}
}
3 changes: 0 additions & 3 deletions src/controllers/UserController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ export class UserController {

if (user.avatar) {
const userAvatarFilePath = path.join(upload.directory, user.avatar);
try {
const userAvatarFileExists = await fs.promises.stat(userAvatarFilePath);
if (userAvatarFileExists) await fs.promises.unlink(userAvatarFilePath);
} catch (error) {
throw new AppError("File no exists in server.");
}

}

Expand Down
6 changes: 4 additions & 2 deletions src/errors/AppError.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
class AppError {
class AppError
{
public readonly message: string;

public readonly statusCode: number;

constructor(message: string, statusCode = 400) {
constructor(message: string, statusCode = 400)
{
this.message = message;
this.statusCode = statusCode;
}
Expand Down
8 changes: 4 additions & 4 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Router } from "express";
import { milistoneRouter } from "./milistone.routes";
import { usersRouter } from "./user.routes";
import { sessionsRouter } from "./sessions.routes";
import { tasksRouter } from "./tasks.routes";
import { milistoneRouter } from "@routes/milistone.routes";
import { usersRouter } from "@routes/user.routes";
import { sessionsRouter } from "@routes/sessions.routes";
import { tasksRouter } from "@routes/tasks.routes";
const router = Router();

router.use("/sessions", sessionsRouter);
Expand Down
2 changes: 2 additions & 0 deletions src/routes/tasks.routes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Router } from "express";
import { TasksController } from "../controllers/TasksController";
import ensureAutheticated from "../middlewares/ensureAuthenticaded";

const tasksRouter = Router();

tasksRouter.use(ensureAutheticated);
tasksRouter.get("/", TasksController.getAll);
tasksRouter.post("/", TasksController.create);
export { tasksRouter };
22 changes: 20 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
import express from "express";
import express, { Request, Response, NextFunction } from "express";
import 'express-async-errors'
import { router } from "./routes";
import swaggerUI from "swagger-ui-express";
import swaggerFile from "./swagger.json"
import { AppDataSource } from "./database";
import upload from "./config/upload";
import { AppError } from "./errors/AppError";

const app = express();
app.use(express.json());
app.use('/api-docs',swaggerUI.serve,swaggerUI.setup(swaggerFile));
app.use("/files", express.static(upload.directory));
app.use(router);


app.use(
(err: Error, request: Request, response: Response, next: NextFunction) => {
if (err instanceof AppError) {
return response.status(err.statusCode).json({
status: "error",
message: err.message,
});
}
return response.status(500).json({
status: "error",
message: "Internal Server Error",
});
}
);
AppDataSource.initialize()
.then(() => {
console.log("Data Base : Ok!");
Expand Down
183 changes: 183 additions & 0 deletions src/swagger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
{
"openapi": "3.0.0",
"info": {
"title": "API Documentation",
"description": "Documentation for the API endpoints.",
"version": "1.0.0"
},
"paths": {
"/milistones": {
"get": {
"summary": "Get all milestones",
"operationId": "getAllMilestones",
"tags": ["Milestones"],
"responses": {
"200": {
"description": "A list of milestones",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object"
}
}
}
}
},
"401": {
"description": "Error fetching milestones"
}
}
},
"post": {
"summary": "Create a milestone",
"operationId": "createMilestone",
"tags": ["Milestones"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"title": { "type": "string" },
"date": { "type": "string", "format": "date-time" },
"user_id": { "type": "string" }
}
}
}
}
},
"responses": {
"201": {
"description": "Milestone created successfully"
},
"400": {
"description": "Missing required fields"
},
"401": {
"description": "Error saving milestone"
}
}
}
},
"/sessions": {
"post": {
"summary": "Authenticate user",
"operationId": "authenticateUser",
"tags": ["Sessions"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"email": { "type": "string" },
"password": { "type": "string" }
}
}
}
}
},
"responses": {
"200": {
"description": "Authentication successful",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"user": { "type": "object" },
"token": { "type": "string" }
}
}
}
}
},
"400": { "description": "Missing required fields" },
"401": { "description": "Incorrect email or password" }
}
}
},
"/tasks": {
"get": {
"summary": "Get all tasks",
"operationId": "getAllTasks",
"tags": ["Tasks"],
"responses": {
"200": { "description": "A list of tasks" },
"401": { "description": "Error fetching tasks" }
}
},
"post": {
"summary": "Create a task",
"operationId": "createTask",
"tags": ["Tasks"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"title": { "type": "string" },
"description": { "type": "string" },
"milistone_id": { "type": "string" },
"status": { "type": "string" }
}
}
}
}
},
"responses": {
"201": { "description": "Task created successfully" },
"400": { "description": "Missing required fields" },
"401": { "description": "Error saving task" }
}
}
},
"/users": {
"post": {
"summary": "Create a user",
"operationId": "createUser",
"tags": ["Users"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"password": { "type": "string" }
}
}
}
}
},
"responses": {
"201": { "description": "User created successfully" },
"400": { "description": "Missing required fields" },
"500": { "description": "Error saving user" }
}
}
},
"/users/upload-avatar": {
"post": {
"summary": "Upload user avatar",
"operationId": "uploadAvatar",
"tags": ["Users"],
"responses": {
"201": { "description": "Avatar uploaded successfully" },
"401": {
"description": "Only authenticated users can change avatar"
},
"500": { "description": "Error uploading avatar" }
}
}
}
}
}
Loading

0 comments on commit 665ef54

Please sign in to comment.