diff --git a/src/components/follow/hooks/useInfiniteFollowInfo.ts b/src/components/follow/hooks/useInfiniteFollowInfo.ts new file mode 100644 index 0000000..7fa9999 --- /dev/null +++ b/src/components/follow/hooks/useInfiniteFollowInfo.ts @@ -0,0 +1,53 @@ +import { + CancelablePromise, + FollowInfoRequestDto, + FollowInfoResponseDto, + FollowService, +} from "@/wrapper/server"; +import { + keepPreviousData, + useInfiniteQuery, + useQuery, + useQueryClient, +} from "@tanstack/react-query"; +import { ExtendedUseInfiniteQueryResult } from "@/util/types/ExtendedUseQueryResult"; + +export function useInfiniteFollowInfo( + dto: Omit, +): ExtendedUseInfiniteQueryResult { + const limit = dto.limit || 10; + const queryClient = useQueryClient(); + const queryKey = ["user", "follow", "info", dto]; + const invalidate = () => { + queryClient.invalidateQueries({ + queryKey, + }); + queryClient.resetQueries({ + queryKey, + }); + }; + return { + ...useInfiniteQuery({ + queryKey, + queryFn: async ({ pageParam }) => { + return FollowService.followControllerGetFollowInfo({ + ...dto, + offset: pageParam, + }) as CancelablePromise; + }, + initialPageParam: 0, + getNextPageParam: ( + lastPage, + allPages, + lastPageParam, + allPageParams, + ) => { + return limit + lastPageParam; + }, + placeholderData: keepPreviousData, + staleTime: Infinity, + }), + invalidate, + queryKey, + }; +} diff --git a/src/components/follow/input/UserFollowActions.tsx b/src/components/follow/input/UserFollowActions.tsx new file mode 100644 index 0000000..db671ca --- /dev/null +++ b/src/components/follow/input/UserFollowActions.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import useUserId from "@/components/auth/hooks/useUserId"; +import { useFollowStatus } from "@/components/follow/hooks/useFollowStatus"; +import { useMutation } from "@tanstack/react-query"; +import { FollowInfoRequestDto, FollowService } from "@/wrapper/server"; +import { useInfiniteFollowInfo } from "@/components/follow/hooks/useInfiniteFollowInfo"; +import criteria = FollowInfoRequestDto.criteria; +import { ActionIcon, Button, Group, Tooltip } from "@mantine/core"; +import { IconX } from "@tabler/icons-react"; + +interface Props { + targetUserId: string; + withUnfollowButton?: boolean; +} + +const UserFollowActions = ({ + targetUserId, + withUnfollowButton = true, +}: Props) => { + const ownUserId = useUserId(); + /* + Checks if current logged-in user is following target user + */ + const ownToTargetFollowStatus = useFollowStatus(ownUserId, targetUserId); + const isFollowing = ownToTargetFollowStatus.data?.isFollowing ?? false; + + const shouldShowFollowButton = + ownUserId != undefined && ownUserId !== targetUserId; + + const followMutation = useMutation({ + mutationFn: async (action: "register" | "remove") => { + if (action === "register") { + if (isFollowing) return; + + await FollowService.followControllerRegisterFollow({ + followedUserId: targetUserId, + }); + + return; + } + + await FollowService.followControllerRemoveFollow({ + followedUserId: targetUserId, + }); + }, + onSettled: () => { + ownToTargetFollowStatus.invalidate(); + }, + }); + + if (!shouldShowFollowButton) return null; + + return ( + + + {isFollowing && withUnfollowButton && ( + + { + followMutation.mutate("remove"); + }} + > + + + + )} + + ); +}; + +export default UserFollowActions; diff --git a/src/components/follow/input/UserFollowGroup.tsx b/src/components/follow/input/UserFollowGroup.tsx new file mode 100644 index 0000000..b2de6b8 --- /dev/null +++ b/src/components/follow/input/UserFollowGroup.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { Group, GroupProps } from "@mantine/core"; +import { UserAvatarGroup } from "@/components/general/input/UserAvatarGroup"; +import ProfileFollowActions from "@/components/profile/view/ProfileFollowActions"; +import UserFollowActions from "@/components/follow/input/UserFollowActions"; + +interface Props extends GroupProps { + userId: string; +} + +const UserFollowGroup = ({ userId, ...groupProps }: Props) => { + return ( + + + + + ); +}; + +export default UserFollowGroup; diff --git a/src/components/follow/list/FollowInfoList.tsx b/src/components/follow/list/FollowInfoList.tsx new file mode 100644 index 0000000..1bb0c94 --- /dev/null +++ b/src/components/follow/list/FollowInfoList.tsx @@ -0,0 +1,94 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { FollowInfoRequestDto, PaginationInfo } from "@/wrapper/server"; +import { Divider, Group, Skeleton, Stack, Text } from "@mantine/core"; +import { useInfiniteFollowInfo } from "@/components/follow/hooks/useInfiniteFollowInfo"; +import UserFollowGroup from "@/components/follow/input/UserFollowGroup"; +import { useIntersection } from "@mantine/hooks"; +import { TBasePaginationRequest } from "@/util/types/pagination"; + +interface Props { + criteria: FollowInfoRequestDto.criteria; + targetUserId: string; +} + +const DEFAULT_LIMIT = 10; + +const FollowInfoList = ({ criteria, targetUserId }: Props) => { + const { entry, ref } = useIntersection({ + threshold: 1, + root: document.getElementById(`${criteria}-intersection-root`), + }); + + const { data, fetchNextPage, isLoading, isFetching, isError } = + useInfiniteFollowInfo({ + criteria, + targetUserId, + limit: 10, + orderBy: { + createdAt: "DESC", + }, + }); + const items = useMemo(() => { + if (data == undefined) return null; + const userIds = data.pages.flatMap((response) => { + return response.data; + }); + return userIds.map((userId) => { + return ; + }); + }, [data]); + + const isEmpty = !isLoading && (items == undefined || items.length === 0); + + const buildItemsSkeletons = useCallback(() => { + return new Array(5).fill(0).map((v, i) => { + return ( + + + + + ); + }); + }, []); + + useEffect(() => { + const minimumIntersectionTime = 3000; + const lastElement = data?.pages[data?.pages.length - 1]; + const hasNextPage = lastElement?.pagination.hasNextPage ?? false; + const canFetchNextPage = + lastElement && hasNextPage && !isLoading && !isFetching && !isError; + + if ( + canFetchNextPage && + entry?.isIntersecting && + entry.time > minimumIntersectionTime + ) { + fetchNextPage().then(); + } + }, [ + entry, + isLoading, + isFetching, + isError, + fetchNextPage, + isEmpty, + data?.pages, + ]); + + return ( + + {isEmpty && ( + + {criteria === "following" + ? "User is not following anyone." + : "User has no followers."} + + )} + {items} + {(isLoading || isFetching) && buildItemsSkeletons()} + {!isEmpty &&
} + + ); +}; + +export default FollowInfoList; diff --git a/src/components/follow/modal/FollowInfoListModal.tsx b/src/components/follow/modal/FollowInfoListModal.tsx new file mode 100644 index 0000000..0e6070f --- /dev/null +++ b/src/components/follow/modal/FollowInfoListModal.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import { Modal, ScrollArea } from "@mantine/core"; +import { BaseModalProps } from "@/util/types/modal-props"; +import FollowInfoList from "@/components/follow/list/FollowInfoList"; +import { FollowInfoRequestDto } from "@/wrapper/server"; +import useUserProfile from "@/components/profile/hooks/useUserProfile"; +import CenteredLoading from "@/components/general/CenteredLoading"; + +interface Props extends BaseModalProps { + targetUserId: string; + criteria: FollowInfoRequestDto.criteria; +} + +const FollowInfoListModal = ({ + opened, + onClose, + targetUserId, + criteria, +}: Props) => { + const title = criteria === "followers" ? `Followers` : `Following`; + return ( + + + + + + + + ); +}; + +export default FollowInfoListModal; diff --git a/src/components/game/info/GameInfoScore.tsx b/src/components/game/info/GameInfoScore.tsx index 225ef20..618491a 100644 --- a/src/components/game/info/GameInfoScore.tsx +++ b/src/components/game/info/GameInfoScore.tsx @@ -43,7 +43,7 @@ const GameInfoScore = ({ gameId }: Props) => { const percentage = (v / total) * 100; const percentageToUse = Number.isNaN(percentage) ? 0 - : percentage; + : Math.trunc(percentage); const lastElement = index + 1 === arr.length; return ( { +const ProfileFollowActions = ({ + targetUserId, + withUnfollowButton = true, +}: Props) => { const ownUserId = useUserId(); /* Checks if current logged-in user is following target user */ const ownToTargetFollowStatus = useFollowStatus(ownUserId, targetUserId); const targetToOwnFollowStatus = useFollowStatus(targetUserId, ownUserId); - const followersCountQuery = useFollowersCount(targetUserId); const isFollowing = ownToTargetFollowStatus.data?.isFollowing ?? false; const isBeingFollowed = targetToOwnFollowStatus.data?.isFollowing ?? false; const isFollowedBack = isFollowing && isBeingFollowed; - const followMutation = useMutation({ - mutationFn: async (action: "register" | "unregister") => { - if (action === "register" && isFollowing) return; - if (action === "register") { - await FollowService.followControllerRegisterFollow({ - followedUserId: targetUserId, - }); - - return; - } - - await FollowService.followControllerRemoveFollow({ - followedUserId: targetUserId, - }); - }, - onSettled: () => { - followersCountQuery.invalidate(); - ownToTargetFollowStatus.invalidate(); - targetToOwnFollowStatus.invalidate(); - }, - }); - return ( - - - {isFollowing && ( - - { - followMutation.mutate("unregister"); - }} - > - - - - )} - - + {isBeingFollowed && !isFollowedBack && ( This user is following you. diff --git a/src/components/profile/view/ProfileUserInfo.tsx b/src/components/profile/view/ProfileUserInfo.tsx index 17143eb..f42f50a 100644 --- a/src/components/profile/view/ProfileUserInfo.tsx +++ b/src/components/profile/view/ProfileUserInfo.tsx @@ -1,30 +1,21 @@ -import React, { useMemo, useState } from "react"; -import { - Box, - Center, - Divider, - Group, - Overlay, - Paper, - Stack, - Text, - Title, -} from "@mantine/core"; +import React, { useMemo } from "react"; +import { Box, Divider, Group, Paper, Stack, Text, Title } from "@mantine/core"; import useUserProfile from "@/components/profile/hooks/useUserProfile"; import { UserAvatar } from "@/components/general/input/UserAvatar"; import useCollectionEntriesForUserId from "@/components/collection/collection-entry/hooks/useCollectionEntriesForUserId"; import useReviewsForUserId from "@/components/review/hooks/useReviewsForUserId"; -import Link from "next/link"; import UserLevelInfo from "@/components/user-level/UserLevelInfo"; import CenteredLoading from "@/components/general/CenteredLoading"; import { useAllObtainedAchievements } from "@/components/achievement/hooks/useAllObtainedAchievements"; -import AchievementItem from "@/components/achievement/AchievementItem"; import ObtainedAchievementItem from "@/components/achievement/ObtainedAchievementItem"; import { useUserLibrary } from "@/components/library/hooks/useUserLibrary"; import ProfileFollowActions from "@/components/profile/view/ProfileFollowActions"; -import { useFollowersCount } from "@/components/follow/hooks/useFollowersCount"; import useUserId from "@/components/auth/hooks/useUserId"; import TitleLink from "@/components/general/TitleLink"; +import { useInfiniteFollowInfo } from "@/components/follow/hooks/useInfiniteFollowInfo"; +import { FollowInfoRequestDto } from "@/wrapper/server"; +import ProfileUserInfoFollowInfo from "@/components/profile/view/ProfileUserInfoFollowInfo"; +import criteria = FollowInfoRequestDto.criteria; const dateFormatter = new Intl.DateTimeFormat(); @@ -37,7 +28,6 @@ const ProfileUserInfo = ({ userId }: Props) => { const libraryQuery = useUserLibrary(profileQuery.data?.userId); const collectionEntriesQuery = useCollectionEntriesForUserId(userId, 0, 1); const reviewsQuery = useReviewsForUserId(userId, 0, 1); - const followersCountQuery = useFollowersCount(userId); const obtainedAchievementsQuery = useAllObtainedAchievements(userId); const featuredAchievement = useMemo(() => { @@ -118,10 +108,15 @@ const ProfileUserInfo = ({ userId }: Props) => { - - Followers - {followersCountQuery.data} - + + + {shouldShowFollowActions && ( diff --git a/src/components/profile/view/ProfileUserInfoFollowInfo.tsx b/src/components/profile/view/ProfileUserInfoFollowInfo.tsx new file mode 100644 index 0000000..d56cda9 --- /dev/null +++ b/src/components/profile/view/ProfileUserInfoFollowInfo.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { FollowInfoRequestDto } from "@/wrapper/server"; +import { useDisclosure } from "@mantine/hooks"; +import { Group, Text, Title } from "@mantine/core"; +import { useInfiniteFollowInfo } from "@/components/follow/hooks/useInfiniteFollowInfo"; +import FollowInfoListModal from "@/components/follow/modal/FollowInfoListModal"; +import TitleLink from "@/components/general/TitleLink"; + +interface Props { + targetUserId: string; + criteria: FollowInfoRequestDto.criteria; +} + +const ProfileUserInfoFollowInfo = ({ targetUserId, criteria }: Props) => { + const [modalOpened, modalUtils] = useDisclosure(); + const followInfoQuery = useInfiniteFollowInfo({ + limit: 1, + criteria, + targetUserId, + }); + const totalItems = + followInfoQuery.data?.pages[0]?.pagination.totalItems || 0; + return ( + + + { + evt.preventDefault(); + modalUtils.open(); + }} + size={"h5"} + > + {criteria === "followers" ? "Followers" : "Following"} + + {totalItems} + + ); +}; + +export default ProfileUserInfoFollowInfo; diff --git a/src/wrapper/input/server_swagger.json b/src/wrapper/input/server_swagger.json index 09867a6..d1e3e9a 100644 --- a/src/wrapper/input/server_swagger.json +++ b/src/wrapper/input/server_swagger.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/v1/auth/logout":{"get":{"operationId":"AuthController_logout","parameters":[],"responses":{"200":{"description":""}},"tags":["auth"]}},"/v1/libraries":{"get":{"operationId":"LibrariesController_findOwn","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Library"}}}}},"tags":["libraries"]}},"/v1/libraries/{id}":{"get":{"operationId":"LibrariesController_findOneByIdWithPermissions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Library"}}}}},"tags":["libraries"]}},"/v1/collections/{id}":{"get":{"operationId":"CollectionsController_findOneByIdWithPermissions","summary":"","description":"Returns a collection which the user has access to\n\n(Either its own collection or a public one)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}}}},"tags":["collections"]},"patch":{"operationId":"CollectionsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollectionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["collections"]},"delete":{"operationId":"CollectionsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["collections"]}},"/v1/collections/library/{userId}":{"get":{"operationId":"CollectionsController_findAllByUserIdWithPermissions","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}}}}}},"tags":["collections"]}},"/v1/collections":{"post":{"operationId":"CollectionsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionDto"}}}},"responses":{"201":{"description":""}},"tags":["collections"]}},"/v1/reviews":{"post":{"operationId":"ReviewsController_createOrUpdate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReviewDto"}}}},"responses":{"201":{"description":""}},"tags":["reviews"]},"get":{"operationId":"ReviewsController_findOneByUserIdAndGameId","parameters":[{"name":"id","required":true,"in":"query","schema":{"type":"string"}},{"name":"gameId","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Review"}}}}},"tags":["reviews"]}},"/v1/reviews/all":{"post":{"operationId":"ReviewsController_findAllById","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindAllReviewsByIdDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Review"}}}}}},"tags":["reviews"]}},"/v1/reviews/score":{"get":{"operationId":"ReviewsController_getScoreForGameId","parameters":[{"name":"gameId","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewScoreResponseDto"}}}}},"tags":["reviews"]}},"/v1/reviews/profile/{userId}":{"get":{"operationId":"ReviewsController_findAllByUserId","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindReviewPaginatedDto"}}}}},"tags":["reviews"]}},"/v1/reviews/game/{id}":{"get":{"operationId":"ReviewsController_findAllByGameId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindReviewPaginatedDto"}}}}},"tags":["reviews"]}},"/v1/reviews/{id}":{"get":{"operationId":"ReviewsController_findOneById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Review"}}}}},"tags":["reviews"]},"delete":{"operationId":"ReviewsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["reviews"]}},"/v1/profile":{"patch":{"operationId":"ProfileController_update","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UpdateProfileDto"}}}},"responses":{"200":{"description":""}},"tags":["profile"]},"get":{"operationId":"ProfileController_findOwn","summary":"","description":"Used to access own profile","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}}},"tags":["profile"]}},"/v1/profile/{id}":{"get":{"operationId":"ProfileController_findOneById","summary":"","description":"Used to access other users' profiles","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}}},"tags":["profile"]}},"/v1/achievements":{"get":{"operationId":"AchievementsController_getAchievements","parameters":[{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedAchievementsResponseDto"}}}}},"tags":["achievements"]}},"/v1/achievements/obtained/{id}":{"get":{"operationId":"AchievementsController_getObtainedAchievement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"targetUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObtainedAchievement"}}}}},"tags":["achievements"]}},"/v1/achievements/obtained":{"get":{"operationId":"AchievementsController_getAllObtainedAchievements","parameters":[{"name":"targetUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ObtainedAchievement"}}}}}},"tags":["achievements"]}},"/v1/achievements/obtained/{id}/featured":{"put":{"operationId":"AchievementsController_updateFeaturedObtainedAchievement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFeaturedObtainedAchievementDto"}}}},"responses":{"200":{"description":""}},"tags":["achievements"]}},"/v1/level/{userId}":{"get":{"operationId":"LevelController_findOne","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLevel"}}}}},"tags":["level"]}},"/v1/collections-entries":{"post":{"operationId":"CollectionsEntriesController_createOrUpdate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionEntryDto"}}}},"responses":{"201":{"description":""}},"tags":["collections-entries"]}},"/v1/collections-entries/game/{id}":{"get":{"operationId":"CollectionsEntriesController_findOwnEntryByGameId","summary":"","description":"Returns a specific collection entry based on game ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntry"}}}},"400":{"description":"Invalid query"}},"tags":["collections-entries"]}},"/v1/collections-entries/{id}/platforms/icons":{"get":{"operationId":"CollectionsEntriesController_getIconsForOwnedPlatforms","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["collections-entries"]}},"/v1/collections-entries/{id}":{"delete":{"operationId":"CollectionsEntriesController_deleteOwnEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["collections-entries"]}},"/v1/collections-entries/game/{id}/favorite":{"post":{"operationId":"CollectionsEntriesController_changeFavoriteStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFavoriteStatusCollectionEntryDto"}}}},"responses":{"204":{"description":""}},"tags":["collections-entries"]}},"/v1/collections-entries/library/{id}":{"get":{"operationId":"CollectionsEntriesController_findAllByLibraryId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntriesPaginatedResponseDto"}}}}},"tags":["collections-entries"]}},"/v1/collections-entries/library/{id}/favorites":{"get":{"operationId":"CollectionsEntriesController_findFavoritesByLibraryId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntriesPaginatedResponseDto"}}}}},"tags":["collections-entries"]}},"/v1/collections-entries/collection/{id}":{"get":{"operationId":"CollectionsEntriesController_findAllByCollectionId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntriesPaginatedResponseDto"}}}}},"tags":["collections-entries"]}},"/v1/statistics/queue/like":{"post":{"operationId":"StatisticsQueueController_addLike","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsActionDto"}}}},"responses":{"201":{"description":""}},"tags":["statistics-queue"]},"delete":{"operationId":"StatisticsQueueController_removeLike","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsActionDto"}}}},"responses":{"200":{"description":""}},"tags":["statistics-queue"]}},"/v1/statistics/queue/view":{"post":{"operationId":"StatisticsQueueController_addView","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsActionDto"}}}},"responses":{"201":{"description":""}},"tags":["statistics-queue"]}},"/v1/statistics":{"post":{"operationId":"StatisticsController_findOneBySourceIdAndType","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindOneStatisticsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["statistics"]}},"/v1/statistics/trending/games":{"post":{"operationId":"StatisticsController_findTrendingGames","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindStatisticsTrendingGamesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameStatisticsPaginatedResponseDto"}}}}},"tags":["statistics"]}},"/v1/statistics/trending/reviews":{"post":{"operationId":"StatisticsController_findTrendingReviews","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindStatisticsTrendingReviewsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewStatisticsPaginatedResponseDto"}}}}},"tags":["statistics"]}},"/v1/statistics/status":{"get":{"operationId":"StatisticsController_getStatus","parameters":[{"name":"statisticsId","required":true,"in":"query","schema":{"type":"number"}},{"name":"sourceType","required":true,"in":"query","schema":{"enum":["game","review"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsStatus"}}}}},"tags":["statistics"]}},"/v1/notifications":{"get":{"operationId":"NotificationsController_findAllAndAggregate","parameters":[{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedNotificationAggregationDto"}}}}},"tags":["notifications"]}},"/v1/notifications/{id}/view":{"put":{"operationId":"NotificationsController_updateViewedStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationViewUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["notifications"]}},"/v1/game/repository/resource":{"get":{"operationId":"GameRepositoryController_getResource","parameters":[{"name":"resourceName","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["game-repository"]}},"/v1/game/repository/{id}/platforms/icon":{"get":{"operationId":"GameRepositoryController_getIconNamesForPlatformAbbreviations","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["game-repository"]}},"/v1/game/repository/{id}/external-stores":{"get":{"operationId":"GameRepositoryController_getExternalStoresForGameId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GameExternalStoreDto"}}}}}},"tags":["game-repository"]}},"/v1/game/repository/{id}":{"post":{"operationId":"GameRepositoryController_findOneById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameRepositoryFindOneDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Game"}}}}},"tags":["game-repository"]}},"/v1/game/repository":{"post":{"operationId":"GameRepositoryController_findAllByIds","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameRepositoryFindAllDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}}}}},"tags":["game-repository"]}},"/v1/sync/hltb/{gameId}":{"get":{"operationId":"HltbController_findPlaytimeForGameId","parameters":[{"name":"gameId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GamePlaytime"}}}}},"tags":["sync-hltb"]}},"/v1/health":{"get":{"operationId":"HealthController_health","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["health"]}},"/v1/activities/feed":{"get":{"operationId":"ActivitiesFeedController_buildActivitiesFeed","parameters":[{"name":"criteria","required":true,"in":"query","schema":{"enum":["following","trending","latest"],"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivitiesFeedPaginatedResponseDto"}}}}},"tags":["activities-feed"]}},"/v1/follow/status":{"get":{"operationId":"FollowController_getFollowerStatus","parameters":[{"name":"followerUserId","required":true,"in":"query","schema":{"type":"string"}},{"name":"followedUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowStatusDto"}}}}},"tags":["follow"]}},"/v1/follow/count":{"get":{"operationId":"FollowController_getFollowersCount","parameters":[{"name":"targetUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"number"}}}}},"tags":["follow"]}},"/v1/follow":{"post":{"operationId":"FollowController_registerFollow","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowRegisterDto"}}}},"responses":{"201":{"description":""}},"tags":["follow"]},"delete":{"operationId":"FollowController_removeFollow","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowRemoveDto"}}}},"responses":{"200":{"description":""}},"tags":["follow"]}}},"info":{"title":"GameNode API","description":"API docs for the videogame catalog system GameNode.

Built with love by the GameNode team.","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"Library":{"type":"object","properties":{"userId":{"type":"string","description":"@description The primary key of the library entity.\nAlso used to share the library with other users.\n\nSame as SuperTokens' userId."},"collections":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["userId","collections","createdAt","updatedAt"]},"GameCover":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["game","id"]},"GameCollection":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"slug":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"checksum":{"type":"string"},"url":{"type":"string"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}},"required":["id","name","slug","createdAt","updatedAt","checksum","url","games"]},"GameAlternativeName":{"type":"object","properties":{"id":{"type":"number"},"comment":{"type":"string"},"name":{"type":"string"},"checksum":{"type":"string"},"game":{"$ref":"#/components/schemas/Game"}},"required":["id","game"]},"GameArtwork":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["game","id"]},"GameScreenshot":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["game","id"]},"GameLocalization":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["game","id","createdAt","updatedAt"]},"GameMode":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["game","id","createdAt","updatedAt"]},"GameGenre":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["games","id","createdAt","updatedAt"]},"GameTheme":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","createdAt","updatedAt"]},"GamePlayerPerspective":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["games","id","createdAt","updatedAt"]},"GameEngineLogo":{"type":"object","properties":{"engine":{"$ref":"#/components/schemas/GameEngine"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["engine","id"]},"GameCompanyLogo":{"type":"object","properties":{"company":{"$ref":"#/components/schemas/GameCompany"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["company","id"]},"GameCompany":{"type":"object","properties":{"id":{"type":"number"},"changeDate":{"format":"date-time","type":"string"},"changeDateCategory":{"type":"string"},"changedCompany":{"$ref":"#/components/schemas/GameCompany"},"checksum":{"type":"string"},"country":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"logo":{"$ref":"#/components/schemas/GameCompanyLogo"},"name":{"type":"string"},"parent":{"$ref":"#/components/schemas/GameCompany"},"slug":{"type":"string"},"startDate":{"format":"date-time","type":"string"},"startDateCategory":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"url":{"type":"string"}},"required":["id","createdAt","name","slug","updatedAt"]},"GamePlatform":{"type":"object","properties":{"id":{"type":"number"},"abbreviation":{"type":"string"},"alternative_name":{"type":"string"},"category":{"type":"number","enum":[1,2,3,4,5,6]},"checksum":{"type":"string"},"generation":{"type":"number"},"name":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"collectionEntries":{"type":"array","items":{"$ref":"#/components/schemas/CollectionEntry"}}},"required":["id","abbreviation","alternative_name","category","checksum","generation","name","createdAt","updatedAt","games","collectionEntries"]},"GameEngine":{"type":"object","properties":{"logo":{"$ref":"#/components/schemas/GameEngineLogo"},"companies":{"type":"array","items":{"$ref":"#/components/schemas/GameCompany"}},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/GamePlatform"}},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["logo","companies","platforms","games","id","createdAt","updatedAt"]},"GameKeyword":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["game","id","createdAt","updatedAt"]},"GameFranchise":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["games","id","createdAt","updatedAt"]},"GameExternalGame":{"type":"object","properties":{"id":{"type":"number"},"uid":{"type":"string","description":"Corresponds to the game id on the target source (see GameExternalGameCategory).\nIt's called uid, not uuid."},"category":{"type":"number","enum":[1,5,10,11,13,14,15,20,22,23,26,28,29,30,31,32,36,37,54,55]},"media":{"type":"number","enum":[1,2]},"checksum":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"year":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"}},"required":["id","uid","createdAt","updatedAt","game","gameId"]},"GameInvolvedCompany":{"type":"object","properties":{"id":{"type":"number"},"checksum":{"type":"string"},"company":{"$ref":"#/components/schemas/GameCompany"},"companyId":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"developer":{"type":"boolean"},"porting":{"type":"boolean"},"publisher":{"type":"boolean"},"supporting":{"type":"boolean"},"updatedAt":{"format":"date-time","type":"string"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}},"required":["id","company","companyId","createdAt","developer","porting","publisher","supporting","updatedAt","games"]},"Game":{"type":"object","properties":{"id":{"type":"number","description":"Should be mapped to the IGDB ID of the game."},"name":{"type":"string"},"slug":{"type":"string"},"aggregatedRating":{"type":"number"},"aggregatedRatingCount":{"type":"number"},"category":{"enum":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],"type":"number"},"status":{"enum":[0,2,3,4,5,6,7,8],"type":"number"},"summary":{"type":"string"},"storyline":{"type":"string"},"checksum":{"type":"string"},"url":{"type":"string"},"firstReleaseDate":{"format":"date-time","type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"dlcs":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"dlcOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expansions":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expansionOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expandedGames":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expandedGameOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"similarGames":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"similarGameOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remakes":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remakeOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remasters":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remasterOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"cover":{"$ref":"#/components/schemas/GameCover"},"collection":{"$ref":"#/components/schemas/GameCollection"},"alternativeNames":{"type":"array","items":{"$ref":"#/components/schemas/GameAlternativeName"}},"artworks":{"type":"array","items":{"$ref":"#/components/schemas/GameArtwork"}},"screenshots":{"type":"array","items":{"$ref":"#/components/schemas/GameScreenshot"}},"gameLocalizations":{"type":"array","items":{"$ref":"#/components/schemas/GameLocalization"}},"gameModes":{"type":"array","items":{"$ref":"#/components/schemas/GameMode"}},"genres":{"type":"array","items":{"$ref":"#/components/schemas/GameGenre"}},"themes":{"type":"array","items":{"$ref":"#/components/schemas/GameTheme"}},"playerPerspectives":{"type":"array","items":{"$ref":"#/components/schemas/GamePlayerPerspective"}},"gameEngines":{"type":"array","items":{"$ref":"#/components/schemas/GameEngine"}},"keywords":{"type":"array","items":{"$ref":"#/components/schemas/GameKeyword"}},"franchises":{"type":"array","items":{"$ref":"#/components/schemas/GameFranchise"}},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/GamePlatform"}},"externalGames":{"type":"array","items":{"$ref":"#/components/schemas/GameExternalGame"}},"involvedCompanies":{"type":"array","items":{"$ref":"#/components/schemas/GameInvolvedCompany"}},"source":{"type":"string","description":"Oh dear maintainer, please forgive me for using transient fields.","default":"MYSQL","enum":["MYSQL","MANTICORE"]}},"required":["id","name","slug","category","status","summary","storyline","checksum","url","firstReleaseDate","createdAt","updatedAt","involvedCompanies","source"]},"ProfileAvatar":{"type":"object","properties":{"id":{"type":"number"},"mimetype":{"type":"string"},"extension":{"type":"string"},"size":{"type":"number"},"filename":{"type":"string"},"encoding":{"type":"string"},"profile":{"$ref":"#/components/schemas/Profile"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","mimetype","extension","size","filename","encoding","profile","createdAt","updatedAt"]},"UserFollow":{"type":"object","properties":{"id":{"type":"number"},"follower":{"$ref":"#/components/schemas/Profile"},"followed":{"$ref":"#/components/schemas/Profile"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","follower","followed","createdAt","updatedAt"]},"Profile":{"type":"object","properties":{"userId":{"type":"string","description":"Shareable string ID\n\nSame as SuperTokens' userId."},"username":{"type":"string"},"bio":{"type":"string"},"avatar":{"$ref":"#/components/schemas/ProfileAvatar"},"followers":{"type":"array","items":{"$ref":"#/components/schemas/UserFollow"}},"following":{"type":"array","items":{"$ref":"#/components/schemas/UserFollow"}},"usernameLastUpdatedAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["userId","username","bio","avatar","followers","following","usernameLastUpdatedAt","createdAt","updatedAt"]},"Review":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string","nullable":true},"rating":{"type":"number"},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string"},"collectionEntry":{"$ref":"#/components/schemas/CollectionEntry"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","content","rating","game","gameId","profile","profileUserId","collectionEntry","createdAt","updatedAt"]},"CollectionEntry":{"type":"object","properties":{"id":{"type":"string"},"collections":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"},"ownedPlatforms":{"description":"The platforms on which the user owns the game.","type":"array","items":{"$ref":"#/components/schemas/GamePlatform"}},"review":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Review"}]},"isFavorite":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","collections","game","gameId","ownedPlatforms","review","isFavorite","createdAt","updatedAt"]},"Collection":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean"},"library":{"$ref":"#/components/schemas/Library"},"libraryUserId":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/CollectionEntry"}},"isFeatured":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","name","description","isPublic","library","libraryUserId","entries","isFeatured","createdAt","updatedAt"]},"CreateCollectionDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean","default":true},"isFeatured":{"type":"boolean","default":false}},"required":["name","isPublic","isFeatured"]},"UpdateCollectionDto":{"type":"object","properties":{}},"CreateReviewDto":{"type":"object","properties":{"gameId":{"type":"number"},"content":{"type":"string","minLength":20},"rating":{"type":"number","minimum":0,"maximum":5}},"required":["gameId","content","rating"]},"FindAllReviewsByIdDto":{"type":"object","properties":{"reviewsIds":{"type":"array","items":{"type":"string"}}},"required":["reviewsIds"]},"ReviewScoreDistribution":{"type":"object","properties":{"1":{"type":"number"},"2":{"type":"number"},"3":{"type":"number"},"4":{"type":"number"},"5":{"type":"number"},"total":{"type":"number","description":"Total number of reviews"}},"required":["1","2","3","4","5","total"]},"ReviewScoreResponseDto":{"type":"object","properties":{"median":{"type":"number"},"distribution":{"$ref":"#/components/schemas/ReviewScoreDistribution"}},"required":["median","distribution"]},"PaginationInfo":{"type":"object","properties":{"totalItems":{"type":"number","description":"Total number of items available for the current query"},"totalPages":{"type":"number","description":"Total number of pages available for the current query"},"hasNextPage":{"type":"boolean","description":"If this query allows for a next page"}},"required":["totalItems","totalPages","hasNextPage"]},"FindReviewPaginatedDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Review"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"UpdateProfileDto":{"type":"object","properties":{"username":{"type":"string","minLength":4,"maxLength":20},"avatar":{"type":"object"},"bio":{"type":"string","minLength":1,"maxLength":240}}},"AchievementDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"expGainAmount":{"type":"number"},"category":{"type":"number","enum":[0,1,2,3]}},"required":["id","name","description","expGainAmount","category"]},"PaginatedAchievementsResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AchievementDto"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"ObtainedAchievement":{"type":"object","properties":{"id":{"type":"number"},"achievementId":{"type":"string","description":"Achievement id specified in entries for achievements.data.ts"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string"},"isFeatured":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","achievementId","profile","profileUserId","isFeatured","createdAt","updatedAt"]},"UpdateFeaturedObtainedAchievementDto":{"type":"object","properties":{"isFeatured":{"type":"boolean"}},"required":["isFeatured"]},"UserLevel":{"type":"object","properties":{"userId":{"type":"string","description":"Should be the same as the profile's UserId"},"profile":{"$ref":"#/components/schemas/Profile"},"currentLevel":{"type":"number"},"currentLevelExp":{"type":"number","description":"XP in the current user-level"},"levelUpExpCost":{"type":"number","description":"Threshold XP to hit the next user-level"},"expMultiplier":{"type":"number","description":"The multiplier to apply to all exp gains"}},"required":["userId","profile","currentLevel","currentLevelExp","levelUpExpCost","expMultiplier"]},"CreateCollectionEntryDto":{"type":"object","properties":{"collectionIds":{"type":"array","items":{"type":"string"}},"gameId":{"type":"number"},"platformIds":{"type":"array","items":{"type":"number"}},"isFavorite":{"type":"boolean","default":false}},"required":["collectionIds","gameId","platformIds","isFavorite"]},"CreateFavoriteStatusCollectionEntryDto":{"type":"object","properties":{"isFavorite":{"type":"boolean","default":false}},"required":["isFavorite"]},"CollectionEntriesPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CollectionEntry"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"StatisticsActionDto":{"type":"object","properties":{"sourceId":{"oneOf":[{"type":"string"},{"type":"number"}]},"targetUserId":{"type":"string","minLength":36},"sourceType":{"enum":["game","review"],"type":"string"}},"required":["sourceId","sourceType"]},"FindOneStatisticsDto":{"type":"object","properties":{"sourceId":{"oneOf":[{"type":"string"},{"type":"number"}]},"sourceType":{"type":"string","enum":["game","review"]}},"required":["sourceId","sourceType"]},"GameRepositoryFilterDto":{"type":"object","properties":{"ids":{"description":"If this is supplied, filtering will be done only for entities specified here.
\nUseful to filter data received from entities which hold game ids (like GameStatistics, Reviews, etc.)","type":"array","items":{"type":"number"}},"status":{"type":"number","enum":[0,2,3,4,5,6,7,8]},"category":{"type":"number","enum":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]},"themes":{"type":"array","items":{"type":"number"}},"gameModes":{"type":"array","items":{"type":"number"}},"platforms":{"type":"array","items":{"type":"number"}},"genres":{"type":"array","items":{"type":"number"}},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20}}},"FindStatisticsTrendingGamesDto":{"type":"object","properties":{"criteria":{"$ref":"#/components/schemas/GameRepositoryFilterDto"},"period":{"type":"string","enum":["day","week","month","quarter","half_year","year","all"]},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20}},"required":["period"]},"UserLike":{"type":"object","properties":{"id":{"type":"number"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"gameStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/GameStatistics"}]},"gameStatisticsId":{"type":"number"},"reviewStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ReviewStatistics"}]},"reviewStatisticsId":{"type":"number"}},"required":["id","profile","profileUserId","createdAt","updatedAt","gameStatistics","gameStatisticsId","reviewStatistics","reviewStatisticsId"]},"ReviewStatistics":{"type":"object","properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/UserView"}},"likes":{"type":"array","items":{"$ref":"#/components/schemas/UserLike"}},"review":{"$ref":"#/components/schemas/Review"},"reviewId":{"type":"string"},"id":{"type":"number"},"viewsCount":{"type":"number"},"likesCount":{"type":"number"}},"required":["views","likes","review","reviewId","id","viewsCount","likesCount"]},"UserView":{"type":"object","properties":{"id":{"type":"number"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"gameStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/GameStatistics"}]},"reviewStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ReviewStatistics"}]}},"required":["id","profileUserId","createdAt","updatedAt","gameStatistics","reviewStatistics"]},"GameStatistics":{"type":"object","properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/UserView"}},"likes":{"type":"array","items":{"$ref":"#/components/schemas/UserLike"}},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"},"id":{"type":"number"},"viewsCount":{"type":"number"},"likesCount":{"type":"number"}},"required":["views","likes","game","gameId","id","viewsCount","likesCount"]},"GameStatisticsPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GameStatistics"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"FindStatisticsTrendingReviewsDto":{"type":"object","properties":{"reviewId":{"type":"string","description":"Usually, this property should not be used unless a specific review needs to be retrieved, and it's easier to just\ncall the statistics controller."},"gameId":{"type":"number"},"userId":{"type":"string","minLength":36},"period":{"type":"string","enum":["day","week","month","quarter","half_year","year","all"]},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20}},"required":["period"]},"ReviewStatisticsPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ReviewStatistics"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"StatisticsStatus":{"type":"object","properties":{"isLiked":{"type":"boolean"},"isViewed":{"type":"boolean"}},"required":["isLiked","isViewed"]},"Activity":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["REVIEW","FOLLOW","COLLECTION_ENTRY"]},"sourceId":{"type":"string"},"metadata":{"type":"object","nullable":true},"profile":{"description":"The associated profile with this Activity","allOf":[{"$ref":"#/components/schemas/Profile"}]},"profileUserId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","type","sourceId","metadata","profile","profileUserId","createdAt","updatedAt"]},"Notification":{"type":"object","properties":{"id":{"type":"number"},"sourceType":{"type":"string","enum":["game","review","activity","profile"]},"category":{"type":"string","description":"What this notification's about. E.g.: a new like, a new follower, a game launch, etc.","enum":["follow","like","comment","launch"]},"review":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Review"}]},"reviewId":{"type":"string","nullable":true},"game":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Game"}]},"gameId":{"type":"number","nullable":true},"activity":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Activity"}]},"activityId":{"type":"string","nullable":true},"profile":{"nullable":true,"description":"User responsible for generating this notification (e.g. user that liked a review).","allOf":[{"$ref":"#/components/schemas/Profile"}]},"profileUserId":{"type":"string","nullable":true,"description":"User responsible for generating this notification (e.g. user that liked a review).\nWhen null/undefined, the notification was generated by the 'system'."},"isViewed":{"type":"boolean"},"targetProfile":{"nullable":true,"description":"User which is the target for this notification.
\nIf this is empty (null/undefined), the notification is targeted at all users.
\nNot to be confused with the 'profile' property.","allOf":[{"$ref":"#/components/schemas/Profile"}]},"targetProfileUserId":{"type":"string","nullable":true,"description":"User which is the target for this notification.
\nIf this is empty (null/undefined), the notification is targeted at all users.
\nNot to be confused with the 'profile' property."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","sourceType","category","review","reviewId","game","gameId","activity","activityId","profile","profileUserId","isViewed","targetProfile","targetProfileUserId","createdAt","updatedAt"]},"NotificationAggregateDto":{"type":"object","properties":{"sourceId":{"oneOf":[{"type":"string"},{"type":"number"}]},"category":{"type":"string","enum":["follow","like","comment","launch"]},"sourceType":{"type":"string","enum":["game","review","activity","profile"]},"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}}},"required":["sourceId","category","sourceType","notifications"]},"PaginatedNotificationAggregationDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/NotificationAggregateDto"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"NotificationViewUpdateDto":{"type":"object","properties":{"isViewed":{"type":"boolean"}},"required":["isViewed"]},"GameExternalStoreDto":{"type":"object","properties":{"icon":{"type":"string","nullable":true,"description":"Icon representing said store/service."},"storeName":{"type":"string","nullable":true},"id":{"type":"number"},"uid":{"type":"string","description":"Corresponds to the game id on the target source (see GameExternalGameCategory).\nIt's called uid, not uuid."},"category":{"type":"number","enum":[1,5,10,11,13,14,15,20,22,23,26,28,29,30,31,32,36,37,54,55]},"media":{"type":"number","enum":[1,2]},"checksum":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"year":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"gameId":{"type":"number"}},"required":["icon","storeName","id","uid","createdAt","updatedAt","gameId"]},"GameRepositoryFindOneDto":{"type":"object","properties":{"relations":{"type":"object"}}},"GameRepositoryFindAllDto":{"type":"object","properties":{"gameIds":{"type":"array","items":{"type":"number"}},"relations":{"type":"object"}},"required":["gameIds"]},"GamePlaytime":{"type":"object","properties":{"id":{"type":"number"},"gameId":{"type":"number"},"game":{"$ref":"#/components/schemas/Game"},"sourceId":{"type":"number"},"timeMain":{"type":"number","nullable":true},"timePlus":{"type":"number","nullable":true},"time100":{"type":"number","nullable":true},"timeAll":{"type":"number","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","gameId","game","sourceId","timeMain","timePlus","time100","timeAll","createdAt","updatedAt"]},"ActivitiesFeedPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Activity"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"FollowStatusDto":{"type":"object","properties":{"isFollowing":{"type":"boolean"}},"required":["isFollowing"]},"FollowRegisterDto":{"type":"object","properties":{"followedUserId":{"type":"string","minLength":36}},"required":["followedUserId"]},"FollowRemoveDto":{"type":"object","properties":{"followedUserId":{"type":"string","minLength":36}},"required":["followedUserId"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/v1/auth/logout":{"get":{"operationId":"AuthController_logout","parameters":[],"responses":{"200":{"description":""}},"tags":["auth"]}},"/v1/libraries":{"get":{"operationId":"LibrariesController_findOwn","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Library"}}}}},"tags":["libraries"]}},"/v1/libraries/{id}":{"get":{"operationId":"LibrariesController_findOneByIdWithPermissions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Library"}}}}},"tags":["libraries"]}},"/v1/collections/{id}":{"get":{"operationId":"CollectionsController_findOneByIdWithPermissions","summary":"","description":"Returns a collection which the user has access to\n\n(Either its own collection or a public one)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}}}},"tags":["collections"]},"patch":{"operationId":"CollectionsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollectionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["collections"]},"delete":{"operationId":"CollectionsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["collections"]}},"/v1/collections/library/{userId}":{"get":{"operationId":"CollectionsController_findAllByUserIdWithPermissions","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}}}}}},"tags":["collections"]}},"/v1/collections":{"post":{"operationId":"CollectionsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionDto"}}}},"responses":{"201":{"description":""}},"tags":["collections"]}},"/v1/reviews":{"post":{"operationId":"ReviewsController_createOrUpdate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReviewDto"}}}},"responses":{"201":{"description":""}},"tags":["reviews"]},"get":{"operationId":"ReviewsController_findOneByUserIdAndGameId","parameters":[{"name":"id","required":true,"in":"query","schema":{"type":"string"}},{"name":"gameId","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Review"}}}}},"tags":["reviews"]}},"/v1/reviews/all":{"post":{"operationId":"ReviewsController_findAllById","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindAllReviewsByIdDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Review"}}}}}},"tags":["reviews"]}},"/v1/reviews/score":{"get":{"operationId":"ReviewsController_getScoreForGameId","parameters":[{"name":"gameId","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewScoreResponseDto"}}}}},"tags":["reviews"]}},"/v1/reviews/profile/{userId}":{"get":{"operationId":"ReviewsController_findAllByUserId","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindReviewPaginatedDto"}}}}},"tags":["reviews"]}},"/v1/reviews/game/{id}":{"get":{"operationId":"ReviewsController_findAllByGameId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindReviewPaginatedDto"}}}}},"tags":["reviews"]}},"/v1/reviews/{id}":{"get":{"operationId":"ReviewsController_findOneById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Review"}}}}},"tags":["reviews"]},"delete":{"operationId":"ReviewsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["reviews"]}},"/v1/profile":{"patch":{"operationId":"ProfileController_update","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UpdateProfileDto"}}}},"responses":{"200":{"description":""}},"tags":["profile"]},"get":{"operationId":"ProfileController_findOwn","summary":"","description":"Used to access own profile","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}}},"tags":["profile"]}},"/v1/profile/{id}":{"get":{"operationId":"ProfileController_findOneById","summary":"","description":"Used to access other users' profiles","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}}},"tags":["profile"]}},"/v1/achievements":{"get":{"operationId":"AchievementsController_getAchievements","parameters":[{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedAchievementsResponseDto"}}}}},"tags":["achievements"]}},"/v1/achievements/obtained/{id}":{"get":{"operationId":"AchievementsController_getObtainedAchievement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"targetUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObtainedAchievement"}}}}},"tags":["achievements"]}},"/v1/achievements/obtained":{"get":{"operationId":"AchievementsController_getAllObtainedAchievements","parameters":[{"name":"targetUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ObtainedAchievement"}}}}}},"tags":["achievements"]}},"/v1/achievements/obtained/{id}/featured":{"put":{"operationId":"AchievementsController_updateFeaturedObtainedAchievement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFeaturedObtainedAchievementDto"}}}},"responses":{"200":{"description":""}},"tags":["achievements"]}},"/v1/level/{userId}":{"get":{"operationId":"LevelController_findOne","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLevel"}}}}},"tags":["level"]}},"/v1/collections-entries":{"post":{"operationId":"CollectionsEntriesController_createOrUpdate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionEntryDto"}}}},"responses":{"201":{"description":""}},"tags":["collections-entries"]}},"/v1/collections-entries/game/{id}":{"get":{"operationId":"CollectionsEntriesController_findOwnEntryByGameId","summary":"","description":"Returns a specific collection entry based on game ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntry"}}}},"400":{"description":"Invalid query"}},"tags":["collections-entries"]}},"/v1/collections-entries/{id}/platforms/icons":{"get":{"operationId":"CollectionsEntriesController_getIconsForOwnedPlatforms","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["collections-entries"]}},"/v1/collections-entries/{id}":{"delete":{"operationId":"CollectionsEntriesController_deleteOwnEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["collections-entries"]}},"/v1/collections-entries/game/{id}/favorite":{"post":{"operationId":"CollectionsEntriesController_changeFavoriteStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFavoriteStatusCollectionEntryDto"}}}},"responses":{"204":{"description":""}},"tags":["collections-entries"]}},"/v1/collections-entries/library/{id}":{"get":{"operationId":"CollectionsEntriesController_findAllByLibraryId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntriesPaginatedResponseDto"}}}}},"tags":["collections-entries"]}},"/v1/collections-entries/library/{id}/favorites":{"get":{"operationId":"CollectionsEntriesController_findFavoritesByLibraryId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntriesPaginatedResponseDto"}}}}},"tags":["collections-entries"]}},"/v1/collections-entries/collection/{id}":{"get":{"operationId":"CollectionsEntriesController_findAllByCollectionId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionEntriesPaginatedResponseDto"}}}}},"tags":["collections-entries"]}},"/v1/statistics/queue/like":{"post":{"operationId":"StatisticsQueueController_addLike","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsActionDto"}}}},"responses":{"201":{"description":""}},"tags":["statistics-queue"]},"delete":{"operationId":"StatisticsQueueController_removeLike","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsActionDto"}}}},"responses":{"200":{"description":""}},"tags":["statistics-queue"]}},"/v1/statistics/queue/view":{"post":{"operationId":"StatisticsQueueController_addView","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsActionDto"}}}},"responses":{"201":{"description":""}},"tags":["statistics-queue"]}},"/v1/statistics":{"post":{"operationId":"StatisticsController_findOneBySourceIdAndType","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindOneStatisticsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["statistics"]}},"/v1/statistics/trending/games":{"post":{"operationId":"StatisticsController_findTrendingGames","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindStatisticsTrendingGamesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameStatisticsPaginatedResponseDto"}}}}},"tags":["statistics"]}},"/v1/statistics/trending/reviews":{"post":{"operationId":"StatisticsController_findTrendingReviews","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindStatisticsTrendingReviewsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewStatisticsPaginatedResponseDto"}}}}},"tags":["statistics"]}},"/v1/statistics/status":{"get":{"operationId":"StatisticsController_getStatus","parameters":[{"name":"statisticsId","required":true,"in":"query","schema":{"type":"number"}},{"name":"sourceType","required":true,"in":"query","schema":{"enum":["game","review"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsStatus"}}}}},"tags":["statistics"]}},"/v1/notifications":{"get":{"operationId":"NotificationsController_findAllAndAggregate","parameters":[{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedNotificationAggregationDto"}}}}},"tags":["notifications"]}},"/v1/notifications/{id}/view":{"put":{"operationId":"NotificationsController_updateViewedStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationViewUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["notifications"]}},"/v1/game/repository/resource":{"get":{"operationId":"GameRepositoryController_getResource","parameters":[{"name":"resourceName","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["game-repository"]}},"/v1/game/repository/{id}/platforms/icon":{"get":{"operationId":"GameRepositoryController_getIconNamesForPlatformAbbreviations","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["game-repository"]}},"/v1/game/repository/{id}/external-stores":{"get":{"operationId":"GameRepositoryController_getExternalStoresForGameId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GameExternalStoreDto"}}}}}},"tags":["game-repository"]}},"/v1/game/repository/{id}":{"post":{"operationId":"GameRepositoryController_findOneById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameRepositoryFindOneDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Game"}}}}},"tags":["game-repository"]}},"/v1/game/repository":{"post":{"operationId":"GameRepositoryController_findAllByIds","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameRepositoryFindAllDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}}}}},"tags":["game-repository"]}},"/v1/sync/hltb/{gameId}":{"get":{"operationId":"HltbController_findPlaytimeForGameId","parameters":[{"name":"gameId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GamePlaytime"}}}}},"tags":["sync-hltb"]}},"/v1/health":{"get":{"operationId":"HealthController_health","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["health"]}},"/v1/activities/feed":{"get":{"operationId":"ActivitiesFeedController_buildActivitiesFeed","parameters":[{"name":"criteria","required":true,"in":"query","schema":{"enum":["following","trending","latest"],"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivitiesFeedPaginatedResponseDto"}}}}},"tags":["activities-feed"]}},"/v1/follow/status":{"get":{"operationId":"FollowController_getFollowerStatus","parameters":[{"name":"followerUserId","required":true,"in":"query","schema":{"type":"string"}},{"name":"followedUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowStatusDto"}}}}},"tags":["follow"]}},"/v1/follow/count":{"get":{"operationId":"FollowController_getFollowersCount","parameters":[{"name":"targetUserId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"number"}}}}},"tags":["follow"]}},"/v1/follow/info":{"post":{"operationId":"FollowController_getFollowInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowInfoRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowInfoResponseDto"}}}},"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["follow"]}},"/v1/follow":{"post":{"operationId":"FollowController_registerFollow","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowRegisterDto"}}}},"responses":{"201":{"description":""}},"tags":["follow"]},"delete":{"operationId":"FollowController_removeFollow","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowRemoveDto"}}}},"responses":{"200":{"description":""}},"tags":["follow"]}}},"info":{"title":"GameNode API","description":"API docs for the videogame catalog system GameNode.

Built with love by the GameNode team.","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"Library":{"type":"object","properties":{"userId":{"type":"string","description":"@description The primary key of the library entity.\nAlso used to share the library with other users.\n\nSame as SuperTokens' userId."},"collections":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["userId","collections","createdAt","updatedAt"]},"GameCover":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["game","id"]},"GameCollection":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"slug":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"checksum":{"type":"string"},"url":{"type":"string"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}},"required":["id","name","slug","createdAt","updatedAt","checksum","url","games"]},"GameAlternativeName":{"type":"object","properties":{"id":{"type":"number"},"comment":{"type":"string"},"name":{"type":"string"},"checksum":{"type":"string"},"game":{"$ref":"#/components/schemas/Game"}},"required":["id","game"]},"GameArtwork":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["game","id"]},"GameScreenshot":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["game","id"]},"GameLocalization":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["game","id","createdAt","updatedAt"]},"GameMode":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["game","id","createdAt","updatedAt"]},"GameGenre":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["games","id","createdAt","updatedAt"]},"GameTheme":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","createdAt","updatedAt"]},"GamePlayerPerspective":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["games","id","createdAt","updatedAt"]},"GameEngineLogo":{"type":"object","properties":{"engine":{"$ref":"#/components/schemas/GameEngine"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["engine","id"]},"GameCompanyLogo":{"type":"object","properties":{"company":{"$ref":"#/components/schemas/GameCompany"},"id":{"type":"number"},"alphaChannel":{"type":"boolean"},"animated":{"type":"boolean"},"height":{"type":"number"},"imageId":{"type":"string"},"url":{"type":"string"},"width":{"type":"number"},"checksum":{"type":"string"}},"required":["company","id"]},"GameCompany":{"type":"object","properties":{"id":{"type":"number"},"changeDate":{"format":"date-time","type":"string"},"changeDateCategory":{"type":"string"},"changedCompany":{"$ref":"#/components/schemas/GameCompany"},"checksum":{"type":"string"},"country":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"logo":{"$ref":"#/components/schemas/GameCompanyLogo"},"name":{"type":"string"},"parent":{"$ref":"#/components/schemas/GameCompany"},"slug":{"type":"string"},"startDate":{"format":"date-time","type":"string"},"startDateCategory":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"url":{"type":"string"}},"required":["id","createdAt","name","slug","updatedAt"]},"GamePlatform":{"type":"object","properties":{"id":{"type":"number"},"abbreviation":{"type":"string"},"alternative_name":{"type":"string"},"category":{"type":"number","enum":[1,2,3,4,5,6]},"checksum":{"type":"string"},"generation":{"type":"number"},"name":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"collectionEntries":{"type":"array","items":{"$ref":"#/components/schemas/CollectionEntry"}}},"required":["id","abbreviation","alternative_name","category","checksum","generation","name","createdAt","updatedAt","games","collectionEntries"]},"GameEngine":{"type":"object","properties":{"logo":{"$ref":"#/components/schemas/GameEngineLogo"},"companies":{"type":"array","items":{"$ref":"#/components/schemas/GameCompany"}},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/GamePlatform"}},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["logo","companies","platforms","games","id","createdAt","updatedAt"]},"GameKeyword":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/Game"},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["game","id","createdAt","updatedAt"]},"GameFranchise":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"id":{"type":"number"},"checksum":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["games","id","createdAt","updatedAt"]},"GameExternalGame":{"type":"object","properties":{"id":{"type":"number"},"uid":{"type":"string","description":"Corresponds to the game id on the target source (see GameExternalGameCategory).\nIt's called uid, not uuid."},"category":{"type":"number","enum":[1,5,10,11,13,14,15,20,22,23,26,28,29,30,31,32,36,37,54,55]},"media":{"type":"number","enum":[1,2]},"checksum":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"year":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"}},"required":["id","uid","createdAt","updatedAt","game","gameId"]},"GameInvolvedCompany":{"type":"object","properties":{"id":{"type":"number"},"checksum":{"type":"string"},"company":{"$ref":"#/components/schemas/GameCompany"},"companyId":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"developer":{"type":"boolean"},"porting":{"type":"boolean"},"publisher":{"type":"boolean"},"supporting":{"type":"boolean"},"updatedAt":{"format":"date-time","type":"string"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}},"required":["id","company","companyId","createdAt","developer","porting","publisher","supporting","updatedAt","games"]},"Game":{"type":"object","properties":{"id":{"type":"number","description":"Should be mapped to the IGDB ID of the game."},"name":{"type":"string"},"slug":{"type":"string"},"aggregatedRating":{"type":"number"},"aggregatedRatingCount":{"type":"number"},"category":{"enum":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],"type":"number"},"status":{"enum":[0,2,3,4,5,6,7,8],"type":"number"},"summary":{"type":"string"},"storyline":{"type":"string"},"checksum":{"type":"string"},"url":{"type":"string"},"firstReleaseDate":{"format":"date-time","type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"dlcs":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"dlcOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expansions":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expansionOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expandedGames":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"expandedGameOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"similarGames":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"similarGameOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remakes":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remakeOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remasters":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"remasterOf":{"type":"array","items":{"$ref":"#/components/schemas/Game"}},"cover":{"$ref":"#/components/schemas/GameCover"},"collection":{"$ref":"#/components/schemas/GameCollection"},"alternativeNames":{"type":"array","items":{"$ref":"#/components/schemas/GameAlternativeName"}},"artworks":{"type":"array","items":{"$ref":"#/components/schemas/GameArtwork"}},"screenshots":{"type":"array","items":{"$ref":"#/components/schemas/GameScreenshot"}},"gameLocalizations":{"type":"array","items":{"$ref":"#/components/schemas/GameLocalization"}},"gameModes":{"type":"array","items":{"$ref":"#/components/schemas/GameMode"}},"genres":{"type":"array","items":{"$ref":"#/components/schemas/GameGenre"}},"themes":{"type":"array","items":{"$ref":"#/components/schemas/GameTheme"}},"playerPerspectives":{"type":"array","items":{"$ref":"#/components/schemas/GamePlayerPerspective"}},"gameEngines":{"type":"array","items":{"$ref":"#/components/schemas/GameEngine"}},"keywords":{"type":"array","items":{"$ref":"#/components/schemas/GameKeyword"}},"franchises":{"type":"array","items":{"$ref":"#/components/schemas/GameFranchise"}},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/GamePlatform"}},"externalGames":{"type":"array","items":{"$ref":"#/components/schemas/GameExternalGame"}},"involvedCompanies":{"type":"array","items":{"$ref":"#/components/schemas/GameInvolvedCompany"}},"source":{"type":"string","description":"Oh dear maintainer, please forgive me for using transient fields.","default":"MYSQL","enum":["MYSQL","MANTICORE"]}},"required":["id","name","slug","category","status","summary","storyline","checksum","url","firstReleaseDate","createdAt","updatedAt","involvedCompanies","source"]},"ProfileAvatar":{"type":"object","properties":{"id":{"type":"number"},"mimetype":{"type":"string"},"extension":{"type":"string"},"size":{"type":"number"},"filename":{"type":"string"},"encoding":{"type":"string"},"profile":{"$ref":"#/components/schemas/Profile"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","mimetype","extension","size","filename","encoding","profile","createdAt","updatedAt"]},"UserFollow":{"type":"object","properties":{"id":{"type":"number"},"follower":{"$ref":"#/components/schemas/Profile"},"followerUserId":{"type":"string"},"followed":{"$ref":"#/components/schemas/Profile"},"followedUserId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","follower","followerUserId","followed","followedUserId","createdAt","updatedAt"]},"Profile":{"type":"object","properties":{"userId":{"type":"string","description":"Shareable string ID\n\nSame as SuperTokens' userId."},"username":{"type":"string"},"bio":{"type":"string"},"avatar":{"$ref":"#/components/schemas/ProfileAvatar"},"followers":{"type":"array","items":{"$ref":"#/components/schemas/UserFollow"}},"following":{"type":"array","items":{"$ref":"#/components/schemas/UserFollow"}},"usernameLastUpdatedAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["userId","username","bio","avatar","followers","following","usernameLastUpdatedAt","createdAt","updatedAt"]},"Review":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string","nullable":true},"rating":{"type":"number"},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string"},"collectionEntry":{"$ref":"#/components/schemas/CollectionEntry"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","content","rating","game","gameId","profile","profileUserId","collectionEntry","createdAt","updatedAt"]},"CollectionEntry":{"type":"object","properties":{"id":{"type":"string"},"collections":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"},"ownedPlatforms":{"description":"The platforms on which the user owns the game.","type":"array","items":{"$ref":"#/components/schemas/GamePlatform"}},"review":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Review"}]},"isFavorite":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","collections","game","gameId","ownedPlatforms","review","isFavorite","createdAt","updatedAt"]},"Collection":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean"},"library":{"$ref":"#/components/schemas/Library"},"libraryUserId":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/CollectionEntry"}},"isFeatured":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","name","description","isPublic","library","libraryUserId","entries","isFeatured","createdAt","updatedAt"]},"CreateCollectionDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean","default":true},"isFeatured":{"type":"boolean","default":false}},"required":["name","isPublic","isFeatured"]},"UpdateCollectionDto":{"type":"object","properties":{}},"CreateReviewDto":{"type":"object","properties":{"gameId":{"type":"number"},"content":{"type":"string","minLength":20},"rating":{"type":"number","minimum":0,"maximum":5}},"required":["gameId","content","rating"]},"FindAllReviewsByIdDto":{"type":"object","properties":{"reviewsIds":{"type":"array","items":{"type":"string"}}},"required":["reviewsIds"]},"ReviewScoreDistribution":{"type":"object","properties":{"1":{"type":"number"},"2":{"type":"number"},"3":{"type":"number"},"4":{"type":"number"},"5":{"type":"number"},"total":{"type":"number","description":"Total number of reviews"}},"required":["1","2","3","4","5","total"]},"ReviewScoreResponseDto":{"type":"object","properties":{"median":{"type":"number"},"distribution":{"$ref":"#/components/schemas/ReviewScoreDistribution"}},"required":["median","distribution"]},"PaginationInfo":{"type":"object","properties":{"totalItems":{"type":"number","description":"Total number of items available for the current query"},"totalPages":{"type":"number","description":"Total number of pages available for the current query"},"hasNextPage":{"type":"boolean","description":"If this query allows for a next page"}},"required":["totalItems","totalPages","hasNextPage"]},"FindReviewPaginatedDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Review"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"UpdateProfileDto":{"type":"object","properties":{"username":{"type":"string","minLength":4,"maxLength":20},"avatar":{"type":"object"},"bio":{"type":"string","minLength":1,"maxLength":240}}},"AchievementDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"expGainAmount":{"type":"number"},"category":{"type":"number","enum":[0,1,2,3]}},"required":["id","name","description","expGainAmount","category"]},"PaginatedAchievementsResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AchievementDto"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"ObtainedAchievement":{"type":"object","properties":{"id":{"type":"number"},"achievementId":{"type":"string","description":"Achievement id specified in entries for achievements.data.ts"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string"},"isFeatured":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","achievementId","profile","profileUserId","isFeatured","createdAt","updatedAt"]},"UpdateFeaturedObtainedAchievementDto":{"type":"object","properties":{"isFeatured":{"type":"boolean"}},"required":["isFeatured"]},"UserLevel":{"type":"object","properties":{"userId":{"type":"string","description":"Should be the same as the profile's UserId"},"profile":{"$ref":"#/components/schemas/Profile"},"currentLevel":{"type":"number"},"currentLevelExp":{"type":"number","description":"XP in the current user-level"},"levelUpExpCost":{"type":"number","description":"Threshold XP to hit the next user-level"},"expMultiplier":{"type":"number","description":"The multiplier to apply to all exp gains"}},"required":["userId","profile","currentLevel","currentLevelExp","levelUpExpCost","expMultiplier"]},"CreateCollectionEntryDto":{"type":"object","properties":{"collectionIds":{"type":"array","items":{"type":"string"}},"gameId":{"type":"number"},"platformIds":{"type":"array","items":{"type":"number"}},"isFavorite":{"type":"boolean","default":false}},"required":["collectionIds","gameId","platformIds","isFavorite"]},"CreateFavoriteStatusCollectionEntryDto":{"type":"object","properties":{"isFavorite":{"type":"boolean","default":false}},"required":["isFavorite"]},"CollectionEntriesPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CollectionEntry"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"StatisticsActionDto":{"type":"object","properties":{"sourceId":{"oneOf":[{"type":"string"},{"type":"number"}]},"targetUserId":{"type":"string","minLength":36},"sourceType":{"enum":["game","review"],"type":"string"}},"required":["sourceId","sourceType"]},"FindOneStatisticsDto":{"type":"object","properties":{"sourceId":{"oneOf":[{"type":"string"},{"type":"number"}]},"sourceType":{"type":"string","enum":["game","review"]}},"required":["sourceId","sourceType"]},"GameRepositoryFilterDto":{"type":"object","properties":{"ids":{"description":"If this is supplied, filtering will be done only for entities specified here.
\nUseful to filter data received from entities which hold game ids (like GameStatistics, Reviews, etc.)","type":"array","items":{"type":"number"}},"status":{"type":"number","enum":[0,2,3,4,5,6,7,8]},"category":{"type":"number","enum":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]},"themes":{"type":"array","items":{"type":"number"}},"gameModes":{"type":"array","items":{"type":"number"}},"platforms":{"type":"array","items":{"type":"number"}},"genres":{"type":"array","items":{"type":"number"}},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20}}},"FindStatisticsTrendingGamesDto":{"type":"object","properties":{"criteria":{"$ref":"#/components/schemas/GameRepositoryFilterDto"},"period":{"type":"string","enum":["day","week","month","quarter","half_year","year","all"]},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20}},"required":["period"]},"UserLike":{"type":"object","properties":{"id":{"type":"number"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"gameStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/GameStatistics"}]},"gameStatisticsId":{"type":"number"},"reviewStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ReviewStatistics"}]},"reviewStatisticsId":{"type":"number"}},"required":["id","profile","profileUserId","createdAt","updatedAt","gameStatistics","gameStatisticsId","reviewStatistics","reviewStatisticsId"]},"ReviewStatistics":{"type":"object","properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/UserView"}},"likes":{"type":"array","items":{"$ref":"#/components/schemas/UserLike"}},"review":{"$ref":"#/components/schemas/Review"},"reviewId":{"type":"string"},"id":{"type":"number"},"viewsCount":{"type":"number"},"likesCount":{"type":"number"}},"required":["views","likes","review","reviewId","id","viewsCount","likesCount"]},"UserView":{"type":"object","properties":{"id":{"type":"number"},"profile":{"$ref":"#/components/schemas/Profile"},"profileUserId":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"gameStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/GameStatistics"}]},"reviewStatistics":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ReviewStatistics"}]}},"required":["id","profileUserId","createdAt","updatedAt","gameStatistics","reviewStatistics"]},"GameStatistics":{"type":"object","properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/UserView"}},"likes":{"type":"array","items":{"$ref":"#/components/schemas/UserLike"}},"game":{"$ref":"#/components/schemas/Game"},"gameId":{"type":"number"},"id":{"type":"number"},"viewsCount":{"type":"number"},"likesCount":{"type":"number"}},"required":["views","likes","game","gameId","id","viewsCount","likesCount"]},"GameStatisticsPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GameStatistics"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"FindStatisticsTrendingReviewsDto":{"type":"object","properties":{"reviewId":{"type":"string","description":"Usually, this property should not be used unless a specific review needs to be retrieved, and it's easier to just\ncall the statistics controller."},"gameId":{"type":"number"},"userId":{"type":"string","minLength":36},"period":{"type":"string","enum":["day","week","month","quarter","half_year","year","all"]},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20}},"required":["period"]},"ReviewStatisticsPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ReviewStatistics"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"StatisticsStatus":{"type":"object","properties":{"isLiked":{"type":"boolean"},"isViewed":{"type":"boolean"}},"required":["isLiked","isViewed"]},"Activity":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["REVIEW","FOLLOW","COLLECTION_ENTRY"]},"sourceId":{"type":"string"},"metadata":{"type":"object","nullable":true},"profile":{"description":"The associated profile with this Activity","allOf":[{"$ref":"#/components/schemas/Profile"}]},"profileUserId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","type","sourceId","metadata","profile","profileUserId","createdAt","updatedAt"]},"Notification":{"type":"object","properties":{"id":{"type":"number"},"sourceType":{"type":"string","enum":["game","review","activity","profile"]},"category":{"type":"string","description":"What this notification's about. E.g.: a new like, a new follower, a game launch, etc.","enum":["follow","like","comment","launch"]},"review":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Review"}]},"reviewId":{"type":"string","nullable":true},"game":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Game"}]},"gameId":{"type":"number","nullable":true},"activity":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Activity"}]},"activityId":{"type":"string","nullable":true},"profile":{"nullable":true,"description":"User responsible for generating this notification (e.g. user that liked a review).","allOf":[{"$ref":"#/components/schemas/Profile"}]},"profileUserId":{"type":"string","nullable":true,"description":"User responsible for generating this notification (e.g. user that liked a review).\nWhen null/undefined, the notification was generated by the 'system'."},"isViewed":{"type":"boolean"},"targetProfile":{"nullable":true,"description":"User which is the target for this notification.
\nIf this is empty (null/undefined), the notification is targeted at all users.
\nNot to be confused with the 'profile' property.","allOf":[{"$ref":"#/components/schemas/Profile"}]},"targetProfileUserId":{"type":"string","nullable":true,"description":"User which is the target for this notification.
\nIf this is empty (null/undefined), the notification is targeted at all users.
\nNot to be confused with the 'profile' property."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","sourceType","category","review","reviewId","game","gameId","activity","activityId","profile","profileUserId","isViewed","targetProfile","targetProfileUserId","createdAt","updatedAt"]},"NotificationAggregateDto":{"type":"object","properties":{"sourceId":{"oneOf":[{"type":"string"},{"type":"number"}]},"category":{"type":"string","enum":["follow","like","comment","launch"]},"sourceType":{"type":"string","enum":["game","review","activity","profile"]},"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}}},"required":["sourceId","category","sourceType","notifications"]},"PaginatedNotificationAggregationDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/NotificationAggregateDto"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"NotificationViewUpdateDto":{"type":"object","properties":{"isViewed":{"type":"boolean"}},"required":["isViewed"]},"GameExternalStoreDto":{"type":"object","properties":{"icon":{"type":"string","nullable":true,"description":"Icon representing said store/service."},"storeName":{"type":"string","nullable":true},"id":{"type":"number"},"uid":{"type":"string","description":"Corresponds to the game id on the target source (see GameExternalGameCategory).\nIt's called uid, not uuid."},"category":{"type":"number","enum":[1,5,10,11,13,14,15,20,22,23,26,28,29,30,31,32,36,37,54,55]},"media":{"type":"number","enum":[1,2]},"checksum":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"year":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"gameId":{"type":"number"}},"required":["icon","storeName","id","uid","createdAt","updatedAt","gameId"]},"GameRepositoryFindOneDto":{"type":"object","properties":{"relations":{"type":"object"}}},"GameRepositoryFindAllDto":{"type":"object","properties":{"gameIds":{"type":"array","items":{"type":"number"}},"relations":{"type":"object"}},"required":["gameIds"]},"GamePlaytime":{"type":"object","properties":{"id":{"type":"number"},"gameId":{"type":"number"},"game":{"$ref":"#/components/schemas/Game"},"sourceId":{"type":"number"},"timeMain":{"type":"number","nullable":true},"timePlus":{"type":"number","nullable":true},"time100":{"type":"number","nullable":true},"timeAll":{"type":"number","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","gameId","game","sourceId","timeMain","timePlus","time100","timeAll","createdAt","updatedAt"]},"ActivitiesFeedPaginatedResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Activity"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"FollowStatusDto":{"type":"object","properties":{"isFollowing":{"type":"boolean"}},"required":["isFollowing"]},"FollowInfoRequestDto":{"type":"object","properties":{"criteria":{"type":"string","enum":["followers","following"]},"targetUserId":{"type":"string","minLength":36},"offset":{"type":"number","default":0},"limit":{"type":"number","default":20},"orderBy":{"type":"object"}},"required":["criteria","targetUserId"]},"FollowInfoResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"type":"string"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"required":["data","pagination"]},"FollowRegisterDto":{"type":"object","properties":{"followedUserId":{"type":"string","minLength":36}},"required":["followedUserId"]},"FollowRemoveDto":{"type":"object","properties":{"followedUserId":{"type":"string","minLength":36}},"required":["followedUserId"]}}}} \ No newline at end of file