From 0616692df25286fd0ea1712aed39a7a666017477 Mon Sep 17 00:00:00 2001 From: Viet Nguyen <3805254+vnugent@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:05:34 -0800 Subject: [PATCH] feat: add ticks field to climb query (#431) - feat: add user public profile to tick query - feat: add ticks field to climb query - fix: getTicksByUserId and climb id returns results by climbed date (most recent first) --- src/graphql/resolvers.ts | 11 +++++++++-- src/graphql/schema/Climb.gql | 3 +++ src/graphql/schema/Tick.gql | 3 +++ src/graphql/tick/TickQueries.ts | 2 +- src/graphql/tick/TickResolvers.ts | 12 ++++++++++++ src/graphql/tick/index.ts | 3 ++- src/model/TickDataSource.ts | 9 +++++++-- src/model/__tests__/ticks.ts | 2 +- 8 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 src/graphql/tick/TickResolvers.ts diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index 45999ffd..76698da5 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -15,7 +15,7 @@ import { MediaMutations, MediaQueries, MediaResolvers } from './media/index.js' import { AreaMutations, AreaQueries } from './area/index.js' import { ClimbMutations } from './climb/index.js' import { OrganizationMutations, OrganizationQueries } from './organization/index.js' -import { TickMutations, TickQueries } from './tick/index.js' +import { TickMutations, TickQueries, TickResolvers } from './tick/index.js' import { UserMutations, UserQueries, UserResolvers } from './user/index.js' import { getAuthorMetadataFromBaseNode } from '../db/utils/index.js' import { geojsonPointToLatitude, geojsonPointToLongitude } from '../utils/helpers.js' @@ -118,6 +118,7 @@ const resolvers = { ...MediaResolvers, ...HistoryFieldResolvers, ...UserResolvers, + ...TickResolvers, JSONObject: GraphQLJSONObject, Climb: { @@ -188,7 +189,13 @@ const resolvers = { } : node.content, - authorMetadata: getAuthorMetadataFromBaseNode + authorMetadata: getAuthorMetadataFromBaseNode, + + ticks: async (node: ClimbGQLQueryType, _: any, { dataSources }: GQLContext) => { + const { ticks } = dataSources + return await ticks.ticksByUserIdAndClimb(node._id.toUUID().toString()) + } + }, Area: { diff --git a/src/graphql/schema/Climb.gql b/src/graphql/schema/Climb.gql index ffa96efd..c81a681d 100644 --- a/src/graphql/schema/Climb.gql +++ b/src/graphql/schema/Climb.gql @@ -67,6 +67,9 @@ type Climb { "Metadata about creation & update of this climb" authorMetadata: AuthorMetadata! + + "User ticks of this climb" + ticks: [TickType] } type ClimbMetadata { diff --git a/src/graphql/schema/Tick.gql b/src/graphql/schema/Tick.gql index b03b8649..002323e5 100644 --- a/src/graphql/schema/Tick.gql +++ b/src/graphql/schema/Tick.gql @@ -104,6 +104,9 @@ type TickType { """ grade: String source: TickSource + + """User public profile""" + user: UserPublicProfile! } "The tick sources that openbeta supports." diff --git a/src/graphql/tick/TickQueries.ts b/src/graphql/tick/TickQueries.ts index f4352d96..fa18d9e4 100644 --- a/src/graphql/tick/TickQueries.ts +++ b/src/graphql/tick/TickQueries.ts @@ -9,7 +9,7 @@ const TickQueries = { userTicksByClimbId: async (_, input, { dataSources }): Promise => { const { ticks }: { ticks: TickDataSource } = dataSources const { climbId, userId } = input - return await ticks.ticksByUserIdAndClimb(userId, climbId) + return await ticks.ticksByUserIdAndClimb(climbId, userId) } } diff --git a/src/graphql/tick/TickResolvers.ts b/src/graphql/tick/TickResolvers.ts new file mode 100644 index 00000000..62242fbe --- /dev/null +++ b/src/graphql/tick/TickResolvers.ts @@ -0,0 +1,12 @@ +import muuid from 'uuid-mongodb' +import { TickType } from '../../db/TickTypes.js' +import { GQLContext } from '../../types.js' + +export const TickResolvers = { + TickType: { + user: async (node: TickType, args: any, { dataSources }: GQLContext) => { + const { users } = dataSources + return await users.getUserPublicProfileByUuid(muuid.from(node.userId)) + } + } +} diff --git a/src/graphql/tick/index.ts b/src/graphql/tick/index.ts index 234ac9d8..d0accc87 100644 --- a/src/graphql/tick/index.ts +++ b/src/graphql/tick/index.ts @@ -1,4 +1,5 @@ import TickMutations from './TickMutations.js' import TickQueries from './TickQueries.js' +import { TickResolvers } from './TickResolvers.js' -export { TickMutations, TickQueries } +export { TickMutations, TickQueries, TickResolvers } diff --git a/src/model/TickDataSource.ts b/src/model/TickDataSource.ts index 6cbdc851..0444a04b 100644 --- a/src/model/TickDataSource.ts +++ b/src/model/TickDataSource.ts @@ -106,8 +106,13 @@ export default class TickDataSource extends MongoDataSource { return await this.tickModel.find({ userId: userIdObject._id.toUUID().toString() }) } - async ticksByUserIdAndClimb (userId: string, climbId: string): Promise { - return await this.tickModel.find({ userId, climbId }) + /** + * Get all ticks by climb uuid and optional user uuid + * @param userId Optional user uuid + * @param climbId climb uuid + */ + async ticksByUserIdAndClimb (climbId: string, userId?: string): Promise { + return await this.tickModel.find({ ...(userId != null && { userId }), climbId }).sort({ dateClimbed: -1 }).lean() } static instance: TickDataSource diff --git a/src/model/__tests__/ticks.ts b/src/model/__tests__/ticks.ts index 7c934b67..6140f927 100644 --- a/src/model/__tests__/ticks.ts +++ b/src/model/__tests__/ticks.ts @@ -156,7 +156,7 @@ describe('Ticks', () => { if (tick == null || tick2 == null) { fail('Should add a new tick') } - const userClimbTicks = await ticks.ticksByUserIdAndClimb(userId.toUUID().toString(), climbId) + const userClimbTicks = await ticks.ticksByUserIdAndClimb(climbId, userId.toUUID().toString()) expect(userClimbTicks.length).toEqual(1) })