Skip to content

Commit

Permalink
feat: ✨ followList 타입 생성 및 리스트 함수 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
niamu01 committed Feb 20, 2024
1 parent 767225e commit a2dd812
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 136 deletions.
12 changes: 0 additions & 12 deletions app/src/api/follow/follow.module.ts

This file was deleted.

66 changes: 0 additions & 66 deletions app/src/api/follow/follow.service.ts

This file was deleted.

2 changes: 2 additions & 0 deletions app/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { JWT_CONFIG } from './config/jwt';
import { RUNTIME_CONFIG } from './config/runtime';
import { MongooseRootModule } from './database/mongoose/database.mongoose.module';
import { DateWrapper } from './dateWrapper/dateWrapper';
import { FollowModule } from './follow/follow.module';
import { HealthCheckModule } from './healthcheck/healthcheck.module';
import { LambdaModule } from './lambda/lambda.module';
import { LoginModule } from './login/login.module';
Expand Down Expand Up @@ -97,6 +98,7 @@ export class AppRootModule {}
EvalLogModule,
SettingModule,
CalculatorModule,
FollowModule,
LambdaModule,
HealthCheckModule,
CacheDecoratorOnReturnModule,
Expand Down
File renamed without changes.
17 changes: 17 additions & 0 deletions app/src/follow/follow.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CursusUserModule } from 'src/api/cursusUser/cursusUser.module';
import { FollowSchema, follow } from './db/follow.database.schema';
import { FollowResolver } from './follow.resolve';
import { FollowService } from './follow.service';

@Module({
imports: [
MongooseModule.forFeature([{ name: follow.name, schema: FollowSchema }]),
CursusUserModule,
],
providers: [FollowResolver, FollowService],
//exports: [FollowService],
})
// eslint-disable-next-line
export class FollowModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,56 @@ import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { MyUserId } from 'src/auth/myContext';
import { StatAuthGuard } from 'src/auth/statAuthGuard';
import { HttpExceptionFilter } from 'src/http-exception.filter';
import { follow } from './db/follow.database.schema';
import { FollowService } from './follow.service';
import { FollowSuccess, UserList } from './model/follow.model';
import { FollowResult, FollowUserList } from './model/follow.model';

