From af606ce9a704a2aba2f0353a08ab9e1988da2f97 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Sat, 25 Jul 2026 15:48:33 +0330 Subject: [PATCH] task manager --- .../1784900000000-addAttachmentsToTaskComment.ts | 15 +++++++++++++++ .../controllers/project.controller.ts | 8 ++++++++ .../dto/task-comment/create-task-comment.dto.ts | 13 ++++++++++++- .../task-manager/entities/task-comment.entity.ts | 4 ++++ .../task-manager/providers/project.service.ts | 8 +++++++- .../providers/task-comment.service.ts | 1 + .../task-manager/repositories/task.repository.ts | 4 +++- src/modules/task-manager/task-manager.module.ts | 2 +- 8 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 database/migrations/1784900000000-addAttachmentsToTaskComment.ts diff --git a/database/migrations/1784900000000-addAttachmentsToTaskComment.ts b/database/migrations/1784900000000-addAttachmentsToTaskComment.ts new file mode 100644 index 0000000..9b1290e --- /dev/null +++ b/database/migrations/1784900000000-addAttachmentsToTaskComment.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddAttachmentsToTaskComment1784900000000 implements MigrationInterface { + name = "AddAttachmentsToTaskComment1784900000000"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "tm_task_comments" ADD "attachments" json NOT NULL DEFAULT '[]'`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tm_task_comments" DROP COLUMN "attachments"`); + } +} diff --git a/src/modules/task-manager/controllers/project.controller.ts b/src/modules/task-manager/controllers/project.controller.ts index aa9f2b7..e8a8f0b 100644 --- a/src/modules/task-manager/controllers/project.controller.ts +++ b/src/modules/task-manager/controllers/project.controller.ts @@ -12,6 +12,7 @@ import { UserDec } from "../../../common/decorators/user.decorator"; import { AuthGuards } from "../../../common/decorators/auth-guard.decorator"; import { ParamDto } from "../../../common/DTO/param.dto"; import { ITokenPayload } from "../../auth/interfaces/IToken-payload"; +import { User } from "../../users/entities/user.entity"; @AuthGuards() @AdminRoute() @@ -80,4 +81,11 @@ export class ProjectController { getProjectDetail(@Param() paramDto: ParamDto, @UserDec() user: ITokenPayload): Promise { return this.projectService.getProjectDetail(paramDto.id, user.id, user.permissions); } + + @Get(":id/users") + @ApiOperation({ summary: "Get project users" }) + @ApiResponse({ status: 200, description: "Got Project Users Successfully!" }) + getProjectUsers(@Param() paramDto: ParamDto): Promise { + return this.projectService.getProjectUsers(paramDto.id); + } } diff --git a/src/modules/task-manager/dto/task-comment/create-task-comment.dto.ts b/src/modules/task-manager/dto/task-comment/create-task-comment.dto.ts index 80b5905..1177924 100644 --- a/src/modules/task-manager/dto/task-comment/create-task-comment.dto.ts +++ b/src/modules/task-manager/dto/task-comment/create-task-comment.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from "@nestjs/swagger"; -import { IsString, IsNotEmpty, IsUUID } from "class-validator"; +import { IsString, IsNotEmpty, IsUUID, IsOptional, IsArray } from "class-validator"; export class CreateTaskCommentDto { @ApiProperty({ description: "Comment content", example: "Please review this task before closing." }) @@ -11,4 +11,15 @@ export class CreateTaskCommentDto { @IsUUID() @IsNotEmpty() taskId: string; + + @ApiProperty({ + description: "Attachment file URLs or paths", + type: [String], + required: false, + example: ["https://cdn.example.com/files/screenshot.png"], + }) + @IsOptional() + @IsArray() + @IsString({ each: true }) + attachments?: string[]; } diff --git a/src/modules/task-manager/entities/task-comment.entity.ts b/src/modules/task-manager/entities/task-comment.entity.ts index 0385bf2..8127e85 100644 --- a/src/modules/task-manager/entities/task-comment.entity.ts +++ b/src/modules/task-manager/entities/task-comment.entity.ts @@ -8,6 +8,9 @@ export class TMTaskComment extends BaseEntity { @Column({ type: "text" }) content: string; + @Column({ type: "json", default: [] }) + attachments: string[]; + // --- Relations --- @ManyToOne(() => User, { @@ -30,3 +33,4 @@ export class TMTaskComment extends BaseEntity { @Column({ type: "uuid" }) taskId: string; } + diff --git a/src/modules/task-manager/providers/project.service.ts b/src/modules/task-manager/providers/project.service.ts index 88e01d4..79f0f92 100644 --- a/src/modules/task-manager/providers/project.service.ts +++ b/src/modules/task-manager/providers/project.service.ts @@ -31,7 +31,8 @@ export class ProjectService { users: { id: true, firstName: true, - lastName: true + lastName: true, + profilePic: true, }, taskPhases: { id: true, @@ -165,4 +166,9 @@ export class ProjectService { return projectDetail; } + + async getProjectUsers(projectId: string): Promise { + const project = await this.findOneOrFail(projectId); + return project.users; + } } diff --git a/src/modules/task-manager/providers/task-comment.service.ts b/src/modules/task-manager/providers/task-comment.service.ts index eebac02..cb78956 100644 --- a/src/modules/task-manager/providers/task-comment.service.ts +++ b/src/modules/task-manager/providers/task-comment.service.ts @@ -37,6 +37,7 @@ export class TaskCommentService { const comment = this.taskCommentRepository.create({ ...dto, + attachments: dto.attachments ?? [], userId, }); return this.taskCommentRepository.save(comment); diff --git a/src/modules/task-manager/repositories/task.repository.ts b/src/modules/task-manager/repositories/task.repository.ts index 2ae25f7..9565aa7 100644 --- a/src/modules/task-manager/repositories/task.repository.ts +++ b/src/modules/task-manager/repositories/task.repository.ts @@ -47,6 +47,7 @@ export class TaskRepository extends Repository { "user.id", "user.firstName", "user.lastName", + "user.profilePic", "ticket.id", "ticket.subject", @@ -64,10 +65,11 @@ export class TaskRepository extends Repository { "comment.id", "comment.content", + "comment.attachments", "comment.createdAt", "commentUser.firstName", "commentUser.lastName", - "commentUser.profilePic" + "commentUser.profilePic", ]) .where("task.id = :taskId", { taskId }) diff --git a/src/modules/task-manager/task-manager.module.ts b/src/modules/task-manager/task-manager.module.ts index 42cfa7b..c2fc82b 100644 --- a/src/modules/task-manager/task-manager.module.ts +++ b/src/modules/task-manager/task-manager.module.ts @@ -74,6 +74,6 @@ import { TaskCommentService } from "./providers/task-comment.service"; TimeService, TaskCommentRepository, TaskCommentService, - ] + ], }) export class TaskManagerModule {}