diff --git a/src/group/dto/req/getGroup.dto.ts b/src/group/dto/req/getGroup.dto.ts new file mode 100644 index 0000000..a9577a4 --- /dev/null +++ b/src/group/dto/req/getGroup.dto.ts @@ -0,0 +1,36 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsOptional, MaxLength, MinLength } from 'class-validator'; +import { IsNumber, IsString } from 'class-validator'; + +export class GetGroupByNameQueryDto { + @ApiPropertyOptional({ + example: '0', + description: '넘길 그룹 개수', + required: false, + }) + @Type(() => Number) + @IsNumber() + @IsOptional() + offset?: number; + + @ApiPropertyOptional({ + example: '10', + description: '페이지당 그룹 개수', + required: false, + }) + @Type(() => Number) + @IsNumber() + @IsOptional() + limit?: number; + + @ApiProperty({ + example: '인포', + description: '검색할 그룹 이름(일부)', + required: true, + }) + @MaxLength(20) + @MinLength(1) + @IsString() + query: string; +} diff --git a/src/group/dto/res/groupsRes.dto.ts b/src/group/dto/res/groupsRes.dto.ts new file mode 100644 index 0000000..6c689aa --- /dev/null +++ b/src/group/dto/res/groupsRes.dto.ts @@ -0,0 +1,41 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class GroupResDto { + @ApiProperty() + uuid: string; + + @ApiProperty() + name: string; + + @ApiProperty() + description: string | null; + + @ApiProperty() + createdAt: Date; + + @ApiProperty() + presidentUuid: string; + + @ApiProperty() + verifiedAt: Date | null; + + @ApiProperty() + notionPageId: string | null; + + @ApiProperty() + profileImageKey: string | null; + + @ApiProperty() + profileImageUrl: string | null; + + @ApiProperty() + verified: boolean; + + @ApiProperty() + deletedAt: Date | null; +} + +export class GroupListResDto { + @ApiProperty({ type: [GroupResDto] }) + list: GroupResDto[]; +} diff --git a/src/group/group.controller.ts b/src/group/group.controller.ts index 1928803..6a295f7 100644 --- a/src/group/group.controller.ts +++ b/src/group/group.controller.ts @@ -1,16 +1,19 @@ -import { Controller, Post, UseGuards } from '@nestjs/common'; +import { Controller, Get, Post, Query, UseGuards } from '@nestjs/common'; import { GroupService } from './group.service'; import { IdPGuard } from 'src/user/guard/idp.guard'; import { ApiCreatedResponse, ApiInternalServerErrorResponse, ApiOAuth2, + ApiOkResponse, ApiOperation, ApiTags, ApiUnauthorizedResponse, } from '@nestjs/swagger'; import { GetToken } from 'src/user/decorator/get-token.decorator'; import { GroupsTokenRes } from './dto/res/GroupsTokenRes.dto'; +import { GroupListResDto } from './dto/res/GroupsRes.dto'; +import { GetGroupByNameQueryDto } from './dto/req/getGroup.dto'; @ApiTags('Group') @ApiOAuth2(['email', 'profile', 'openid'], 'oauth2') @@ -33,4 +36,21 @@ export class GroupController { async getGroupsToken(@GetToken() token: string): Promise<GroupsTokenRes> { return this.groupService.getExternalTokenFromGroups(token); } + + @ApiOperation({ + summary: 'Searching group list', + description: 'Searching group list by nmae query', + }) + @ApiOkResponse({ + type: GroupListResDto, + description: '검색된 그룹 목록', + }) + @ApiUnauthorizedResponse() + @ApiInternalServerErrorResponse() + @Get('search') + async getGroupListByNamequeryFromGroups( + @Query() groupNameQuery: GetGroupByNameQueryDto, + ): Promise<GroupListResDto> { + return this.groupService.getGroupListByNamequeryFromGroups(groupNameQuery); + } } diff --git a/src/group/group.service.ts b/src/group/group.service.ts index 5bfa490..0fe81c1 100644 --- a/src/group/group.service.ts +++ b/src/group/group.service.ts @@ -11,6 +11,8 @@ import { GroupsToken } from './types/groupsToken.type'; import { Loggable } from '@lib/logger/decorator/loggable'; import { GroupInfo } from './types/groupInfo.type'; import { CustomConfigService } from '@lib/custom-config'; +import { GetGroupByNameQueryDto } from './dto/req/getGroup.dto'; +import { GroupListResDto } from './dto/res/GroupsRes.dto'; @Injectable() @Loggable() @@ -89,4 +91,34 @@ export class GroupService { return groupResponse.data.list; } + + async getGroupListByNamequeryFromGroups( + groupNameQuery: GetGroupByNameQueryDto, + ): Promise<GroupListResDto> { + const groupResponse = await firstValueFrom( + this.httpService.get<GroupListResDto>(this.groupsUrl + '/group/search', { + params: groupNameQuery, + auth: { + username: this.groupsClientId, + password: this.groupsClientSecret, + }, + }), + ).catch((error) => { + if (error instanceof AxiosError) { + if (error.response?.status === 401) { + this.logger.debug('Unauthorized'); + throw new UnauthorizedException(); + } else if (error.response?.status === 500) { + this.logger.error('Internal Server Error'); + throw new InternalServerErrorException(); + } + } + this.logger.error(error); + throw new InternalServerErrorException(); + }); + + return { + list: groupResponse.data.list, + }; + } }