implement task controller

This commit is contained in:
João Geonizeli
2022-07-09 16:58:47 -03:00
parent 8c66fa8c85
commit 87af51d504
10 changed files with 228 additions and 19 deletions

View File

@@ -3,6 +3,7 @@ import { ProjectDto } from "../dto/poject.dto";
import { ProjectService } from "../service/project.service"; import { ProjectService } from "../service/project.service";
const router = Router(); const router = Router();
export const ProjectRoutes = router;
export const apiNamespace = "/projects"; export const apiNamespace = "/projects";
@@ -44,10 +45,7 @@ router.put(`${apiNamespace}/:id`, async (req, res) => {
const { name } = req.body; const { name } = req.body;
const projectId = parseInt(id); const projectId = parseInt(id);
const userProjects = await ProjectService.listAllByUserId(req.userId); const projectToBeUpdated = await ProjectService.findProjectFromUserById(req.userId, projectId);
const projectToBeUpdated = userProjects.find(
(project) => project.id === projectId
);
if (projectToBeUpdated) { if (projectToBeUpdated) {
ProjectService.update(projectToBeUpdated, { ProjectService.update(projectToBeUpdated, {
@@ -66,14 +64,11 @@ router.put(`${apiNamespace}/:id`, async (req, res) => {
} }
}); });
router.delete(`${apiNamespace}/:id`, async (req, res, next) => { router.delete(`${apiNamespace}/:id`, async (req, res) => {
const { id } = req.params; const { id } = req.params;
const projectId = parseInt(id); const projectId = parseInt(id);
const userProjects = await ProjectService.listAllByUserId(req.userId); const projecToBeDeleted = await ProjectService.findProjectFromUserById(req.userId, projectId);
const projecToBeDeleted = userProjects.find(
(project) => project.id === projectId
);
if (projecToBeDeleted) { if (projecToBeDeleted) {
const success = await ProjectService.destroy(projecToBeDeleted); const success = await ProjectService.destroy(projecToBeDeleted);
@@ -91,5 +86,3 @@ router.delete(`${apiNamespace}/:id`, async (req, res, next) => {
}); });
} }
}); });
export const ProjectRoutes = router;

View File

@@ -0,0 +1,171 @@
import { Router } from "express";
import { ProjectDto } from "../dto/poject.dto";
import { ProjectService } from "../service/project.service";
import { TaskService } from "../service/task.service";
const router = Router();
export const TaskRoutes = router;
export const apiNamespace = "/projects/:projectId";
router.get(`${apiNamespace}/tasks`, async (req, res) => {
let { projectId } = req.params;
const parsedProjctId = parseInt(projectId);
const project = await ProjectService.findProjectFromUserById(
req.userId,
parsedProjctId
);
if (!project) {
res.status(404).json({
error: "Project not found",
});
return;
}
const tasks: TaskDto[] = (
await TaskService.findByProjectId(parsedProjctId)
).map((task) => ({
id: task.id,
description: task.description,
createdAt: task.createdAt,
finishedAt: task.finishedAt,
}));
res.json({
data: tasks,
});
});
router.post(`${apiNamespace}/tasks`, async (req, res) => {
let { projectId } = req.params;
const parsedProjctId = parseInt(projectId);
const project = await ProjectService.findProjectFromUserById(
req.userId,
parsedProjctId
);
if (!project) {
res.status(404).json();
return;
}
const task = await TaskService.create(project, {
description: req.body.description,
});
const taskDto: TaskDto = {
id: task.id,
createdAt: task.createdAt,
description: task.description,
finishedAt: task.finishedAt,
};
res.json({
data: taskDto,
});
});
router.put(`${apiNamespace}/tasks/:id`, async (req, res) => {
let { projectId, id } = req.params;
const { description }: UpdateTaskDto = req.body;
const parsedProjctId = parseInt(projectId);
const project = await ProjectService.findProjectFromUserById(
req.userId,
parsedProjctId
);
if (!project) {
res.status(404).json();
return;
}
const task = await TaskService.findByProjectIdAndTaskId(
parsedProjctId,
parseInt(id)
);
await TaskService.update(task, { description });
const taskDto: TaskDto = {
id: task.id,
createdAt: task.createdAt,
description: task.description,
finishedAt: task.finishedAt,
};
res.json({
data: taskDto,
});
});
router.delete(`${apiNamespace}/tasks/:id`, async (req, res) => {
let { projectId, id } = req.params;
const parsedProjctId = parseInt(projectId);
const project = await ProjectService.findProjectFromUserById(
req.userId,
parsedProjctId
);
if (!project) {
res.status(404).json();
return;
}
const task = await TaskService.findByProjectIdAndTaskId(
parsedProjctId,
parseInt(id)
);
if (!task) {
res.status(404).json();
return;
}
const success = await TaskService.destroy(task);
if (success) {
res.status(204).json();
} else {
res.status(504).json();
}
});
router.get(`${apiNamespace}/tasks/:id/finish`, async (req, res) => {
const { projectId, id } = req.params;
const parsedProjctId = parseInt(projectId);
const project = await ProjectService.findProjectFromUserById(
req.userId,
parsedProjctId
);
const task = await TaskService.findByProjectIdAndTaskId(
parsedProjctId,
parseInt(id)
);
if (!project || !task) {
res.status(404).json();
return;
}
const result = await TaskService.finish(task);
const resultDto: TaskDto = {
id: result.id,
createdAt: result.createdAt,
description: result.description,
finishedAt: result.finishedAt,
};
res.json({
data: resultDto,
});
});

View File

@@ -4,6 +4,7 @@ import { AuthService } from '../service/auth.service';
import { UserService } from '../service/user.service'; import { UserService } from '../service/user.service';
const router = Router(); const router = Router();
export const UserRoutes = router;
export const apiNamespace = '/users' export const apiNamespace = '/users'
@@ -64,5 +65,3 @@ router.delete(`${apiNamespace}/sign_out`, async (req, res) => {
}) })
} }
}) })
export const UserRoutes = router;