@UseFilters(HttpExceptionFilter)
@UseGuards(StatAuthGuard)
@Resolver()
export class FollowResolver {
constructor(private readonly followService: FollowService) {}

@Mutation((_returns) => FollowSuccess)
@Mutation((_returns) => FollowResult)
async followUser(
@MyUserId() userId: number,
@Args('login') login: string,
): Promise<follow> {
): Promise<typeof FollowResult> {
return await this.followService.followUser(userId, login);
}

@Mutation((_returns) => FollowSuccess)
async unfollowUser(
@Mutation((_returns) => FollowResult)
async unFollowUser(
@MyUserId() userId: number,
@Args('login') login: string,
): Promise<follow> {
return await this.followService.unfollowUser(userId, login);
): Promise<typeof FollowResult> {
return await this.followService.unFollowUser(userId, login);
}

@Mutation((_returns) => UserList)
async getFollowerList(login: string): Promise<UserList> {
const user = await this.followService.getFollowerList(login);
@Mutation((_returns) => FollowUserList)
async getFollowerList(
@MyUserId() userId: number,
@Args('login') login: string,
): Promise<FollowUserList> {
const followUser = await this.followService.getFollowerList(login);
const count = await this.followService.getFollowerCount(login);

return {
count,
user,
followUser,
};
}

@Mutation((_returns) => UserList)
async getFollowingList(login: string): Promise<UserList> {
const user = await this.followService.getFollowingList(login);
@Mutation((_returns) => FollowUserList)
async getFollowingList(
@MyUserId() userId: number,
@Args('login') login: string,
): Promise<FollowUserList> {
const followUser = await this.followService.getFollowingList(userId, login);
const count = await this.followService.getFollowingCount(login);

return {
count,
user,
followUser,
};
}
}
166 changes: 166 additions & 0 deletions app/src/follow/follow.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { UserPreview } from 'src/common/models/common.user.model';
import { CursusUserService } from '../api/cursusUser/cursusUser.service';
import { follow } from './db/follow.database.schema';
import { FollowListByMe, FollowResult } from './model/follow.model';

@Injectable()
export class FollowService {
constructor(
@InjectModel(follow.name)
private readonly followModel: Model<follow>,
private readonly cursusUserService: CursusUserService,
) {}

// input으로 들어온 유저를 팔로우 함
async followUser(
followerId: number,
followingLogin: string,
): Promise<typeof FollowResult> {
const follower = await this.cursusUserService
.findOneAndLean({
filter: { 'user.id': followerId },
})
.then((follower) => follower?.user.id);

const following = await this.cursusUserService
.findOneAndLean({
filter: { 'user.login': followingLogin },
})
.then((following) => following?.user.id);

if (!follower || !following || follower === following) {
return { message: 'fail' };
}

const result = await this.followModel
.create({ userId: follower, followId: following })
.then((result) => result.toObject());

return {
message: 'OK',
userId: result.userId,
followId: result.followId,
};
}

// input으로 들어온 유저를 언팔로우 함
// todo: unfollow 성공도 같은걸 (상태) 반환해서 이름 다시 지어야함
async unFollowUser(
followerId: number,
followingLogin: string,
): Promise<typeof FollowResult> {
const follower = await this.cursusUserService
.findOneAndLean({
filter: { 'user.id': followerId },
})
.then((follower) => follower?.user.id);

const following = await this.cursusUserService
.findOneAndLean({
filter: { 'user.login': followingLogin },
})
.then((following) => following?.user.id);

if (!follower || !following || follower === following) {
return { message: 'fail' };
}

const deletedCount = await this.followModel
.deleteOne({
userId: follower,
followId: following,
})
.then((result) => result.deletedCount);

if (deletedCount === 1) {
return {
message: 'OK',
userId: follower,
followId: following,
};
} else {
return {
message: 'fail',
};
}
}

// input 유저 <- 팔로워 목록을 찾아옴
// getFollowerList("yeju") -> yeju를 팔로우 하는 사람들
async getFollowerList(login: string): Promise<FollowListByMe[]> {
//login이 A<-B 의 A위치에 있는거 find 후 B들의 UserPreview로 합쳐서 반환

return [];
}

// input 유저 -> 팔로잉 목록을 찾아옴
// getFollowingList("yeju") -> yeju(target)가 팔로우 하는 사람들
async getFollowingList(
me: number,
target: string,
): Promise<FollowListByMe[]> {
//target의 id
const targetId = await this.cursusUserService
.findOneAndLean({
filter: { 'user.login': target },
})
.then((user) => user?.user.id);

//target이 팔로우 하는 사람들
const following: follow[] = await this.followModel.find({
userId: targetId,
});

const targetFollowingUserPreview: Promise<UserPreview>[] = following.map(
async (following) => {
//target이 팔로우 하는 사람의 preview
const user = await this.cursusUserService
.findAllUserPreviewAndLean({
filter: { 'user.id': following.followId },
})
//findOne으로 바꾸기
.then((a) => a[0]);

return user;
},
);

const followListByMeArray: Promise<FollowListByMe>[] =
targetFollowingUserPreview.map(async (targetFollowingUser) => {
const user = await targetFollowingUser;
let follow: boolean = true;

const isFollowed = await this.followModel.find({
userId: me,
followId: user.id,
});

if (!isFollowed) {
follow = false;
}

return { follow, user };
});

return await Promise.all(followListByMeArray);
}

async getFollowerCount(login: string): Promise<number> {
const id = await this.cursusUserService.findOneAndLean({
filter: { 'user.login': login },
});

return await this.followModel.countDocuments({ followId: id?.user.id }); //login filter
}

async getFollowingCount(login: string): Promise<number> {
const id = await this.cursusUserService.findOneAndLean({
filter: { 'user.login': login },
});

return await this.followModel.countDocuments({ userId: id?.user.id }); //login filter
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@ import { Field, ObjectType, createUnionType } from '@nestjs/graphql';
import { UserPreview } from 'src/common/models/common.user.model';

@ObjectType()
export class UserList {
export class FollowListByMe {
@Field()
user: UserPreview[];
follow: boolean;

@Field()
user: UserPreview;
}

@ObjectType()
export class FollowUserList {
@Field((_type) => [FollowListByMe])
followUser: FollowListByMe[];

@Field()
count: number;
Expand All @@ -28,8 +37,8 @@ export class FollowSuccess {
followId: number;
}

export const LoginResult = createUnionType({
name: 'LoginResult',
export const FollowResult = createUnionType({
name: 'FollowResult',
types: () => [FollowSuccess, FollowFail] as const,
resolveType(value) {
switch (value.message) {
Expand Down
Loading

0 comments on commit a2dd812

Please sign in to comment.