improve project controller typings

This commit is contained in:
João Geonizeli
2022-07-10 14:33:56 -03:00
parent 3816bb852c
commit e3729ae4c0
11 changed files with 129 additions and 79 deletions

View File

@@ -1,90 +1,113 @@
import { Router } from "express"; import { Router } from "express";
import { ProjectDto } from "../dto/poject.dto"; import { ProjectDto } from "../dto/poject.dto";
import { NewProjectDto } from "../dto/project.new.dto";
import { UpdateProjectDto } from "../dto/project.update.dto";
import { ProjectService } from "../service/project.service"; import { ProjectService } from "../service/project.service";
import {
CreateResponse, DeleteResponse, IndexResponse,
UpdateResponse
} from "./typings/responses";
const router = Router(); const router = Router();
export const ProjectRoutes = router; export const ProjectRoutes = router;
export const apiNamespace = "/projects"; export const apiNamespace = "/projects";
router.get(apiNamespace, async (req, res) => { router.get<typeof apiNamespace, IndexResponse<ProjectDto>>(
const projects = await ProjectService.listAllByUserId(req.userId); apiNamespace,
async (req, res) => {
const projects = await ProjectService.listAllByUserId(req.userId);
const response: ProjectDto[] = projects.map<ProjectDto>((project) => ({ res.json({
id: project.id, data: projects.map<ProjectDto>((project) => ({
name: project.name,
}));
res.json({
data: response
});
});
router.post(apiNamespace, (req, res) => {
const { name } = req.body;
ProjectService.create({
name,
userId: req.userId,
})
.then((project) => {
const respose: ProjectDto = {
id: project.id, id: project.id,
name: project.name, name: project.name,
}; })),
res.json(respose);
})
.catch((err) => {
res.status(422).json({
error: err.message,
});
});
});
router.put(`${apiNamespace}/:id`, async (req, res) => {
const { id } = req.params;
const { name } = req.body;
const projectId = parseInt(id);
const projectToBeUpdated = await ProjectService.findProjectFromUserById(req.userId, projectId);
if (projectToBeUpdated) {
ProjectService.update(projectToBeUpdated, {
name,
}).then((success) => {
if (success) {
res.status(204).json();
} else {
res.status(402).json();
}
});
} else {
res.status(404).json({
error: "Project not found",
}); });
} }
}); );
router.delete(`${apiNamespace}/:id`, async (req, res) => { router.post<typeof apiNamespace, unknown, CreateResponse<ProjectDto>, NewProjectDto>(
const { id } = req.params; apiNamespace,
const projectId = parseInt(id); (req, res) => {
const { name } = req.body;
const projecToBeDeleted = await ProjectService.findProjectFromUserById(req.userId, projectId); ProjectService.create(req.userId, {
name,
})
.then((project) => {
res.json({
data: {
id: project.id,
name: project.name,
},
});
})
.catch((err) => {
res.status(422).json({
errors: [err.message],
});
});
}
);
if (projecToBeDeleted) { const putPath = `${apiNamespace}/:taskId`;
const success = await ProjectService.destroy(projecToBeDeleted); router.put<typeof putPath, { taskId: string }, UpdateResponse<ProjectDto>, UpdateProjectDto>(
putPath,
async (req, res) => {
const { taskId } = req.params;
const { name } = req.body;
const projectId = parseInt(taskId);
if (success) { const projectToBeUpdated = await ProjectService.findProjectFromUserById(
res.json({ success }); req.userId,
projectId
);
if (projectToBeUpdated) {
ProjectService.update(projectToBeUpdated, {
name,
}).then((success) => {
if (success) {
res.status(204).json();
} else {
res.status(402).json();
}
});
} else { } else {
res.status(422).json({ res.status(404).json({
error: "Could not delete project", errors: ["Project not found"],
}); });
} }
} else {
res.status(404).json({
error: "Project not found",
});
} }
}); );
const deletePath = `${apiNamespace}/:taskId`;
router.delete<typeof deletePath, { taskId: string }, DeleteResponse>(
deletePath,
async (req, res) => {
const { taskId } = req.params;
const projectId = parseInt(taskId);
const projecToBeDeleted = await ProjectService.findProjectFromUserById(
req.userId,
projectId
);
if (projecToBeDeleted) {
const success = await ProjectService.destroy(projecToBeDeleted);
if (success) {
res.json({ success });
} else {
res.status(422).json({
errors: ["Could not delete project"],
});
}
} else {
res.status(404).json({
errors: ["Project not found"],
});
}
}
);

View File

@@ -0,0 +1,25 @@
export type ErrorResponse = {
errors: string[];
};
export type IndexResponse<TData> = {
data: TData[];
};
export type CreateResponse<TData> =
| {
data: TData;
}
| ErrorResponse;
export type UpdateResponse<TData> =
| {
data: TData;
}
| ErrorResponse;
export type DeleteResponse =
| {
success: boolean;
}
| ErrorResponse;

View File

@@ -1,4 +1,3 @@
export type NewProjectDto = { export type NewProjectDto = {
name: string name: string
userId: number
} }

View File

@@ -1,3 +1,3 @@
export type UpdateProjectDto = { export type UpdateProjectDto = {
name: string name?: string
} }

View File

@@ -1,14 +1,17 @@
import { validate } from "class-validator"; import { validate } from "class-validator";
import { NewProjectDto } from "../dto/newProject.dto"; import { NewProjectDto } from "../dto/project.new.dto";
import { UpdateProjectDto } from "../dto/updateProject.dto"; import { UpdateProjectDto } from "../dto/project.update.dto";
import { Project } from "../entity/project.entity"; import { Project } from "../entity/project.entity";
import { User } from "../entity/user.entity"; import { User } from "../entity/user.entity";
import { projectRepository } from "../repository/project.repository"; import { projectRepository } from "../repository/project.repository";
import { UserService } from "./user.service"; import { UserService } from "./user.service";
async function create(newProject: NewProjectDto): Promise<Project> { async function create(
userId: User["id"],
newProject: NewProjectDto
): Promise<Project> {
const project = new Project(); const project = new Project();
const user = await UserService.findUserById(newProject.userId); const user = await UserService.findUserById(userId);
project.name = newProject.name; project.name = newProject.name;
project.user = user; project.user = user;
@@ -40,9 +43,9 @@ async function destroy(project: Project): Promise<boolean> {
async function update( async function update(
project: Project, project: Project,
updateProjectDto: UpdateProjectDto data: UpdateProjectDto
): Promise<boolean> { ): Promise<boolean> {
projectRepository.merge(project, updateProjectDto); projectRepository.merge(project, data);
const updateResult = await projectRepository.save(project); const updateResult = await projectRepository.save(project);
return !!updateResult; return !!updateResult;
@@ -64,5 +67,5 @@ export const ProjectService = {
listAllByUserId, listAllByUserId,
destroy, destroy,
update, update,
findProjectFromUserById findProjectFromUserById,
}; };

View File

@@ -1,4 +1,4 @@
import { NewTaskDto } from "../dto/newTask.dto"; import { NewTaskDto } from "../dto/task.new.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";

View File

@@ -1,5 +1,5 @@
import { validate } from "class-validator" import { validate } from "class-validator"
import { NewUserDto } from "../dto/newUser.dto" import { NewUserDto } from "../dto/user.new.dto"
import { User } from "../entity/user.entity" import { User } from "../entity/user.entity"
import { userRepository } from "../repository/user.repository" import { userRepository } from "../repository/user.repository"
import { AuthService } from "./auth.service" import { AuthService } from "./auth.service"