From def3c0ca93bde7a654aaf44427ff352ffd2c169d Mon Sep 17 00:00:00 2001 From: Kristaps Fabians Geikins Date: Tue, 24 Sep 2024 14:27:25 +0300 Subject: [PATCH] chore(server): comments IoC 14 - getPaginatedCommitCommentsFactory --- .../modules/comments/domain/operations.ts | 31 ++++- .../comments/graph/resolvers/comments.ts | 10 +- .../modules/comments/repositories/comments.ts | 129 +++++++++--------- .../modules/comments/services/retrieval.ts | 34 +++-- 4 files changed, 124 insertions(+), 80 deletions(-) diff --git a/packages/server/modules/comments/domain/operations.ts b/packages/server/modules/comments/domain/operations.ts index 84d055def..4d04ec840 100644 --- a/packages/server/modules/comments/domain/operations.ts +++ b/packages/server/modules/comments/domain/operations.ts @@ -14,7 +14,7 @@ import { } from '@/modules/core/graph/generated/graphql' import { SmartTextEditorValueSchema } from '@/modules/core/services/richTextEditorService' import { MarkNullableOptional, Optional } from '@/modules/shared/helpers/typeHelper' -import { SpeckleViewer } from '@speckle/shared' +import { MaybeNullOrUndefined, SpeckleViewer } from '@speckle/shared' import { Knex } from 'knex' import { Merge } from 'type-fest' @@ -66,6 +66,17 @@ export type GetCommentsResources = (commentIds: string[]) => Promise<{ } }> +export type GetPaginatedCommitCommentsPage = ( + params: PaginatedCommitCommentsParams +) => Promise<{ + items: CommentRecord[] + cursor: string | null +}> + +export type GetPaginatedCommitCommentsTotalCount = ( + params: Omit +) => Promise + export type CheckStreamResourcesAccess = (params: { streamId: string resources: ResourceIdentifier[] @@ -124,3 +135,21 @@ export type ArchiveCommentAndNotify = ( userId: string, archived?: boolean ) => Promise> + +export type PaginatedCommitCommentsParams = { + commitId: string + limit: number + cursor?: MaybeNullOrUndefined + filter?: MaybeNullOrUndefined<{ + threadsOnly: boolean + includeArchived: boolean + }> +} + +export type GetPaginatedCommitComments = ( + params: PaginatedCommitCommentsParams +) => Promise<{ + totalCount: number + items: CommentRecord[] + cursor: string | null +}> diff --git a/packages/server/modules/comments/graph/resolvers/comments.ts b/packages/server/modules/comments/graph/resolvers/comments.ts index f2cf8e6a3..ac8274a90 100644 --- a/packages/server/modules/comments/graph/resolvers/comments.ts +++ b/packages/server/modules/comments/graph/resolvers/comments.ts @@ -15,6 +15,8 @@ import { getCommentFactory, getCommentsLegacyFactory, getCommentsResourcesFactory, + getPaginatedCommitCommentsPageFactory, + getPaginatedCommitCommentsTotalCountFactory, getResourceCommentCountFactory, insertCommentLinksFactory, insertCommentsFactory, @@ -32,8 +34,8 @@ import { SmartTextEditorValueSchema } from '@/modules/core/services/richTextEditorService' import { - getPaginatedCommitComments, getPaginatedBranchComments, + getPaginatedCommitCommentsFactory, getPaginatedProjectComments } from '@/modules/comments/services/retrieval' import { @@ -205,6 +207,12 @@ const archiveCommentAndNotify = archiveCommentAndNotifyFactory({ updateComment, addCommentArchivedActivity }) +const getPaginatedCommitComments = getPaginatedCommitCommentsFactory({ + getPaginatedCommitCommentsPage: getPaginatedCommitCommentsPageFactory({ db }), + getPaginatedCommitCommentsTotalCount: getPaginatedCommitCommentsTotalCountFactory({ + db + }) +}) const getStreamComment = async ( { streamId, commentId }: { streamId: string; commentId: string }, diff --git a/packages/server/modules/comments/repositories/comments.ts b/packages/server/modules/comments/repositories/comments.ts index 2f6d87bdd..497422bb2 100644 --- a/packages/server/modules/comments/repositories/comments.ts +++ b/packages/server/modules/comments/repositories/comments.ts @@ -37,14 +37,21 @@ import { DeleteComment, GetComment, GetCommentsResources, + GetPaginatedCommitCommentsPage, + GetPaginatedCommitCommentsTotalCount, InsertCommentLinks, InsertCommentPayload, InsertComments, MarkCommentUpdated, MarkCommentViewed, + PaginatedCommitCommentsParams, UpdateComment } from '@/modules/comments/domain/operations' -import { ObjectRecord, StreamCommitRecord } from '@/modules/core/helpers/types' +import { + CommitRecord, + ObjectRecord, + StreamCommitRecord +} from '@/modules/core/helpers/types' import { ExtendedComment } from '@/modules/comments/domain/types' const tables = { @@ -52,7 +59,8 @@ const tables = { objects: (db: Knex) => db(Objects.name), comments: (db: Knex) => db(Comments.name), commentLinks: (db: Knex) => db(CommentLinks.name), - commentViews: (db: Knex) => db(CommentViews.name) + commentViews: (db: Knex) => db(CommentViews.name), + commits: (db: Knex) => db(Commits.name) } export const generateCommentId = () => crs({ length: 10 }) @@ -335,78 +343,71 @@ export async function getCommentReplyAuthorIds( ) } -export type PaginatedCommitCommentsParams = { - commitId: string - limit: number - cursor?: MaybeNullOrUndefined - filter?: MaybeNullOrUndefined<{ - threadsOnly: boolean - includeArchived: boolean - }> -} +const getPaginatedCommitCommentsBaseQueryFactory = + (deps: { db: Knex }) => + ( + params: Omit + ) => { + const { commitId, filter } = params -function getPaginatedCommitCommentsBaseQuery( - params: Omit -) { - const { commitId, filter } = params + const q = tables + .commits(deps.db) + .select(Comments.cols) + .innerJoin(CommentLinks.name, function () { + this.on(CommentLinks.col.resourceId, Commits.col.id).andOnVal( + CommentLinks.col.resourceType, + 'commit' as CommentLinkResourceType + ) + }) + .innerJoin(Comments.name, Comments.col.id, CommentLinks.col.commentId) + .where(Commits.col.id, commitId) - const q = Commits.knex() - .select(Comments.cols) - .innerJoin(CommentLinks.name, function () { - this.on(CommentLinks.col.resourceId, Commits.col.id).andOnVal( - CommentLinks.col.resourceType, - 'commit' as CommentLinkResourceType - ) - }) - .innerJoin(Comments.name, Comments.col.id, CommentLinks.col.commentId) - .where(Commits.col.id, commitId) + if (!filter?.includeArchived) { + q.andWhere(Comments.col.archived, false) + } - if (!filter?.includeArchived) { - q.andWhere(Comments.col.archived, false) + if (filter?.threadsOnly) { + q.whereNull(Comments.col.parentComment) + } + + return q } - if (filter?.threadsOnly) { - q.whereNull(Comments.col.parentComment) +export const getPaginatedCommitCommentsPageFactory = + (deps: { db: Knex }): GetPaginatedCommitCommentsPage => + async (params: PaginatedCommitCommentsParams) => { + const { cursor } = params + + const limit = clamp(params.limit, 0, 100) + if (!limit) return { items: [], cursor: null } + + const q = getPaginatedCommitCommentsBaseQueryFactory(deps)(params) + .orderBy(Comments.col.createdAt, 'desc') + .limit(limit) + + if (cursor) { + q.andWhere(Comments.col.createdAt, '<', decodeCursor(cursor)) + } + + const items = await q + return { + items, + cursor: items.length + ? encodeCursor(items[items.length - 1].createdAt.toISOString()) + : null + } } - return q -} +export const getPaginatedCommitCommentsTotalCountFactory = + (deps: { db: Knex }): GetPaginatedCommitCommentsTotalCount => + async (params: Omit) => { + const baseQ = getPaginatedCommitCommentsBaseQueryFactory(deps)(params) + const q = knex.count<{ count: string }[]>().from(baseQ.as('sq1')) + const [row] = await q -export async function getPaginatedCommitComments( - params: PaginatedCommitCommentsParams -) { - const { cursor } = params - - const limit = clamp(params.limit, 0, 100) - if (!limit) return { items: [], cursor: null } - - const q = getPaginatedCommitCommentsBaseQuery(params) - .orderBy(Comments.col.createdAt, 'desc') - .limit(limit) - - if (cursor) { - q.andWhere(Comments.col.createdAt, '<', decodeCursor(cursor)) + return parseInt(row.count || '0') } - const items = await q - return { - items, - cursor: items.length - ? encodeCursor(items[items.length - 1].createdAt.toISOString()) - : null - } -} - -export async function getPaginatedCommitCommentsTotalCount( - params: Omit -) { - const baseQ = getPaginatedCommitCommentsBaseQuery(params) - const q = knex.count<{ count: string }[]>().from(baseQ.as('sq1')) - const [row] = await q - - return parseInt(row.count || '0') -} - export type PaginatedBranchCommentsParams = { branchId: string limit: number diff --git a/packages/server/modules/comments/services/retrieval.ts b/packages/server/modules/comments/services/retrieval.ts index e1bac8bfe..807fbeb29 100644 --- a/packages/server/modules/comments/services/retrieval.ts +++ b/packages/server/modules/comments/services/retrieval.ts @@ -1,8 +1,5 @@ import { Optional } from '@speckle/shared' import { - PaginatedCommitCommentsParams, - getPaginatedCommitComments as getPaginatedCommitCommentsDb, - getPaginatedCommitCommentsTotalCount, PaginatedBranchCommentsParams, getPaginatedBranchComments as getPaginatedBranchCommentsDb, getPaginatedBranchCommentsTotalCount, @@ -13,20 +10,29 @@ import { } from '@/modules/comments/repositories/comments' import { getBranchLatestCommits } from '@/modules/core/repositories/branches' import { isUndefined } from 'lodash' +import { + GetPaginatedCommitComments, + GetPaginatedCommitCommentsPage, + GetPaginatedCommitCommentsTotalCount, + PaginatedCommitCommentsParams +} from '@/modules/comments/domain/operations' -export async function getPaginatedCommitComments( - params: PaginatedCommitCommentsParams -) { - const [result, totalCount] = await Promise.all([ - getPaginatedCommitCommentsDb(params), - getPaginatedCommitCommentsTotalCount(params) - ]) +export const getPaginatedCommitCommentsFactory = + (deps: { + getPaginatedCommitCommentsPage: GetPaginatedCommitCommentsPage + getPaginatedCommitCommentsTotalCount: GetPaginatedCommitCommentsTotalCount + }): GetPaginatedCommitComments => + async (params: PaginatedCommitCommentsParams) => { + const [result, totalCount] = await Promise.all([ + deps.getPaginatedCommitCommentsPage(params), + deps.getPaginatedCommitCommentsTotalCount(params) + ]) - return { - ...result, - totalCount + return { + ...result, + totalCount + } } -} export async function getPaginatedBranchComments( params: PaginatedBranchCommentsParams