Skip to content

Commit

Permalink
refactor: ♻️ pagination cursor base -> index base
Browse files Browse the repository at this point in the history
  • Loading branch information
niamu01 committed Feb 20, 2024
1 parent 7f5667c commit f268b91
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 150 deletions.
4 changes: 2 additions & 2 deletions app/src/follow/dto/follow.dto.getFollowList.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ArgsType, Field, registerEnumType } from '@nestjs/graphql';
import { PaginationCursorArgs } from 'src/pagination/cursor/dtos/pagination.cursor.dto';
import { PaginationIndexArgs } from 'src/pagination/index/dtos/pagination.index.dto.args';

export enum FollowSortOrder {
FOLLOW_AT_ASC,
Expand All @@ -9,7 +9,7 @@ export enum FollowSortOrder {
registerEnumType(FollowSortOrder, { name: 'FollowSortOrder' });

@ArgsType()
export class FollowListPaginatedArgs extends PaginationCursorArgs {
export class FollowListPaginatedArgs extends PaginationIndexArgs {
@Field()
target: string;

Expand Down
4 changes: 2 additions & 2 deletions app/src/follow/follow.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CursusUserModule } from 'src/api/cursusUser/cursusUser.module';
import { PaginationCursorModule } from 'src/pagination/cursor/pagination.cursor.module';
import { PaginationIndexModule } from 'src/pagination/index/pagination.index.module';
import { FollowSchema, follow } from './db/follow.database.schema';
import { FollowResolver } from './follow.resolver';
import { FollowService } from './follow.service';
Expand All @@ -10,7 +10,7 @@ import { FollowService } from './follow.service';
imports: [
MongooseModule.forFeature([{ name: follow.name, schema: FollowSchema }]),
CursusUserModule,
PaginationCursorModule,
PaginationIndexModule,
],
providers: [FollowResolver, FollowService],
})
Expand Down
11 changes: 2 additions & 9 deletions app/src/follow/follow.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,9 @@ import { PubSub } from 'graphql-subscriptions';
import { MyUserId } from 'src/auth/myContext';
import { StatAuthGuard } from 'src/auth/statAuthGuard';
import { HttpExceptionFilter } from 'src/http-exception.filter';
import {
FollowListPaginatedArgs,
FollowSortOrder,
} from './dto/follow.dto.getFollowList';
import { FollowListPaginatedArgs } from './dto/follow.dto.getFollowList';
import { FollowService } from './follow.service';
import {
FollowListPaginated,
FollowListWithCount,
FollowResult,
} from './model/follow.model';
import { FollowListPaginated, FollowResult } from './model/follow.model';

const pubSub = new PubSub();

Expand Down
134 changes: 14 additions & 120 deletions app/src/follow/follow.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
import {
CursorExtractor,
FieldExtractor,
PaginationCursorService,
} from 'src/pagination/cursor/pagination.cursor.service';
import { PaginationIndexService } from 'src/pagination/index/pagination.index.service';
import { CursusUserService } from '../api/cursusUser/cursusUser.service';
import { follow } from './db/follow.database.schema';
import {
Expand All @@ -33,7 +33,7 @@ export class FollowService {
@InjectModel(follow.name)
private readonly followModel: Model<follow>,
private readonly cursusUserService: CursusUserService,
private readonly paginationCursorService: PaginationCursorService,
private readonly paginationIndexService: PaginationIndexService,
) {}

async findOneAndLean(
Expand Down Expand Up @@ -118,7 +118,6 @@ export class FollowService {
async followerList(
userId: number,
target: string,
limit: number,
sortOrder: FollowSortOrder,
filter?: FilterQuery<follow>,
): Promise<FollowList[]> {
Expand All @@ -134,7 +133,6 @@ export class FollowService {
filter: { followId: targetId },
select: { _id: 0, userId: 1 },
sort: followSort(sortOrder),
limit,
});

const followerUserPreview = await Promise.all(
Expand All @@ -157,61 +155,19 @@ export class FollowService {

async followerPaginated(
userId: number,
{ after, first, target, sortOrder }: FollowListPaginatedArgs,
{ pageNumber, pageSize, target, sortOrder }: FollowListPaginatedArgs,
): Promise<FollowListPaginated> {
const targetId = await this.userIdByLogin(target);

const totalCount = await this.followerCount(targetId);

const filter: FilterQuery<follow> = {};

if (after) {
const [id, _login]: FollowListCursorField =
this.paginationCursorService.toFields(after, fieldExtractor);

const followAt: Pick<follow, 'followAt'> | null =
await this.findOneAndLean({
filter: {
userId: id,
followId: targetId,
},
select: { _id: 0, followAt: 1 },
});

if (!followAt) {
return this.generateEmptyPage();
}

switch (sortOrder) {
case FollowSortOrder.FOLLOW_AT_ASC:
filter.$or = [{ followAt: { $gt: followAt.followAt } }];
break;
case FollowSortOrder.FOLLOW_AT_DESC:
filter.$or = [{ followAt: { $lt: followAt.followAt } }];
break;
}
}

const followList = await this.followerList(
userId,
target,
first + 1,
sortOrder,
filter,
);
const followList = await this.followerList(userId, target, sortOrder);

return this.paginationCursorService.toPaginated<FollowList>(
followList.slice(0, first),
totalCount,
followList.length > first,
cursorExtractor,
);
return this.paginationIndexService.toPaginated<FollowList>(followList, {
pageNumber,
pageSize,
});
}

async followingList(
userId: number,
target: string,
limit: number,
sortOrder: FollowSortOrder,
filter?: FilterQuery<follow>,
): Promise<FollowList[]> {
Expand All @@ -227,7 +183,6 @@ export class FollowService {
filter: { userId: targetId },
select: { _id: 0, followId: 1 },
sort: followSort(sortOrder),
limit,
});

const followingUserPreview = await Promise.all(
Expand All @@ -250,55 +205,14 @@ export class FollowService {

async followingPaginated(
userId: number,
{ after, first, target, sortOrder }: FollowListPaginatedArgs,
{ pageNumber, pageSize, target, sortOrder }: FollowListPaginatedArgs,
): Promise<FollowListPaginated> {
const targetId = await this.userIdByLogin(target);
const followList = await this.followingList(userId, target, sortOrder);

const totalCount = await this.followingCount(targetId);

const filter: FilterQuery<follow> = {};

if (after) {
const [id, _login]: FollowListCursorField =
this.paginationCursorService.toFields(after, fieldExtractor);

const followAt: Pick<follow, 'followAt'> | null =
await this.findOneAndLean({
filter: {
userId: targetId,
followId: id,
},
select: { _id: 0, followAt: 1 },
});

if (!followAt) {
return this.generateEmptyPage();
}

switch (sortOrder) {
case FollowSortOrder.FOLLOW_AT_ASC:
filter.$or = [{ followAt: { $gt: followAt.followAt } }];
break;
case FollowSortOrder.FOLLOW_AT_DESC:
filter.$or = [{ followAt: { $lt: followAt.followAt } }];
break;
}
}

const followList = await this.followingList(
userId,
target,
first + 1,
sortOrder,
filter,
);

return this.paginationCursorService.toPaginated<FollowList>(
followList.slice(0, first),
totalCount,
followList.length > first,
cursorExtractor,
);
return this.paginationIndexService.toPaginated<FollowList>(followList, {
pageSize,
pageNumber,
});
}

async followerCount(
Expand Down Expand Up @@ -334,28 +248,8 @@ export class FollowService {

return await Promise.all(followList);
}

private generateEmptyPage(): FollowListPaginated {
return this.paginationCursorService.toPaginated<FollowList>(
[],
0,
false,
cursorExtractor,
);
}
}

const cursorExtractor: CursorExtractor<FollowList> = (doc) =>
doc.user.id.toString() + '_' + doc.user.login.toString();

const fieldExtractor: FieldExtractor<FollowListCursorField> = (
cursor: string,
) => {
const [idString, loginString] = cursor.split('_');

return [parseInt(idString), loginString];
};

const followSort = (sortOrder: FollowSortOrder): Record<string, SortOrder> => {
switch (sortOrder) {
case FollowSortOrder.FOLLOW_AT_ASC:
Expand Down
4 changes: 2 additions & 2 deletions app/src/follow/model/follow.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Field, ObjectType, createUnionType } from '@nestjs/graphql';
import { UserPreview } from 'src/common/models/common.user.model';
import { CursorPaginated } from 'src/pagination/cursor/models/pagination.cursor.model';
import { IndexPaginated } from 'src/pagination/index/models/pagination.index.model';

@ObjectType()
export class FollowList {
Expand All @@ -12,7 +12,7 @@ export class FollowList {
}

@ObjectType()
export class FollowListPaginated extends CursorPaginated(FollowList) {}
export class FollowListPaginated extends IndexPaginated(FollowList) {}

@ObjectType()
export class FollowListWithCount {
Expand Down
27 changes: 12 additions & 15 deletions app/src/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,16 @@ type UserRankingIndexPaginated {
pageNumber: Int!
}

type CursorPageInfo {
totalCount: Int!
hasNextPage: Boolean!
endCursor: String
}

type FollowList {
isFollowing: Boolean
user: UserPreview!
}

type FollowListEdge {
cursor: String!
node: FollowList!
}

type FollowListPaginated {
edges: [FollowListEdge!]!
pageInfo: CursorPageInfo!
nodes: [FollowList!]!
totalCount: Int!
pageSize: Int!
pageNumber: Int!
}

type LinkableAccount {
Expand Down Expand Up @@ -113,6 +104,12 @@ type ProjectPreview {
difficulty: Int
}

type CursorPageInfo {
totalCount: Int!
hasNextPage: Boolean!
endCursor: String
}

type TeamPreview {
id: Int!
name: String!
Expand Down Expand Up @@ -637,8 +634,8 @@ type Query {
getSetting: Setting!
getExpTable: [ExpTable!]!
getIsFollowing(targetId: Int!): Boolean!
getFollowerPaginated(after: String, first: Int! = 20, target: String!, sortOrder: FollowSortOrder! = FOLLOW_AT_DESC): FollowListPaginated!
getFollowingPaginated(after: String, first: Int! = 20, target: String!, sortOrder: FollowSortOrder! = FOLLOW_AT_DESC): FollowListPaginated!
getFollowerPaginated(pageSize: Int! = 10, pageNumber: Int! = 1, target: String!, sortOrder: FollowSortOrder! = FOLLOW_AT_DESC): FollowListPaginated!
getFollowingPaginated(pageSize: Int! = 10, pageNumber: Int! = 1, target: String!, sortOrder: FollowSortOrder! = FOLLOW_AT_DESC): FollowListPaginated!
}

enum EvalLogSortOrder {
Expand Down

0 comments on commit f268b91

Please sign in to comment.