implement task controller
This commit is contained in:
@@ -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;
|
|
||||||
|
|||||||
171
server/src/controller/task.controller.ts
Normal file
171
server/src/controller/task.controller.ts
Normal 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,
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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;
|
|
||||||
6
server/src/dto/task.dto.ts
Normal file
6
server/src/dto/task.dto.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
type TaskDto = {
|
||||||
|
id: number;
|
||||||
|
description: string;
|
||||||
|
createdAt: Date;
|
||||||
|
finishedAt?: Date;
|
||||||
|
}
|
||||||
3
server/src/dto/updateTask.dto.ts
Normal file
3
server/src/dto/updateTask.dto.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
type UpdateTaskDto = {
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user