feat: added task phase APIs
This commit is contained in:
@@ -1,58 +1,58 @@
|
|||||||
import { Controller, Get, Post, Patch, Delete, Param, Body, Query } from "@nestjs/common";
|
import { Controller, Get, Post, Patch, Delete, Param, Body, Query } from '@nestjs/common';
|
||||||
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery } from "@nestjs/swagger";
|
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery } from '@nestjs/swagger';
|
||||||
import { ProjectService } from "../providers/project.service";
|
import { ProjectService } from '../providers/project.service';
|
||||||
import { CreateProjectDto } from "../dto/project/create-project.dto";
|
import { CreateProjectDto } from '../dto/project/create-project.dto';
|
||||||
import { UpdateProjectDto } from "../dto/project/update-project.dto";
|
import { UpdateProjectDto } from '../dto/project/update-project.dto';
|
||||||
import { TMProject } from "../entities/project.entity";
|
import { TMProject } from '../entities/project.entity';
|
||||||
|
|
||||||
@ApiTags("Task Manager - Projects")
|
@ApiTags('Task Manager - Projects')
|
||||||
@Controller("task-manager/projects")
|
@Controller('task-manager/projects')
|
||||||
export class ProjectController {
|
export class ProjectController {
|
||||||
constructor(private readonly projectService: ProjectService) {}
|
constructor(private readonly projectService: ProjectService) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiOperation({ summary: "Get all projects, optionally filtered by workspace" })
|
@ApiOperation({ summary: 'Get all projects, optionally filtered by workspace' })
|
||||||
@ApiQuery({ name: "workspaceId", required: false, description: "Filter projects by workspace ID" })
|
@ApiQuery({ name: 'workspaceId', required: false, description: 'Filter projects by workspace ID' })
|
||||||
@ApiResponse({ status: 200, description: "List of projects", type: [TMProject] })
|
@ApiResponse({ status: 200, description: 'List of projects', type: [TMProject] })
|
||||||
findAll(@Query("workspaceId") workspaceId?: string): Promise<TMProject[]> {
|
findAll(@Query('workspaceId') workspaceId?: string): Promise<TMProject[]> {
|
||||||
if (workspaceId) return this.projectService.findByWorkspace(workspaceId);
|
if (workspaceId) return this.projectService.findByWorkspace(workspaceId);
|
||||||
return this.projectService.findAll();
|
return this.projectService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(":id")
|
@Get(':id')
|
||||||
@ApiOperation({ summary: "Get a project by ID" })
|
@ApiOperation({ summary: 'Get a project by ID' })
|
||||||
@ApiParam({ name: "id", description: "Project ID" })
|
@ApiParam({ name: 'id', description: 'Project ID' })
|
||||||
@ApiResponse({ status: 200, description: "Project found", type: TMProject })
|
@ApiResponse({ status: 200, description: 'Project found', type: TMProject })
|
||||||
@ApiResponse({ status: 404, description: "Project not found" })
|
@ApiResponse({ status: 404, description: 'Project not found' })
|
||||||
findOne(@Param("id") id: string): Promise<TMProject> {
|
findOne(@Param('id') id: string): Promise<TMProject> {
|
||||||
return this.projectService.findOne(id);
|
return this.projectService.findOne(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@ApiOperation({ summary: "Create a new project" })
|
@ApiOperation({ summary: 'Create a new project' })
|
||||||
@ApiResponse({ status: 201, description: "Project created", type: TMProject })
|
@ApiResponse({ status: 201, description: 'Project created', type: TMProject })
|
||||||
@ApiResponse({ status: 400, description: "One or more users are not members of the workspace" })
|
@ApiResponse({ status: 400, description: 'One or more users are not members of the workspace' })
|
||||||
@ApiResponse({ status: 404, description: "Workspace not found" })
|
@ApiResponse({ status: 404, description: 'Workspace not found' })
|
||||||
create(@Body() body: CreateProjectDto): Promise<TMProject> {
|
create(@Body() body: CreateProjectDto): Promise<TMProject> {
|
||||||
return this.projectService.create(body);
|
return this.projectService.create(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(":id")
|
@Patch(':id')
|
||||||
@ApiOperation({ summary: "Update a project" })
|
@ApiOperation({ summary: 'Update a project' })
|
||||||
@ApiParam({ name: "id", description: "Project ID" })
|
@ApiParam({ name: 'id', description: 'Project ID' })
|
||||||
@ApiResponse({ status: 200, description: "Project updated", type: TMProject })
|
@ApiResponse({ status: 200, description: 'Project updated', type: TMProject })
|
||||||
@ApiResponse({ status: 400, description: "One or more users are not members of the workspace" })
|
@ApiResponse({ status: 400, description: 'One or more users are not members of the workspace' })
|
||||||
@ApiResponse({ status: 404, description: "Project not found" })
|
@ApiResponse({ status: 404, description: 'Project not found' })
|
||||||
update(@Param("id") id: string, @Body() body: UpdateProjectDto): Promise<TMProject> {
|
update(@Param('id') id: string, @Body() body: UpdateProjectDto): Promise<TMProject> {
|
||||||
return this.projectService.update(id, body);
|
return this.projectService.update(id, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(":id")
|
@Delete(':id')
|
||||||
@ApiOperation({ summary: "Delete a project" })
|
@ApiOperation({ summary: 'Delete a project' })
|
||||||
@ApiParam({ name: "id", description: "Project ID" })
|
@ApiParam({ name: 'id', description: 'Project ID' })
|
||||||
@ApiResponse({ status: 200, description: "Project deleted" })
|
@ApiResponse({ status: 200, description: 'Project deleted' })
|
||||||
@ApiResponse({ status: 404, description: "Project not found" })
|
@ApiResponse({ status: 404, description: 'Project not found' })
|
||||||
remove(@Param("id") id: string): Promise<TMProject> {
|
remove(@Param('id') id: string): Promise<TMProject> {
|
||||||
return this.projectService.remove(id);
|
return this.projectService.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { Controller, Get, Post, Patch, Delete, Param, Body, Query } from "@nestjs/common";
|
||||||
|
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery } from "@nestjs/swagger";
|
||||||
|
import { TaskPhaseService } from "../providers/task-phase.service";
|
||||||
|
import { CreateTaskPhaseDto } from "../dto/task-phase/create-task-phase.dto";
|
||||||
|
import { UpdateTaskPhaseDto } from "../dto/task-phase/update-task-phase.dto";
|
||||||
|
import { TMTaskPhase } from "../entities/task-phase.entity";
|
||||||
|
|
||||||
|
@ApiTags("Task Manager - Task Phases")
|
||||||
|
@Controller("task-manager/task-phases")
|
||||||
|
export class TaskPhaseController {
|
||||||
|
constructor(private readonly taskPhaseService: TaskPhaseService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiOperation({ summary: "Get all task phases, optionally filtered by project" })
|
||||||
|
@ApiQuery({ name: "projectId", required: false, description: "Filter task phases by project ID" })
|
||||||
|
@ApiResponse({ status: 200, description: "List of task phases", type: [TMTaskPhase] })
|
||||||
|
findAll(@Query("projectId") projectId?: string): Promise<TMTaskPhase[]> {
|
||||||
|
if (projectId) return this.taskPhaseService.findByProject(projectId);
|
||||||
|
return this.taskPhaseService.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(":id")
|
||||||
|
@ApiOperation({ summary: "Get a task phase by ID" })
|
||||||
|
@ApiParam({ name: "id", description: "TaskPhase ID" })
|
||||||
|
@ApiResponse({ status: 200, description: "TaskPhase found", type: TMTaskPhase })
|
||||||
|
@ApiResponse({ status: 404, description: "TaskPhase not found" })
|
||||||
|
findOne(@Param("id") id: string): Promise<TMTaskPhase> {
|
||||||
|
return this.taskPhaseService.findOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@ApiOperation({ summary: "Create a new task phase" })
|
||||||
|
@ApiResponse({ status: 201, description: "TaskPhase created", type: TMTaskPhase })
|
||||||
|
@ApiResponse({ status: 404, description: "Project not found" })
|
||||||
|
create(@Body() body: CreateTaskPhaseDto): Promise<TMTaskPhase> {
|
||||||
|
return this.taskPhaseService.create(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(":id")
|
||||||
|
@ApiOperation({ summary: "Update a task phase" })
|
||||||
|
@ApiParam({ name: "id", description: "TaskPhase ID" })
|
||||||
|
@ApiResponse({ status: 200, description: "TaskPhase updated", type: TMTaskPhase })
|
||||||
|
@ApiResponse({ status: 404, description: "TaskPhase or Project not found" })
|
||||||
|
update(@Param("id") id: string, @Body() body: UpdateTaskPhaseDto): Promise<TMTaskPhase> {
|
||||||
|
return this.taskPhaseService.update(id, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(":id")
|
||||||
|
@ApiOperation({ summary: "Delete a task phase" })
|
||||||
|
@ApiParam({ name: "id", description: "TaskPhase ID" })
|
||||||
|
@ApiResponse({ status: 200, description: "TaskPhase deleted" })
|
||||||
|
@ApiResponse({ status: 404, description: "TaskPhase not found" })
|
||||||
|
remove(@Param("id") id: string): Promise<void> {
|
||||||
|
return this.taskPhaseService.remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsString, IsOptional, IsNotEmpty, IsUUID, IsInt, MaxLength, Min } from "class-validator";
|
||||||
|
|
||||||
|
export class CreateTaskPhaseDto {
|
||||||
|
@ApiProperty({ description: "Name of the task phase", example: "In Progress" })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@MaxLength(100)
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Display order of the task phase", required: false, example: 1 })
|
||||||
|
@IsInt()
|
||||||
|
@IsOptional()
|
||||||
|
@Min(0)
|
||||||
|
order?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Color code for the task phase", required: false, example: "#4F46E5" })
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@MaxLength(20)
|
||||||
|
color?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: "ID of the project this phase belongs to", example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" })
|
||||||
|
@IsUUID()
|
||||||
|
@IsNotEmpty()
|
||||||
|
projectId: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { PartialType } from "@nestjs/swagger";
|
||||||
|
import { CreateTaskPhaseDto } from "./create-task-phase.dto";
|
||||||
|
|
||||||
|
export class UpdateTaskPhaseDto extends PartialType(CreateTaskPhaseDto) {}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
|
import { TaskPhaseRepository } from "../repositories/task-phase.repository";
|
||||||
|
import { ProjectRepository } from "../repositories/project.repository";
|
||||||
|
import { TMTaskPhase } from "../entities/task-phase.entity";
|
||||||
|
import { CreateTaskPhaseDto } from "../dto/task-phase/create-task-phase.dto";
|
||||||
|
import { UpdateTaskPhaseDto } from "../dto/task-phase/update-task-phase.dto";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TaskPhaseService {
|
||||||
|
constructor(
|
||||||
|
private readonly taskPhaseRepository: TaskPhaseRepository,
|
||||||
|
private readonly projectRepository: ProjectRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
findAll(): Promise<TMTaskPhase[]> {
|
||||||
|
return this.taskPhaseRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
findByProject(projectId: string): Promise<TMTaskPhase[]> {
|
||||||
|
return this.taskPhaseRepository.findByProject(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(id: string): Promise<TMTaskPhase> {
|
||||||
|
const taskPhase = await this.taskPhaseRepository.findOneById(id);
|
||||||
|
if (!taskPhase) throw new NotFoundException(`TaskPhase #${id} not found`);
|
||||||
|
return taskPhase;
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(dto: CreateTaskPhaseDto): Promise<TMTaskPhase> {
|
||||||
|
const project = await this.projectRepository.findOneById(dto.projectId);
|
||||||
|
if (!project) throw new NotFoundException(`Project #${dto.projectId} not found`);
|
||||||
|
|
||||||
|
const taskPhase = this.taskPhaseRepository.create(dto);
|
||||||
|
return this.taskPhaseRepository.save(taskPhase);
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: string, dto: UpdateTaskPhaseDto): Promise<TMTaskPhase> {
|
||||||
|
const taskPhase = await this.findOne(id);
|
||||||
|
|
||||||
|
if (dto.projectId) {
|
||||||
|
const project = await this.projectRepository.findOneById(dto.projectId);
|
||||||
|
if (!project) throw new NotFoundException(`Project #${dto.projectId} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(taskPhase, dto);
|
||||||
|
return this.taskPhaseRepository.save(taskPhase);
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string): Promise<void> {
|
||||||
|
await this.findOne(id);
|
||||||
|
await this.taskPhaseRepository.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { Injectable } from "@nestjs/common";
|
||||||
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
|
import { Repository } from "typeorm";
|
||||||
|
import { TMTaskPhase } from "../entities/task-phase.entity";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TaskPhaseRepository {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(TMTaskPhase)
|
||||||
|
private readonly repository: Repository<TMTaskPhase>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
findAll() {
|
||||||
|
return this.repository.find({
|
||||||
|
relations: ["project", "tasks"],
|
||||||
|
order: { order: "ASC" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
findByProject(projectId: string) {
|
||||||
|
return this.repository.find({
|
||||||
|
where: { projectId },
|
||||||
|
relations: ["tasks"],
|
||||||
|
order: { order: "ASC" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
findOneById(id: string) {
|
||||||
|
return this.repository.findOne({
|
||||||
|
where: { id },
|
||||||
|
relations: ["project", "tasks"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
create(data: Partial<TMTaskPhase>) {
|
||||||
|
return this.repository.create(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
save(taskPhase: TMTaskPhase) {
|
||||||
|
return this.repository.save(taskPhase);
|
||||||
|
}
|
||||||
|
|
||||||
|
update(id: string, data: Partial<TMTaskPhase>) {
|
||||||
|
return this.repository.update(id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(id: string) {
|
||||||
|
return this.repository.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user