chore(server): comments IoC 14 - getPaginatedCommitCommentsFactory

This commit is contained in:
Kristaps Fabians Geikins
2024-09-24 14:27:25 +03:00
parent be7c3a6021
commit def3c0ca93
4 changed files with 124 additions and 80 deletions
@@ -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<PaginatedCommitCommentsParams, 'limit' | 'cursor'>
) => Promise<number>
export type CheckStreamResourcesAccess = (params: {
streamId: string
resources: ResourceIdentifier[]
@@ -124,3 +135,21 @@ export type ArchiveCommentAndNotify = (
userId: string,
archived?: boolean
) => Promise<Optional<CommentRecord>>
export type PaginatedCommitCommentsParams = {
commitId: string
limit: number
cursor?: MaybeNullOrUndefined<string>
filter?: MaybeNullOrUndefined<{
threadsOnly: boolean
includeArchived: boolean
}>
}
export type GetPaginatedCommitComments = (
params: PaginatedCommitCommentsParams
) => Promise<{
totalCount: number
items: CommentRecord[]
cursor: string | null
}>
@@ -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 },
@@ -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<ObjectRecord>(Objects.name),
comments: (db: Knex) => db<CommentRecord>(Comments.name),
commentLinks: (db: Knex) => db<CommentLinkRecord>(CommentLinks.name),
commentViews: (db: Knex) => db<CommentViewRecord>(CommentViews.name)
commentViews: (db: Knex) => db<CommentViewRecord>(CommentViews.name),
commits: (db: Knex) => db<CommitRecord>(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<string>
filter?: MaybeNullOrUndefined<{
threadsOnly: boolean
includeArchived: boolean
}>
}
const getPaginatedCommitCommentsBaseQueryFactory =
(deps: { db: Knex }) =>
<T = CommentRecord[]>(
params: Omit<PaginatedCommitCommentsParams, 'limit' | 'cursor'>
) => {
const { commitId, filter } = params
function getPaginatedCommitCommentsBaseQuery<T = CommentRecord[]>(
params: Omit<PaginatedCommitCommentsParams, 'limit' | 'cursor'>
) {
const { commitId, filter } = params
const q = tables
.commits(deps.db)
.select<T>(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<T>(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<PaginatedCommitCommentsParams, 'limit' | 'cursor'>) => {
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<PaginatedCommitCommentsParams, 'limit' | 'cursor'>
) {
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
@@ -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