Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Server/Feature] 커뮤니티 삭제, 자신이 속한 커뮤니티들의 정보를 받아오는 API 구현 #129

Merged
merged 10 commits into from
Nov 25, 2022
Merged
38 changes: 18 additions & 20 deletions server/apps/api/src/community/community.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ export class CommunityController {
private communityService: CommunityService,
) {}

@Get()
@UseGuards(JwtAccessGuard)
async getCommunities(@Req() req: any) {
try {
const result = await this.communityService.getCommunities(req.user._doc);
return responseForm(200, result);
} catch (error) {
this.logger.error(JSON.stringify(error.response));
throw error;
}
}

@Post()
@UseGuards(JwtAccessGuard)
async crateCommunity(@Body() createCommunityDto: CreateCommunityDto, @Req() req: any) {
Expand All @@ -52,12 +64,11 @@ export class CommunityController {
@Req() req: any,
) {
try {
const _id = req.user._id;
const result = await this.communityService.appendParticipantsToCommunity({
...appendUsersToCommunityDto,
requestUser_id: _id,
});
return responseForm(200, result);
await this.communityService.appendParticipantsToCommunity(
req.user,
appendUsersToCommunityDto,
);
return responseForm(200, { message: '커뮤니티 사용자 추가 완료' });
} catch (error) {
this.logger.error(JSON.stringify(error.response));
throw error;
Expand All @@ -70,7 +81,7 @@ export class CommunityController {
try {
const _id = req.user._id;
await this.communityService.modifyCommunity({ ...modifyCommunityDto, managerId: _id });
return responseForm(200, {});
return responseForm(200, { message: '커뮤니티 정보 수정 완료' });
} catch (error) {
this.logger.error(JSON.stringify(error.response));
throw error;
Expand All @@ -90,17 +101,4 @@ export class CommunityController {
throw error;
}
}

// @Get()
// @UseGuards(JwtAccessGuard)
// async getCommunities(@Req() req: any) {
// try {
// const _id = req.user._id;
// const result = await this.communityService.getCommunities(_id);
// return responseForm(200, result);
// } catch (error) {
// this.logger.error(JSON.stringify(error.response));
// throw error;
// }
// }
}
75 changes: 63 additions & 12 deletions server/apps/api/src/community/community.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
ModifyCommunityDto,
DeleteCommunityDto,
} from './dto';
import { IsUserInCommunity, makeCommunityObj } from '@community/helper';
import { communityInUser } from '@user/dto/community-in-user.dto';

@Injectable()
export class CommunityService {
Expand All @@ -15,48 +17,97 @@ export class CommunityService {
private readonly userRepository: UserRepository,
) {}

async getCommunities(user2) {
const user = await this.userRepository.findById('637f2abb146636e4082885b1');
const infos = [];
await Promise.all(
Array.from(user.communities.values()).map(async (userCommunity) => {
const { _id, channels } = userCommunity as communityInUser;
const community = await this.communityRepository.findById(_id);
if (!community) {
throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.');
}
const result = Array.from(channels.keys()).filter(
(channel_id: string) => !community.channels.includes(channel_id),
);
if (result.length > 0) {
console.log(result);
throw new BadRequestException('커뮤니티에 없는 비정상적인 채널이 존재합니다.');
}
const info = {};
info[_id] = [];
await Promise.all(
Array.from(channels.keys()).map(async (channelId) => {
const lastRead = channels.get(channelId);
console.log(lastRead);
// TODO: soft delete이면 조건 다시 설정
// const channel = await this.channelRepository.findById(channelId);
// if (!channel) {
// throw new BadRequestException('존재하지 않는 채널입니다.');
// }
// info[_id][channelId] = lastRead < channel.updatedAt;
// console.log(info[_id]);
}),
);
console.log(info);

infos.push(info);
}),
);
return infos;
}
async createCommunity(createCommunityDto: CreateCommunityDto) {
const community = await this.communityRepository.create({
...createCommunityDto,
users: [createCommunityDto.managerId],
});
const newCommunity = {};
newCommunity[`communities.${community._id.toString()}`] = { _id: community._id.toString() };
const newCommunity = makeCommunityObj(community._id.toString());
await this.userRepository.updateObject({ _id: createCommunityDto.managerId }, newCommunity);
return community;
}

async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) {
async appendParticipantsToCommunity(
reqUser,
appendUsersToCommunityDto: AppendUsersToCommunityDto,
) {
const communityId = appendUsersToCommunityDto.community_id;
if (!IsUserInCommunity(reqUser, communityId)) {
throw new BadRequestException(`커뮤니티에 속하지 않는 사용자는 요청할 수 없습니다.`);
}
const newCommunity = makeCommunityObj(communityId);
await Promise.all(
// 사용자 document 검증 (올바른 사용자인지, 해당 사용자가 이미 커뮤니티에 참여하고 있는건 아닌지)
appendUsersToCommunityDto.users.map(async (user_id) => {
const user = await this.userRepository.findById(user_id);
if (!user) {
throw new BadRequestException(
`커뮤니티에 추가를 요청한 사용자 _id(${user_id})가 올바르지 않습니다.`,
);
} else if (IsUserInCommunity(user, communityId)) {
throw new BadRequestException(`이미 커뮤니티에 추가된 사용자 입니다.`);
}
await this.userRepository.addArrAtArr(user_id, 'communities', [
appendUsersToCommunityDto.community_id,
]);
}),
);
await Promise.all(
// 사용자 document 검증이 끝난 후 update
appendUsersToCommunityDto.users.map(async (user_id) => {
await this.userRepository.updateObject({ _id: user_id }, newCommunity);
}),
);
const community = await this.communityRepository.addArrAtArr(
appendUsersToCommunityDto.community_id,
{ _id: appendUsersToCommunityDto.community_id },
'users',
appendUsersToCommunityDto.users,
);
if (!community) {
await Promise.all(
// 사용자 document에서 다시 삭제
appendUsersToCommunityDto.users.map((user_id) => {
this.userRepository.deleteElementAtArr(
{ _id: user_id },
{ communities: [appendUsersToCommunityDto.community_id] },
);
this.userRepository.deleteObject({ _id: user_id }, newCommunity);
}),
);
throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.');
}
return { message: '커뮤니티 사용자 추가 완료' };
}

async modifyCommunity(modifyCommunityDto: ModifyCommunityDto) {
Expand Down
2 changes: 1 addition & 1 deletion server/apps/api/src/community/dto/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './append-particitants-to-community.dto';
export * from './append-participants-to-community.dto';
export * from './create-community.dto';
export * from './modify-community.dto';
export * from './delete-community.dto';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const IsUserInCommunity = (user, communityId) =>
(user.communities ?? false) && Array.from(user.communities.keys()).includes(communityId);
2 changes: 2 additions & 0 deletions server/apps/api/src/community/helper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './checkUserIsInCommunity';
export * from './makeCommunityObj';
8 changes: 8 additions & 0 deletions server/apps/api/src/community/helper/makeCommunityObj.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const makeCommunityObj = (community_id: string) => {
const newCommunity = {};
newCommunity[`communities.${community_id}`] = {
_id: community_id,
channels: {},
};
return newCommunity;
};
4 changes: 4 additions & 0 deletions server/apps/api/src/user/dto/community-in-user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface communityInUser {
_id: string;
channels?: Map<string, Date>;
}
5 changes: 3 additions & 2 deletions server/dao/repository/community.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ export class CommunityRepository {
return await this.communityModel.findById(_id);
}

async addArrAtArr(_id, attribute, appendArr) {
async addArrAtArr(filter, attribute, appendArr) {
const addArr = {};
addArr[attribute] = { $each: appendArr };
return await this.communityModel.findByIdAndUpdate(_id, { $addToSet: addArr }, { new: true });
return await this.communityModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true });
// console.log('pass');
}

async findOne(condition: any) {
Expand Down
6 changes: 5 additions & 1 deletion server/dao/repository/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ export class UserRepository {
}

async updateObject(filter, appendElement) {
await this.userModel.updateOne(filter, { $set: appendElement });
return await this.userModel.updateOne(filter, { $set: appendElement });
}

async deleteObject(filter, appendElement) {
await this.userModel.updateOne(filter, { $unset: appendElement });
}

async deleteElementAtArr(filter, removeElement) {
Expand Down
7 changes: 1 addition & 6 deletions server/dao/schemas/user.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import { IsIn, IsString } from 'class-validator';
import mongoose, { Document } from 'mongoose';
import { STATUS } from '@utils/def';

const channels = {
_id: { type: String },
lastRead: { type: Date, default: new Date() },
};

export type UserDocument = User & Document;

@Schema({ timestamps: true })
Expand Down Expand Up @@ -71,7 +66,7 @@ export class User {
of: new mongoose.Schema({ _id: { type: String }, channels: { type: Map, of: Date } }),
}),
)
communities; //: { type: Map<string, any> };
communities;
}

export const UserSchema = SchemaFactory.createForClass(User);