View File

@@ -0,0 +1,6 @@
type TaskDto = {
id: number;
description: string;
createdAt: Date;
finishedAt?: Date;
}

View File

@@ -0,0 +1,3 @@
type UpdateTaskDto = {
description?: string;
}

View File

@@ -24,7 +24,10 @@ export class Task {
@Column({ type: "timestamptz", nullable: true }) @Column({ type: "timestamptz", nullable: true })
finishedAt?: Date; finishedAt?: Date;
@ManyToOne((_type) => Project, (project) => project.tasks) @ManyToOne((_type) => Project, (project) => project.tasks,{
onUpdate: "CASCADE",
onDelete: "CASCADE",
})
@JoinColumn() @JoinColumn()
@IsNotEmpty() @IsNotEmpty()
project: Project; project: Project;

View File

@@ -1,8 +1,9 @@
import "reflect-metadata"
import * as dotenv from 'dotenv'; import * as dotenv from 'dotenv';
import * as express from 'express'; import * as express from 'express';
import { AppDataSource } from "./infra/dataSource"; import "reflect-metadata";
import { ProjectRoutes, UserRoutes } from "./controller"; import { ProjectRoutes, UserRoutes } from "./controller";
import { TaskRoutes } from "./controller/task.controller";
import { AppDataSource } from "./infra/dataSource";
import { RedisConnection } from "./infra/redis"; import { RedisConnection } from "./infra/redis";
import { sessionMiddleware } from "./middleware/session.middleware"; import { sessionMiddleware } from "./middleware/session.middleware";
@@ -15,6 +16,7 @@ app.use(sessionMiddleware)
app.use(UserRoutes) app.use(UserRoutes)
app.use(ProjectRoutes) app.use(ProjectRoutes)
app.use(TaskRoutes)
const startApp = async () => { const startApp = async () => {
console.log('[redis]: connecting') console.log('[redis]: connecting')

View File

@@ -48,9 +48,21 @@ async function update(
return !!updateResult; return !!updateResult;
} }
async function findProjectFromUserById(
userId: User["id"],
projectId: Project["id"]
): Promise<Project> {
const query = projectRepository.createQueryBuilder();
query.where('"userId" = :userId', { userId });
query.andWhere('"id" = :projectId', { projectId });
return query.getOne();
}
export const ProjectService = { export const ProjectService = {
create, create,
listAllByUserId, listAllByUserId,
destroy, destroy,
update, update,
findProjectFromUserById
}; };

View File

@@ -1,4 +1,4 @@
import { NewTaskDto } from "../dto/newTaskDto"; import { NewTaskDto } from "../dto/newTask.dto";
import { Project } from "../entity/project.entity"; import { Project } from "../entity/project.entity";
import { Task } from "../entity/task.entity"; import { Task } from "../entity/task.entity";
import { taskRepository } from "../repository/task.repository"; import { taskRepository } from "../repository/task.repository";
@@ -18,20 +18,40 @@ async function destroy(task: Task) {
throw new Error("You can't destroy a finished task"); throw new Error("You can't destroy a finished task");
} }
return taskRepository.delete(task); const result = await taskRepository.delete({
id: task.id,
});
return !!result.affected;
} }
async function create(newTaskDto: NewTaskDto, project: Project) { async function create(project: Project, newTaskDto: NewTaskDto) {
const task = new Task(); const task = new Task();
task.description = newTaskDto.description; task.description = newTaskDto.description;
task.project = project; task.project = project;
task.createdAt = new Date();
return taskRepository.save(task); return taskRepository.save(task);
} }
async function findByProjectId(projectId: Project["id"]): Promise<Task[]> {
return await taskRepository.findBy({ project: { id: projectId } });
}
async function findByProjectIdAndTaskId (projectId: Project['id'], taskId: Task["id"]): Promise<Task> {
return await taskRepository.findOneBy({ id: taskId, project: { id: projectId } });
}
async function update(task: Task, updateTaskDto: UpdateTaskDto): Promise<Task> {
taskRepository.merge(task, updateTaskDto);
return taskRepository.save(task);
}
export const TaskService = { export const TaskService = {
finish, finish,
destroy, destroy,
create, create,
update,
findByProjectId,
findByProjectIdAndTaskId,
}; };