diff --git a/src/modules/task-manager/controllers/workspace.controller.ts b/src/modules/task-manager/controllers/workspace.controller.ts new file mode 100644 index 0000000..93cd8eb --- /dev/null +++ b/src/modules/task-manager/controllers/workspace.controller.ts @@ -0,0 +1,53 @@ +import { Controller, Get, Post, Patch, Delete, Param, Body } from '@nestjs/common'; +import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger'; +import { WorkspaceService } from '../providers/workspace.service'; +import { CreateWorkspaceDto } from '../dto/workspace/create-workspace.dto'; +import { UpdateWorkspaceDto } from '../dto/workspace/update-workspace.dto'; +import { TMWorkspace } from '../entities/workspace.entity'; + +@ApiTags('Task Manager - Workspaces') +@Controller('task-manager/workspaces') +export class WorkspaceController { + constructor(private readonly workspaceService: WorkspaceService) {} + + @Get() + @ApiOperation({ summary: 'Get all workspaces' }) + @ApiResponse({ status: 200, description: 'List of workspaces', type: [TMWorkspace] }) + findAll(): Promise { + return this.workspaceService.findAll(); + } + + @Get(':id') + @ApiOperation({ summary: 'Get a workspace by ID' }) + @ApiParam({ name: 'id', description: 'Workspace ID' }) + @ApiResponse({ status: 200, description: 'Workspace found', type: TMWorkspace }) + @ApiResponse({ status: 404, description: 'Workspace not found' }) + findOne(@Param('id') id: string): Promise { + return this.workspaceService.findOneOrFail(id); + } + + @Post() + @ApiOperation({ summary: 'Create a new workspace' }) + @ApiResponse({ status: 201, description: 'Workspace created', type: TMWorkspace }) + create(@Body() body: CreateWorkspaceDto): Promise { + return this.workspaceService.create(body); + } + + @Patch(':id') + @ApiOperation({ summary: 'Update a workspace' }) + @ApiParam({ name: 'id', description: 'Workspace ID' }) + @ApiResponse({ status: 200, description: 'Workspace updated', type: TMWorkspace }) + @ApiResponse({ status: 404, description: 'Workspace not found' }) + update(@Param('id') id: string, @Body() body: UpdateWorkspaceDto): Promise { + return this.workspaceService.update(id, body); + } + + @Delete(':id') + @ApiOperation({ summary: 'Delete a workspace' }) + @ApiParam({ name: 'id', description: 'Workspace ID' }) + @ApiResponse({ status: 200, description: 'Workspace deleted' }) + @ApiResponse({ status: 404, description: 'Workspace not found' }) + remove(@Param('id') id: string): Promise { + return this.workspaceService.remove(id); + } +} \ No newline at end of file diff --git a/src/modules/task-manager/dto/workspace/create-workspace.dto.ts b/src/modules/task-manager/dto/workspace/create-workspace.dto.ts index ac2ef19..0efdb4b 100644 --- a/src/modules/task-manager/dto/workspace/create-workspace.dto.ts +++ b/src/modules/task-manager/dto/workspace/create-workspace.dto.ts @@ -1,25 +1,40 @@ +import { ApiProperty } from "@nestjs/swagger"; import { IsString, IsOptional, IsBoolean, IsNotEmpty, IsUUID, MaxLength } from "class-validator"; export class CreateWorkspaceDto { + @ApiProperty({ description: "Name of the workspace", example: "Engineering" }) @IsString() @IsNotEmpty() @MaxLength(100) name: string; + @ApiProperty({ description: "ID of the workspace type", example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }) + @IsUUID() + @IsNotEmpty() + workspaceTypeId: string; + + @ApiProperty({ description: "Description of the workspace", required: false, example: "Workspace for the engineering team" }) @IsString() @IsOptional() description?: string; + @ApiProperty({ description: "Color code for the workspace (hex or named)", example: "#4F46E5" }) @IsString() @IsNotEmpty() @MaxLength(20) color: string; + @ApiProperty({ description: "Whether the workspace is active", required: false, default: true, example: true }) @IsBoolean() - @IsOptional() - isActive?: boolean; + isActive: boolean; - @IsUUID() - @IsNotEmpty() - workspaceTypeId: string; + @ApiProperty({ + description: "IDs of users to assign to the workspace", + required: false, + type: [String], + example: ["b2c3d4e5-f6a7-8901-bcde-f12345678901"], + }) + @IsUUID("4", { each: true }) + @IsOptional() + userIds?: string[]; } diff --git a/src/modules/task-manager/dto/workspace/update-workspace.dto.ts b/src/modules/task-manager/dto/workspace/update-workspace.dto.ts index 8d9eef1..9dd610e 100644 --- a/src/modules/task-manager/dto/workspace/update-workspace.dto.ts +++ b/src/modules/task-manager/dto/workspace/update-workspace.dto.ts @@ -1,4 +1,4 @@ -import { PartialType } from "@nestjs/mapped-types"; +import { PartialType } from "@nestjs/swagger"; import { CreateWorkspaceDto } from "./create-workspace.dto"; export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) {} diff --git a/src/modules/task-manager/providers/workspace.service.ts b/src/modules/task-manager/providers/workspace.service.ts index 259b4f1..8d8ea40 100644 --- a/src/modules/task-manager/providers/workspace.service.ts +++ b/src/modules/task-manager/providers/workspace.service.ts @@ -1,41 +1,64 @@ -import { Injectable, NotFoundException } from "@nestjs/common"; -import { CreateWorkspaceDto } from "../dto/workspace/create-workspace.dto"; -import { WorkspaceRepository } from "../repositories/workspace.repository"; -import { UpdateWorkspaceDto } from "../dto/workspace/update-workspace.dto"; +import { Injectable, NotFoundException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { In, Repository } from 'typeorm'; +import { TMWorkspace } from '../entities/workspace.entity'; +import { CreateWorkspaceDto } from '../dto/workspace/create-workspace.dto'; +import { UpdateWorkspaceDto } from '../dto/workspace/update-workspace.dto'; +import { User } from '../../users/entities/user.entity'; @Injectable() export class WorkspaceService { constructor( - private readonly workspaceRepository: WorkspaceRepository, + @InjectRepository(TMWorkspace) + private readonly workspaceRepository: Repository, + @InjectRepository(User) + private readonly userRepository: Repository, ) {} - findAll() { - return this.workspaceRepository.findAll(); + findAll(): Promise { + return this.workspaceRepository.find({ + relations: ['workspaceType', 'projects', 'users'], + }); } - async findOne(id: string) { - const workspace = await this.workspaceRepository.findOneById(id); - - if (!workspace) { - throw new NotFoundException(`Workspace #${id} not found`); - } - + async findOneOrFail(id: string): Promise { + const workspace = await this.workspaceRepository.findOne({ + where: { id }, + relations: ['workspaceType', 'projects', 'users'], + }); + if (!workspace) throw new NotFoundException(`Workspace #${id} not found`); return workspace; } - async create(dto: CreateWorkspaceDto) { - const workspace = this.workspaceRepository.create(dto); + async create(dto: CreateWorkspaceDto): Promise { + const { userIds, ...rest } = dto; + + const workspace = this.workspaceRepository.create(rest); + + if (userIds?.length) { + workspace.users = await this.userRepository.findBy({ id: In(userIds) }); + } + return this.workspaceRepository.save(workspace); } - async update(id: string, dto: UpdateWorkspaceDto) { - await this.findOne(id); - await this.workspaceRepository.update(id, dto); - return this.findOne(id); + async update(id: string, dto: UpdateWorkspaceDto): Promise { + const workspace = await this.findOneOrFail(id); + const { userIds, ...rest } = dto; + + Object.assign(workspace, rest); + + if (userIds) { + workspace.users = userIds.length + ? await this.userRepository.findBy({ id: In(userIds) }) + : []; + } + + return this.workspaceRepository.save(workspace); } - async remove(id: string) { - await this.findOne(id); + async remove(id: string): Promise { + await this.findOneOrFail(id); await this.workspaceRepository.delete(id); } } \ No newline at end of file diff --git a/src/modules/task-manager/task-manager.controller.ts b/src/modules/task-manager/task-manager.controller.ts deleted file mode 100644 index 1d7f245..0000000 --- a/src/modules/task-manager/task-manager.controller.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Controller, Get, Post, Patch, Delete, Param, Body } from '@nestjs/common'; -import { TMWorkspace } from './entities/workspace.entity'; -import { WorkspaceService } from './providers/workspace.service'; -import { CreateWorkspaceDto } from './dto/workspace/create-workspace.dto'; -import { UpdateWorkspaceDto } from './dto/workspace/update-workspace.dto'; - -@Controller('task-manager') -export class TaskManagerController { - constructor( - private readonly workspaceService: WorkspaceService, - ) {} - // --- Workspace --- - - @Get('workspaces') - findAllWorkspaces(): Promise { - return this.workspaceService.findAll(); - } - - @Get('workspaces/:id') - findOneWorkspace(@Param('id') id: string): Promise { - return this.workspaceService.findOne(id); - } - - @Post('workspaces') - createWorkspace(@Body() body: CreateWorkspaceDto): Promise { - return this.workspaceService.create(body); - } - - @Patch('workspaces/:id') - updateWorkspace(@Param('id') id: string, @Body() body: UpdateWorkspaceDto): Promise { - return this.workspaceService.update(id, body); - } - - @Delete('workspaces/:id') - removeWorkspace(@Param('id') id: string): Promise { - return this.workspaceService.remove(id); - } -} \ No newline at end of file diff --git a/src/modules/task-manager/task-manager.module.ts b/src/modules/task-manager/task-manager.module.ts index d02d0c4..f580f2d 100644 --- a/src/modules/task-manager/task-manager.module.ts +++ b/src/modules/task-manager/task-manager.module.ts @@ -10,8 +10,9 @@ import { TMRemark } from './entities/remark.entity'; import { TMAttachment } from './entities/attachment.entity'; import { TMCheckListItem } from './entities/check-list-item.entity'; import { WorkspaceRepository } from './repositories/workspace.repository'; -import { TaskManagerController } from './task-manager.controller'; +import { WorkspaceController } from './controllers/workspace.controller'; import { WorkspaceService } from './providers/workspace.service'; +import { User } from '../users/entities/user.entity'; // import { WorkspaceTypeService } from './providers/workspace-type.service'; // import { WorkspaceService } from './providers/workspace.service'; @@ -32,9 +33,10 @@ import { WorkspaceService } from './providers/workspace.service'; TMRemark, TMAttachment, TMCheckListItem, + User ]), ], - controllers: [TaskManagerController], + controllers: [WorkspaceController], providers: [ WorkspaceRepository, WorkspaceService,